Merge "Abstract away access to audio streams HAL in AudioFlinger"
diff --git a/Android.bp b/Android.bp
index 6fd6c72..0990db6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,12 @@
+ndk_headers {
+    name: "libcamera2ndk_headers",
+    from: "include/camera/ndk/",
+    to: "camera",
+    srcs: ["include/camera/ndk/**/*.h"],
+}
+
 subdirs = [
+    "camera/ndk",
     "media/libmedia",
     "media/libstagefright/foundation",
 ]
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
new file mode 100644
index 0000000..6f2351f
--- /dev/null
+++ b/camera/ndk/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Headers module is in frameworks/av/Android.bp because modules are not allowed
+// to refer to headers in parent directories and the headers live in
+// frameworks/av/include.
+
+ndk_library {
+    name: "libcamera2ndk.ndk",
+    symbol_file: "libcamera2ndk.map.txt",
+    first_version: "24",
+}
diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt
new file mode 100644
index 0000000..41bb22b
--- /dev/null
+++ b/camera/ndk/libcamera2ndk.map.txt
@@ -0,0 +1,46 @@
+LIBCAMERA2NDK {
+  global:
+    ACameraCaptureSession_abortCaptures;
+    ACameraCaptureSession_capture;
+    ACameraCaptureSession_close;
+    ACameraCaptureSession_getDevice;
+    ACameraCaptureSession_setRepeatingRequest;
+    ACameraCaptureSession_stopRepeating;
+    ACameraDevice_close;
+    ACameraDevice_createCaptureRequest;
+    ACameraDevice_createCaptureSession;
+    ACameraDevice_getId;
+    ACameraManager_create;
+    ACameraManager_delete;
+    ACameraManager_deleteCameraIdList;
+    ACameraManager_getCameraCharacteristics;
+    ACameraManager_getCameraIdList;
+    ACameraManager_openCamera;
+    ACameraManager_registerAvailabilityCallback;
+    ACameraManager_unregisterAvailabilityCallback;
+    ACameraMetadata_copy;
+    ACameraMetadata_free;
+    ACameraMetadata_getAllTags;
+    ACameraMetadata_getConstEntry;
+    ACameraOutputTarget_create;
+    ACameraOutputTarget_free;
+    ACaptureRequest_addTarget;
+    ACaptureRequest_free;
+    ACaptureRequest_getAllTags;
+    ACaptureRequest_getConstEntry;
+    ACaptureRequest_removeTarget;
+    ACaptureRequest_setEntry_double;
+    ACaptureRequest_setEntry_float;
+    ACaptureRequest_setEntry_i32;
+    ACaptureRequest_setEntry_i64;
+    ACaptureRequest_setEntry_rational;
+    ACaptureRequest_setEntry_u8;
+    ACaptureSessionOutputContainer_add;
+    ACaptureSessionOutputContainer_create;
+    ACaptureSessionOutputContainer_free;
+    ACaptureSessionOutputContainer_remove;
+    ACaptureSessionOutput_create;
+    ACaptureSessionOutput_free;
+  local:
+    *;
+};
diff --git a/include/camera/ndk/NdkCameraCaptureSession.h b/include/camera/ndk/NdkCameraCaptureSession.h
index 7b314e9..d96f538 100644
--- a/include/camera/ndk/NdkCameraCaptureSession.h
+++ b/include/camera/ndk/NdkCameraCaptureSession.h
@@ -32,6 +32,8 @@
  * Do not reference types that are not part of the NDK.
  * Do not #include files that aren't part of the NDK.
  */
+#include <sys/cdefs.h>
+
 #include <android/native_window.h>
 #include "NdkCameraError.h"
 #include "NdkCameraMetadata.h"
@@ -39,9 +41,9 @@
 #ifndef _NDK_CAMERA_CAPTURE_SESSION_H
 #define _NDK_CAMERA_CAPTURE_SESSION_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
 
 /**
  * ACameraCaptureSession is an opaque type that manages frame captures of a camera device.
@@ -587,11 +589,10 @@
  */
 camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session);
 
+#endif /* __ANDROID_API__ >= 24 */
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+__END_DECLS
 
-#endif // _NDK_CAMERA_CAPTURE_SESSION_H
+#endif /* _NDK_CAMERA_CAPTURE_SESSION_H */
 
 /** @} */
diff --git a/include/camera/ndk/NdkCameraDevice.h b/include/camera/ndk/NdkCameraDevice.h
index 9011cb6..9b7f6f4 100644
--- a/include/camera/ndk/NdkCameraDevice.h
+++ b/include/camera/ndk/NdkCameraDevice.h
@@ -32,6 +32,7 @@
  * Do not reference types that are not part of the NDK.
  * Do not #include files that aren't part of the NDK.
  */
+#include <sys/cdefs.h>
 
 #include <android/native_window.h>
 #include "NdkCameraError.h"
@@ -41,9 +42,9 @@
 #ifndef _NDK_CAMERA_DEVICE_H
 #define _NDK_CAMERA_DEVICE_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
 
 /**
  * ACameraDevice is opaque type that provides access to a camera device.
@@ -658,11 +659,11 @@
         const ACameraCaptureSession_stateCallbacks* callbacks,
         /*out*/ACameraCaptureSession** session);
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#endif /* __ANDROID_API__ >= 24 */
 
-#endif // _NDK_CAMERA_DEVICE_H
+__END_DECLS
+
+#endif /* _NDK_CAMERA_DEVICE_H */
 
 /** @} */
 
diff --git a/include/camera/ndk/NdkCameraError.h b/include/camera/ndk/NdkCameraError.h
index 36251fc..6b58155 100644
--- a/include/camera/ndk/NdkCameraError.h
+++ b/include/camera/ndk/NdkCameraError.h
@@ -36,9 +36,11 @@
 #ifndef _NDK_CAMERA_ERROR_H
 #define _NDK_CAMERA_ERROR_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
 
 typedef enum {
     ACAMERA_OK = 0,
@@ -130,11 +132,10 @@
     ACAMERA_ERROR_PERMISSION_DENIED     = ACAMERA_ERROR_BASE - 13,
 } camera_status_t;
 
+#endif /* __ANDROID_API__ >= 24 */
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+__END_DECLS
 
-#endif // _NDK_CAMERA_ERROR_H
+#endif /* _NDK_CAMERA_ERROR_H */
 
 /** @} */
diff --git a/include/camera/ndk/NdkCameraManager.h b/include/camera/ndk/NdkCameraManager.h
index 9188e94..5b5c98b 100644
--- a/include/camera/ndk/NdkCameraManager.h
+++ b/include/camera/ndk/NdkCameraManager.h
@@ -36,13 +36,15 @@
 #ifndef _NDK_CAMERA_MANAGER_H
 #define _NDK_CAMERA_MANAGER_H
 
+#include <sys/cdefs.h>
+
 #include "NdkCameraError.h"
 #include "NdkCameraMetadata.h"
 #include "NdkCameraDevice.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
 
 /**
  * ACameraManager is opaque type that provides access to camera service.
@@ -271,10 +273,10 @@
         ACameraDevice_StateCallbacks* callback,
         /*out*/ACameraDevice** device);
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#endif /* __ANDROID_API__ >= 24 */
 
-#endif //_NDK_CAMERA_MANAGER_H
+__END_DECLS
+
+#endif /* _NDK_CAMERA_MANAGER_H */
 
 /** @} */
diff --git a/include/camera/ndk/NdkCameraMetadata.h b/include/camera/ndk/NdkCameraMetadata.h
index d929854..f2aec98 100644
--- a/include/camera/ndk/NdkCameraMetadata.h
+++ b/include/camera/ndk/NdkCameraMetadata.h
@@ -36,12 +36,14 @@
 #ifndef _NDK_CAMERA_METADATA_H
 #define _NDK_CAMERA_METADATA_H
 
+#include <sys/cdefs.h>
+
 #include "NdkCameraError.h"
 #include "NdkCameraMetadataTags.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
 
 /**
  * ACameraMetadata is opaque type that provides access to read-only camera metadata like camera
@@ -226,10 +228,10 @@
  */
 void ACameraMetadata_free(ACameraMetadata* metadata);
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#endif /* __ANDROID_API__ >= 24 */
 
-#endif //_NDK_CAMERA_METADATA_H
+__END_DECLS
+
+#endif /* _NDK_CAMERA_METADATA_H */
 
 /** @} */
diff --git a/include/camera/ndk/NdkCameraMetadataTags.h b/include/camera/ndk/NdkCameraMetadataTags.h
index e7f6989..0fec983 100644
--- a/include/camera/ndk/NdkCameraMetadataTags.h
+++ b/include/camera/ndk/NdkCameraMetadataTags.h
@@ -36,6 +36,12 @@
 #ifndef _NDK_CAMERA_METADATA_TAGS_H
 #define _NDK_CAMERA_METADATA_TAGS_H
 
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
+
 typedef enum acamera_metadata_section {
     ACAMERA_COLOR_CORRECTION,
     ACAMERA_CONTROL,
@@ -6901,8 +6907,10 @@
 
 } acamera_metadata_enum_android_depth_depth_is_exclusive_t;
 
+#endif /* __ANDROID_API__ >= 24 */
 
+__END_DECLS
 
-#endif //_NDK_CAMERA_METADATA_TAGS_H
+#endif /* _NDK_CAMERA_METADATA_TAGS_H */
 
 /** @} */
diff --git a/include/camera/ndk/NdkCaptureRequest.h b/include/camera/ndk/NdkCaptureRequest.h
index cd97f4d..c62ba2c 100644
--- a/include/camera/ndk/NdkCaptureRequest.h
+++ b/include/camera/ndk/NdkCaptureRequest.h
@@ -32,6 +32,9 @@
  * Do not reference types that are not part of the NDK.
  * Do not #include files that aren't part of the NDK.
  */
+
+#include <sys/cdefs.h>
+
 #include <android/native_window.h>
 #include "NdkCameraError.h"
 #include "NdkCameraMetadata.h"
@@ -39,9 +42,9 @@
 #ifndef _NDK_CAPTURE_REQUEST_H
 #define _NDK_CAPTURE_REQUEST_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
+
+#if __ANDROID_API__ >= 24
 
 // Container for output targets
 typedef struct ACameraOutputTargets ACameraOutputTargets;
@@ -300,10 +303,10 @@
  */
 void ACaptureRequest_free(ACaptureRequest* request);
 
-#ifdef __cplusplus
-} // extern "C"
-#endif
+#endif /* __ANDROID_API__ >= 24 */
 
-#endif // _NDK_CAPTURE_REQUEST_H
+__END_DECLS
+
+#endif /* _NDK_CAPTURE_REQUEST_H */
 
 /** @} */
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 5a3717e..0dedad4 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -814,31 +814,35 @@
                             // mark the last page as inaccessible, to avoid exploitation
                             // of codecs that access past the end of the allocation because
                             // they didn't check the size
-                            mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
-                            switch (code) {
-                                case GET_PARAMETER:
-                                    err = getParameter(node, index, params, size);
-                                    break;
-                                case SET_PARAMETER:
-                                    err = setParameter(node, index, params, size);
-                                    break;
-                                case GET_CONFIG:
-                                    err = getConfig(node, index, params, size);
-                                    break;
-                                case SET_CONFIG:
-                                    err = setConfig(node, index, params, size);
-                                    break;
-                                case SET_INTERNAL_OPTION:
-                                {
-                                    InternalOptionType type =
-                                        (InternalOptionType)data.readInt32();
+                            if (mprotect((char*)params + allocSize - pageSize, pageSize,
+                                    PROT_NONE) != 0) {
+                                ALOGE("mprotect failed: %s", strerror(errno));
+                            } else {
+                                switch (code) {
+                                    case GET_PARAMETER:
+                                        err = getParameter(node, index, params, size);
+                                        break;
+                                    case SET_PARAMETER:
+                                        err = setParameter(node, index, params, size);
+                                        break;
+                                    case GET_CONFIG:
+                                        err = getConfig(node, index, params, size);
+                                        break;
+                                    case SET_CONFIG:
+                                        err = setConfig(node, index, params, size);
+                                        break;
+                                    case SET_INTERNAL_OPTION:
+                                    {
+                                        InternalOptionType type =
+                                            (InternalOptionType)data.readInt32();
 
-                                    err = setInternalOption(node, index, type, params, size);
-                                    break;
+                                        err = setInternalOption(node, index, type, params, size);
+                                        break;
+                                    }
+
+                                    default:
+                                        TRESPASS();
                                 }
-
-                                default:
-                                    TRESPASS();
                             }
                         }
                     }
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 416826a..6700352 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -55,6 +55,10 @@
 enum {
     // max track header chunk to return
     kMaxTrackHeaderSize = 32,
+
+    // maximum size of an atom. Some atoms can be bigger according to the spec,
+    // but we only allow up to this size.
+    kMaxAtomSize = 64 * 1024 * 1024,
 };
 
 class MPEG4Source : public MediaSource {
@@ -884,6 +888,13 @@
         ALOGE("b/23540914");
         return ERROR_MALFORMED;
     }
+    if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) {
+        char errMsg[100];
+        sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
+        ALOGE("%s (b/28615448)", errMsg);
+        android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg));
+        return ERROR_MALFORMED;
+    }
 
     if (chunk_type != FOURCC('c', 'p', 'r', 't')
             && chunk_type != FOURCC('c', 'o', 'v', 'r')
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2dd5a57..bb12c2c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1969,19 +1969,21 @@
                 continue;
             }
             routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
-            audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, true /*fromCache*/);
-            if ((curStreamDevice & device) == 0) {
+            audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, false /*fromCache*/);
+            if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
+                    ((curStreamDevice & device) == 0)) {
                 continue;
             }
-            bool applyDefault = false;
+            bool applyVolume;
             if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
                 curStreamDevice |= device;
-            } else if (!mVolumeCurves->hasVolumeIndexForDevice(
-                    stream, Volume::getDeviceForVolume(curStreamDevice))) {
-                applyDefault = true;
+                applyVolume = (curDevice & curStreamDevice) != 0;
+            } else {
+                applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
+                        stream, Volume::getDeviceForVolume(curStreamDevice));
             }
 
-            if (applyDefault || ((curDevice & curStreamDevice) != 0)) {
+            if (applyVolume) {
                 //FIXME: workaround for truncated touch sounds
                 // delayed volume change for system stream to be removed when the problem is
                 // handled by system UI