Merge "Camera: Add low latency snapshot use case id"
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
index a3e96c4..b342206 100644
--- a/apex/ld.config.txt
+++ b/apex/ld.config.txt
@@ -61,14 +61,14 @@
 namespace.platform.search.paths = /system/${LIB}
 namespace.platform.asan.search.paths = /data/asan/system/${LIB}
 
-# /system/lib/libc.so, etc are symlinks to /bionic/lib/libc.so, etc.
-# Add /bionic/lib to the permitted paths because linker uses realpath(3)
+# /system/lib/libc.so, etc are symlinks to /apex/com.android.lib/lib/bionic/libc.so, etc.
+# Add /apex/... pat to the permitted paths because linker uses realpath(3)
 # to check the accessibility of the lib. We could add this to search.paths
 # instead but that makes the resolution of bionic libs be dependent on
-# the order of /system/lib and /bionic/lib in search.paths. If /bionic/lib
-# is after /system/lib, then /bionic/lib is never tried because libc.so
+# the order of /system/lib and /apex/... in search.paths. If /apex/...
+# is after /system/lib, then /apex/... is never tried because libc.so
 # is always found in /system/lib but fails to pass the accessibility test
 # because of its realpath.  It's better to not depend on the ordering if
 # possible.
-namespace.platform.permitted.paths = /bionic/${LIB}
-namespace.platform.asan.permitted.paths = /bionic/${LIB}
+namespace.platform.permitted.paths = /apex/com.android.runtime/${LIB}/bionic
+namespace.platform.asan.permitted.paths = /apex/com.android.runtime/${LIB}/bionic
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 93f34a8..22819cb 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -6124,6 +6124,7 @@
         FOURCC("mp41"),
         FOURCC("mp42"),
         FOURCC("dash"),
+        FOURCC("nvr1"),
 
         // Won't promise that the following file types can be played.
         // Just give these file types a chance.
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
index 910edff..fab6c64 100644
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ b/media/libmediaplayer2/JAudioTrack.cpp
@@ -571,10 +571,9 @@
 }
 
 void JAudioTrack::registerRoutingDelegates(
-        Vector<std::pair<jobject, jobject>>& routingDelegates) {
-    for (Vector<std::pair<jobject, jobject>>::iterator it = routingDelegates.begin();
-            it != routingDelegates.end(); it++) {
-        addAudioDeviceCallback(it->second, getHandler(it->second));
+        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates) {
+    for (auto it = routingDelegates.begin(); it != routingDelegates.end(); it++) {
+        addAudioDeviceCallback(it->second->getJObject(), getHandler(it->second->getJObject()));
     }
 }
 
@@ -597,20 +596,22 @@
     return env->CallObjectMethod(routingDelegateObj, jGetHandler);
 }
 
-jobject JAudioTrack::findByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key) {
+jobject JAudioTrack::findByKey(
+        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
     JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (Vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
-        if (env->IsSameObject(it->first, key)) {
-            return it->second;
+    for (auto it = mp.begin(); it != mp.end(); it++) {
+        if (env->IsSameObject(it->first->getJObject(), key)) {
+            return it->second->getJObject();
         }
     }
     return nullptr;
 }
 
-void JAudioTrack::eraseByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key) {
+void JAudioTrack::eraseByKey(
+        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
     JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (Vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
-        if (env->IsSameObject(it->first, key)) {
+    for (auto it = mp.begin(); it != mp.end(); it++) {
+        if (env->IsSameObject(it->first->getJObject(), key)) {
             mp.erase(it);
             return;
         }
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index 7c3063d..b4fa0c1 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -521,15 +521,18 @@
 status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
     ALOGV("addAudioDeviceCallback");
     Mutex::Autolock lock(mLock);
-    jobject listener = (new JObjectHolder(
-            JAudioTrack::getListener(jRoutingDelegate)))->getJObject();
+    jobject listener = JAudioTrack::getListener(jRoutingDelegate);
     if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
-        jobject handler = (new JObjectHolder(
-                JAudioTrack::getHandler(jRoutingDelegate)))->getJObject();
-        jobject routingDelegate = (new JObjectHolder(jRoutingDelegate))->getJObject();
-        mRoutingDelegates.push_back(std::pair<jobject, jobject>(listener, routingDelegate));
+        sp<JObjectHolder> listenerHolder = new JObjectHolder(listener);
+        jobject handler = JAudioTrack::getHandler(jRoutingDelegate);
+        sp<JObjectHolder> routingDelegateHolder = new JObjectHolder(jRoutingDelegate);
+
+        mRoutingDelegates.push_back(std::pair<sp<JObjectHolder>, sp<JObjectHolder>>(
+                listenerHolder, routingDelegateHolder));
+
         if (mJAudioTrack != nullptr) {
-            return mJAudioTrack->addAudioDeviceCallback(routingDelegate, handler);
+            return mJAudioTrack->addAudioDeviceCallback(
+                    routingDelegateHolder->getJObject(), handler);
         }
     }
     return NO_ERROR;
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
index 7381286..2ed4632 100644
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
@@ -405,7 +405,8 @@
      * routingDelegates: backed-up routing delegates
      *
      */
-    void registerRoutingDelegates(Vector<std::pair<jobject, jobject>>& routingDelegates);
+    void registerRoutingDelegates(
+            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates);
 
     /* get listener from RoutingDelegate object
      */
@@ -422,13 +423,15 @@
      * Returns value if key is in the map
      *         nullptr if key is not in the map
      */
-    static jobject findByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key);
+    static jobject findByKey(
+            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
 
     /*
      * Parameters:
      * map and key
      */
-    static void eraseByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key);
+    static void eraseByKey(
+            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
 
 private:
     audio_output_flags_t mFlags;
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
index 1b3f2dc..f38b7cc 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
@@ -124,7 +124,9 @@
     audio_output_flags_t    mFlags;
     sp<JObjectHolder>       mPreferredDevice;
     mutable Mutex           mLock;
-    Vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
+
+    // <listener, routingDelegate>
+    Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>> mRoutingDelegates;
 
     // static variables below not protected by mutex
     static bool             mIsOnEmulator;
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index b2361b8..cb97a3c 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -1397,6 +1397,18 @@
         case 'ulaw':
         case 'vdva':
         case 'ac-4':
+        case 'Opus':
+        case 'a3ds':
+        case 'dts+':
+        case 'dts-':
+        case 'dtsx':
+        case 'dtsy':
+        case 'ec+3':
+        case 'mha1':
+        case 'mha2':
+        case 'mhm1':
+        case 'mhm2':
+        case 'sevs':
             return !strcmp("audio", type);
 
         case 'avc1':
@@ -1445,6 +1457,35 @@
         case 'tga ':
         case 'tiff':
         case 'WRLE':
+        case 'a3d1':
+        case 'a3d2':
+        case 'a3d3':
+        case 'a3d4':
+        case 'avc3':
+        case 'avc4':
+        case 'dva1':
+        case 'dvav':
+        case 'dvh1':
+        case 'dvhe':
+        case 'hev1':
+        case 'hev2':
+        case 'hvc1':
+        case 'hvc2':
+        case 'hvt1':
+        case 'lhe1':
+        case 'lht1':
+        case 'lhv1':
+        case 'mjpg':
+        case 'mvc3':
+        case 'mvc4':
+        case 'mvd1':
+        case 'mvd2':
+        case 'mvd3':
+        case 'mvd4':
+        case 'rv60':
+        case 'svc2':
+        case 'vp08':
+        case 'vp09':
             return !strcmp("video", type);
 
         default:
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index 8377723..6a1cc71 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -25,7 +25,6 @@
     ],
 
     static_libs: [
-        "libicuandroid_utils",
         "libregistermsext",
     ],
 
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index ecddc48..7b22b05 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "mediaserver"
 //#define LOG_NDEBUG 0
 
+#include <aicu/AIcu.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
@@ -25,7 +26,6 @@
 #include "RegisterExtensions.h"
 
 // from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
 #include "MediaPlayerService.h"
 #include "ResourceManagerService.h"
 
@@ -38,7 +38,7 @@
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm(defaultServiceManager());
     ALOGI("ServiceManager: %p", sm.get());
-    InitializeIcuOrDie();
+    AIcu_initializeIcuOrDie();
     MediaPlayerService::instantiate();
     ResourceManagerService::instantiate();
     registerExtensions();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index cd09de6..b8f88cf 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -224,6 +224,14 @@
         // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
         closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
     }
+    while (!mMmapThreads.isEmpty()) {
+        const audio_io_handle_t io = mMmapThreads.keyAt(0);
+        if (mMmapThreads.valueAt(0)->isOutput()) {
+            closeOutput_nonvirtual(io); // removes entry from mMmapThreads
+        } else {
+            closeInput_nonvirtual(io);  // removes entry from mMmapThreads
+        }
+    }
 
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         // no mHardwareLock needed, as there are no other references to this
@@ -3208,24 +3216,44 @@
         goto Exit;
     }
 
-    // check audio settings permission for global effects
-    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
-        lStatus = PERMISSION_DENIED;
-        goto Exit;
-    }
-
-    // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
-    // that can only be created by audio policy manager
-    if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && !isAudioServerUid(callingUid)) {
-        lStatus = PERMISSION_DENIED;
-        goto Exit;
-    }
-
     if (mEffectsFactoryHal == 0) {
+        ALOGE("%s: no effects factory hal", __func__);
         lStatus = NO_INIT;
         goto Exit;
     }
 
+    // check audio settings permission for global effects
+    if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
+        if (!settingsAllowed()) {
+            ALOGE("%s: no permission for AUDIO_SESSION_OUTPUT_MIX", __func__);
+            lStatus = PERMISSION_DENIED;
+            goto Exit;
+        }
+    } else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
+        if (!isAudioServerUid(callingUid)) {
+            ALOGE("%s: only APM can create using AUDIO_SESSION_OUTPUT_STAGE", __func__);
+            lStatus = PERMISSION_DENIED;
+            goto Exit;
+        }
+
+        if (io == AUDIO_IO_HANDLE_NONE) {
+            ALOGE("%s: APM must specify output when using AUDIO_SESSION_OUTPUT_STAGE", __func__);
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+    } else {
+        // general sessionId.
+
+        if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
+            ALOGE("%s: invalid sessionId %d", __func__, sessionId);
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+
+        // TODO: should we check if the callingUid (limited to pid) is in mAudioSessionRefs
+        // to prevent creating an effect when one doesn't actually have track with that session?
+    }
+
     {
         // Get the full effect descriptor from the uuid/type.
         // If the session is the output mix, prefer an auxiliary effect,
@@ -3271,38 +3299,13 @@
         // because of code checking output when entering the function.
         // Note: io is never 0 when creating an effect on an input
         if (io == AUDIO_IO_HANDLE_NONE) {
-            if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
-                // output must be specified by AudioPolicyManager when using session
-                // AUDIO_SESSION_OUTPUT_STAGE
-                lStatus = BAD_VALUE;
-                goto Exit;
-            }
             // look for the thread where the specified audio session is present
-            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-                uint32_t sessionType = mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
-                if (sessionType != 0) {
-                    io = mPlaybackThreads.keyAt(i);
-                    // thread with same effect session is preferable
-                    if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) {
-                        break;
-                    }
-                }
+            io = findIoHandleBySessionId_l(sessionId, mPlaybackThreads);
+            if (io == AUDIO_IO_HANDLE_NONE) {
+                io = findIoHandleBySessionId_l(sessionId, mRecordThreads);
             }
             if (io == AUDIO_IO_HANDLE_NONE) {
-                for (size_t i = 0; i < mRecordThreads.size(); i++) {
-                    if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
-                        io = mRecordThreads.keyAt(i);
-                        break;
-                    }
-                }
-            }
-            if (io == AUDIO_IO_HANDLE_NONE) {
-                for (size_t i = 0; i < mMmapThreads.size(); i++) {
-                    if (mMmapThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
-                        io = mMmapThreads.keyAt(i);
-                        break;
-                    }
-                }
+                io = findIoHandleBySessionId_l(sessionId, mMmapThreads);
             }
             // If no output thread contains the requested session ID, default to
             // first output. The effect chain will be moved to the correct output
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1441e15..ec5dfb1 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -558,6 +558,26 @@
 
 #include "PatchPanel.h"
 
+    // Find io handle by session id.
+    // Preference is given to an io handle with a matching effect chain to session id.
+    // If none found, AUDIO_IO_HANDLE_NONE is returned.
+    template <typename T>
+    static audio_io_handle_t findIoHandleBySessionId_l(
+            audio_session_t sessionId, const T& threads) {
+        audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
+
+        for (size_t i = 0; i < threads.size(); i++) {
+            const uint32_t sessionType = threads.valueAt(i)->hasAudioSession(sessionId);
+            if (sessionType != 0) {
+                io = threads.keyAt(i);
+                if ((sessionType & AudioFlinger::ThreadBase::EFFECT_SESSION) != 0) {
+                    break; // effect chain here.
+                }
+            }
+        }
+        return io;
+    }
+
     // server side of the client's IAudioTrack
     class TrackHandle : public android::BnAudioTrack {
     public:
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4a0e764..5574e1c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2503,7 +2503,7 @@
         }
         for (auto curVolGroup : getVolumeGroups()) {
             VolumeSource curVolSrc = toVolumeSource(curVolGroup);
-            if (!(curVolSrc == vs || isInCall())) {
+            if (curVolSrc != vs) {
                 continue;
             }
             if (!(desc->isActive(vs) || isInCall())) {
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index 4f3ac1b..06baac9 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -76,9 +76,6 @@
 
 namespace android {
 
-    using namespace android::base;
-    using namespace android::content::pm;
-
 // individual records kept in memory: age or count
 // age: <= 28 hours (1 1/6 days)
 // count: hard limit of # records
@@ -649,7 +646,8 @@
         }
 
         if (binder != NULL) {
-            sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
+            sp<content::pm::IPackageManagerNative> package_mgr =
+                            interface_cast<content::pm::IPackageManagerNative>(binder);
             binder::Status status;
 
             std::vector<int> uids;
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 661a475..fd34d5b 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -22,7 +22,6 @@
 LOCAL_SRC_FILES := main_extractorservice.cpp
 LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
     liblog libandroidicu libavservices_minijail
-LOCAL_STATIC_LIBRARIES := libicuandroid_utils
 LOCAL_MODULE:= mediaextractor
 LOCAL_INIT_RC := mediaextractor.rc
 LOCAL_C_INCLUDES := frameworks/av/media/libmedia
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 3c15bfd..06b532d 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -15,6 +15,7 @@
 ** limitations under the License.
 */
 
+#include <aicu/AIcu.h>
 #include <fcntl.h>
 #include <sys/prctl.h>
 #include <sys/wait.h>
@@ -29,7 +30,6 @@
 #include <utils/misc.h>
 
 // from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
 #include "MediaExtractorService.h"
 #include "MediaUtils.h"
 #include "minijail.h"
@@ -64,7 +64,7 @@
 
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
-    InitializeIcuOrDie();
+    AIcu_initializeIcuOrDie();
 
     strcpy(argv[0], "media.extractor");
     sp<ProcessState> proc(ProcessState::self());