Merge cherrypicks of [3166006, 3165952, 3164925, 3164926, 3164927, 3164928, 3167313, 3167314, 3167315, 3167316, 3167317, 3167318, 3167319, 3167320, 3167321, 3167322, 3166318, 3166319, 3166320, 3166321, 3166322, 3166323, 3166324, 3167333, 3167334, 3167373, 3165112, 3166325, 3165229, 3165230] into nyc-mr2-release

Change-Id: I13459e3d398de152ffed93f79acb12c8a59165db
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index ca68722..cd284f6 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -1037,6 +1037,10 @@
                 bool haveVideo = false;
                 for (size_t i = 0; i < numTracks; ++i) {
                     sp<IMediaSource> source = extractor->getTrack(i);
+                    if (source == nullptr) {
+                        fprintf(stderr, "skip NULL track %zu, track count %zu.\n", i, numTracks);
+                        continue;
+                    }
 
                     const char *mime;
                     CHECK(source->getFormat()->findCString(
@@ -1099,6 +1103,10 @@
                 }
 
                 mediaSource = extractor->getTrack(i);
+                if (mediaSource == nullptr) {
+                    fprintf(stderr, "skip NULL track %zu, total tracks %zu.\n", i, numTracks);
+                    return -1;
+                }
             }
         }
 
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index bca3832..cf59357 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -171,7 +171,8 @@
     mWriter = new MPEG2TSWriter(
             this, &MyConvertingStreamSource::WriteDataWrapper);
 
-    for (size_t i = 0; i < extractor->countTracks(); ++i) {
+    size_t numTracks = extractor->countTracks();
+    for (size_t i = 0; i < numTracks; ++i) {
         const sp<MetaData> &meta = extractor->getTrackMetaData(i);
 
         const char *mime;
@@ -181,7 +182,12 @@
             continue;
         }
 
-        CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
+        sp<IMediaSource> track = extractor->getTrack(i);
+        if (track == nullptr) {
+            fprintf(stderr, "skip NULL track %zu, total tracks %zu\n", i, numTracks);
+            continue;
+        }
+        CHECK_EQ(mWriter->addSource(track), (status_t)OK);
     }
 
     CHECK_EQ(mWriter->start(), (status_t)OK);
diff --git a/include/media/IMediaExtractor.h b/include/media/IMediaExtractor.h
index 34b15e9..743ef7f 100644
--- a/include/media/IMediaExtractor.h
+++ b/include/media/IMediaExtractor.h
@@ -30,6 +30,9 @@
     DECLARE_META_INTERFACE(MediaExtractor);
 
     virtual size_t countTracks() = 0;
+    // This function could return NULL IMediaSource even when index is within the
+    // track count returned by countTracks, since it's possible the track is malformed
+    // and it's not detected during countTracks call.
     virtual sp<IMediaSource> getTrack(size_t index) = 0;
 
     enum GetTrackMetaDataFlags {
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index 51a1130..393286d 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -559,8 +559,13 @@
 
 void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
     uint32_t size = data.readInt32();
-    vector.insertAt((size_t)0, size);
-    data.read(vector.editArray(), size);
+    if (vector.insertAt((size_t)0, size) < 0) {
+        vector.clear();
+    }
+    if (data.read(vector.editArray(), size) != NO_ERROR) {
+        vector.clear();
+        android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
+    }
 }
 
 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 72d1d7c..4be1118 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -209,11 +209,16 @@
     for (size_t i = 0; i < tracks.size(); i++) {
         const String8 desc = trackDescriptions.itemAt(i);
         str.appendFormat("    track {%s} ", desc.string());
-        const sp<IMediaSource> source = tracks.itemAt(i).promote();
-        if (source == NULL) {
-            str.append(": deleted\n");
+        wp<IMediaSource> wSource = tracks.itemAt(i);
+        if (wSource == NULL) {
+            str.append(": null\n");
         } else {
-            str.appendFormat(": active\n");
+            const sp<IMediaSource> source = wSource.promote();
+            if (source == NULL) {
+                str.append(": deleted\n");
+            } else {
+                str.appendFormat(": active\n");
+            }
         }
     }
     return str;
@@ -232,9 +237,14 @@
         if (extractor != NULL && extractor == ex) {
             if (instance.tracks.size() > 5) {
                 instance.tracks.resize(5);
+                instance.trackDescriptions.resize(5);
             }
             instance.tracks.push_front(source);
-            instance.trackDescriptions.add(source->getFormat()->toString());
+            if (source != NULL) {
+                instance.trackDescriptions.push_front(source->getFormat()->toString());
+            } else {
+                instance.trackDescriptions.push_front(String8::empty());
+            }
             break;
         }
     }
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 4558b3c..c3e8f20 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -305,6 +305,10 @@
 
     sp<IMediaSource> source = mImpl->getTrack(index);
 
+    if (source == nullptr) {
+        return ERROR_MALFORMED;
+    }
+
     status_t ret = source->start();
     if (ret != OK) {
         return ret;
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
index f7192b1c..7202f98 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
@@ -560,7 +560,7 @@
 
     BitstreamShow13Bits(stream, &code);
 
-    if (code == 0)
+    if (code < 8)
     {
         return VLC_CODE_ERROR;
     }
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index f6e8d60..7bd66b1 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -353,6 +353,8 @@
             break;
     }
 
+    Mutex::Autolock _l(mLock);
+
     ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName);
     OMX_ERRORTYPE err = master->destroyComponentInstance(
             static_cast<OMX_COMPONENTTYPE *>(mHandle));
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index a75e3dd..a41ed95 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -665,6 +665,7 @@
                                        audio_io_handle_t *ioHandle,
                                        audio_devices_t *device)
 {
+    Mutex::Autolock _l(mLock);
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
@@ -674,6 +675,7 @@
 
 status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)
 {
+    Mutex::Autolock _l(mLock);
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index eebc487..c6dcd01 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -505,6 +505,8 @@
     if (!captureHotwordAllowed()) {
         return;
     }
+    Vector<audio_session_t> releasedSessions;
+
     {
         AutoMutex lock(mLock);
         for (size_t i = 0; i < mModels.size(); i++) {
@@ -514,9 +516,16 @@
                 mHwDevice->stop_recognition(mHwDevice, model->mHandle);
             }
             mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
+            releasedSessions.add(model->mCaptureSession);
         }
         mModels.clear();
     }
+
+    for (size_t i = 0; i < releasedSessions.size(); i++) {
+        // do not call AudioSystem methods with mLock held
+        AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
+    }
+
     if (mClient != 0) {
         IInterface::asBinder(mClient)->unlinkToDeath(this);
     }
@@ -558,33 +567,43 @@
         return BAD_VALUE;
     }
 
-    AutoMutex lock(mLock);
-
-    if (mModels.size() >= mDescriptor.properties.max_sound_models) {
-        ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
-              mDescriptor.properties.max_sound_models);
-        return INVALID_OPERATION;
-    }
-
-    status_t status = mHwDevice->load_sound_model(mHwDevice, sound_model,
-                                                  SoundTriggerHwService::soundModelCallback,
-                                                  this, handle);
-
-    if (status != NO_ERROR) {
-        return status;
-    }
     audio_session_t session;
     audio_io_handle_t ioHandle;
     audio_devices_t device;
-
-    status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
+    // do not call AudioSystem methods with mLock held
+    status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
     if (status != NO_ERROR) {
         return status;
     }
 
-    sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
-    mModels.replaceValueFor(*handle, model);
+    {
+        AutoMutex lock(mLock);
 
+        if (mModels.size() >= mDescriptor.properties.max_sound_models) {
+            ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
+                  mDescriptor.properties.max_sound_models);
+            status = INVALID_OPERATION;
+            goto exit;
+        }
+
+        status_t status = mHwDevice->load_sound_model(mHwDevice,
+                                                      sound_model,
+                                                      SoundTriggerHwService::soundModelCallback,
+                                                      this,
+                                                      handle);
+        if (status != NO_ERROR) {
+            goto exit;
+        }
+
+        sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type);
+        mModels.replaceValueFor(*handle, model);
+    }
+
+exit:
+    if (status != NO_ERROR) {
+        // do not call AudioSystem methods with mLock held
+        AudioSystem::releaseSoundTriggerSession(session);
+    }
     return status;
 }
 
@@ -594,25 +613,26 @@
     if (!captureHotwordAllowed()) {
         return PERMISSION_DENIED;
     }
+    status_t status;
+    audio_session_t session;
 
-    AutoMutex lock(mLock);
-    return unloadSoundModel_l(handle);
-}
-
-status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle)
-{
-    ssize_t index = mModels.indexOfKey(handle);
-    if (index < 0) {
-        return BAD_VALUE;
+    {
+      AutoMutex lock(mLock);
+      ssize_t index = mModels.indexOfKey(handle);
+      if (index < 0) {
+          return BAD_VALUE;
+      }
+      sp<Model> model = mModels.valueAt(index);
+      mModels.removeItem(handle);
+      if (model->mState == Model::STATE_ACTIVE) {
+          mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+          model->mState = Model::STATE_IDLE;
+      }
+      status = mHwDevice->unload_sound_model(mHwDevice, handle);
+      session = model->mCaptureSession;
     }
-    sp<Model> model = mModels.valueAt(index);
-    mModels.removeItem(handle);
-    if (model->mState == Model::STATE_ACTIVE) {
-        mHwDevice->stop_recognition(mHwDevice, model->mHandle);
-        model->mState = Model::STATE_IDLE;
-    }
-    AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);
-    return mHwDevice->unload_sound_model(mHwDevice, handle);
+    AudioSystem::releaseSoundTriggerSession(session);
+    return status;
 }
 
 status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index 2619a5f..d05dacd 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -141,9 +141,6 @@
 
     private:
 
-       status_t unloadSoundModel_l(sound_model_handle_t handle);
-
-
         Mutex                                  mLock;
         wp<SoundTriggerHwService>              mService;
         struct sound_trigger_hw_device*        mHwDevice;