Merge "Fix NuPlayer deadlock" into lmp-dev
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 140e1ae..e11f40e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -227,7 +227,7 @@
 
             if (mStartupSeekTimeUs >= 0) {
                 if (mStartupSeekTimeUs == 0) {
-                    notifySeekComplete();
+                    notifySeekComplete_l();
                 } else {
                     mPlayer->seekToAsync(mStartupSeekTimeUs);
                 }
@@ -320,7 +320,7 @@
             // pretend that the seek completed. It will actually happen when starting playback.
             // TODO: actually perform the seek here, so the player is ready to go at the new
             // location
-            notifySeekComplete();
+            notifySeekComplete_l();
             break;
         }
 
@@ -525,23 +525,28 @@
 }
 
 void NuPlayerDriver::notifySeekComplete() {
+    Mutex::Autolock autoLock(mLock);
+    notifySeekComplete_l();
+}
+
+void NuPlayerDriver::notifySeekComplete_l() {
     bool wasSeeking = true;
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mState == STATE_STOPPED_AND_PREPARING) {
-            wasSeeking = false;
-            mState = STATE_STOPPED_AND_PREPARED;
-            mCondition.broadcast();
-            if (!mIsAsyncPrepare) {
-                // if we are preparing synchronously, no need to notify listener
-                return;
-            }
-        } else if (mState == STATE_STOPPED) {
-            // no need to notify listener
+    if (mState == STATE_STOPPED_AND_PREPARING) {
+        wasSeeking = false;
+        mState = STATE_STOPPED_AND_PREPARED;
+        mCondition.broadcast();
+        if (!mIsAsyncPrepare) {
+            // if we are preparing synchronously, no need to notify listener
             return;
         }
+    } else if (mState == STATE_STOPPED) {
+        // no need to notify listener
+        return;
     }
+    // note: notifyListener called with lock held
+    mLock.unlock();
     notifyListener(wasSeeking ? MEDIA_SEEK_COMPLETE : MEDIA_PREPARED);
+    mLock.lock();
 }
 
 void NuPlayerDriver::notifyFrameStats(
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index f520395..a006d8f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -69,6 +69,7 @@
     void notifyDuration(int64_t durationUs);
     void notifyPosition(int64_t positionUs);
     void notifySeekComplete();
+    void notifySeekComplete_l();
     void notifyFrameStats(int64_t numFramesTotal, int64_t numFramesDropped);
     void notifyListener(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
     void notifyFlagsChanged(uint32_t flags);