MediaPlayer2: hook up srcId.

Test: MediaPlayer2 plays.
Bug: 63934228
Change-Id: I0dd8b345d89034600e1c0fb3f58e4d92990c0054
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index ea9d270..c414f23 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -314,6 +314,7 @@
                 if (err == OK) {
                     *source = genericSource;
                 } else {
+                    *source = NULL;
                     ALOGE("Failed to create NuPlayer2Source!");
                 }
 
@@ -364,7 +365,7 @@
 
         default:
             err = BAD_TYPE;
-            source = NULL;
+            *source = NULL;
             *dataSourceType = DATA_SOURCE_TYPE_NONE;
             ALOGE("invalid data source type!");
             break;
@@ -376,13 +377,22 @@
 void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
     DATA_SOURCE_TYPE dataSourceType;
     sp<Source> source;
-    status_t err = createNuPlayer2Source(dsd, &source, &dataSourceType);
+    createNuPlayer2Source(dsd, &source, &dataSourceType);
 
+    // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
+    // and expects notifySetDataSourceCompleted regardless of success or failure.
+    // This will be changed since setDataSource should be asynchronous at JAVA level.
+    // When it succeeds, app will get onInfo notification. Otherwise, onError
+    // will be called.
+    /*
     if (err != OK) {
-        notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
+        notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
         return;
     }
 
+    // Now, source != NULL.
+    */
+
     mDataSourceType = dataSourceType;
 
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
@@ -394,13 +404,17 @@
 void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
     DATA_SOURCE_TYPE dataSourceType;
     sp<Source> source;
-    status_t err = createNuPlayer2Source(dsd, &source, &dataSourceType);
+    createNuPlayer2Source(dsd, &source, &dataSourceType);
 
+    /*
     if (err != OK) {
-        notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
+        notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
         return;
     }
 
+    // Now, source != NULL.
+    */
+
     mNextDataSourceType = dataSourceType;
 
     sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
@@ -632,7 +646,7 @@
             CHECK(mDriver != NULL);
             sp<NuPlayer2Driver> driver = mDriver.promote();
             if (driver != NULL) {
-                driver->notifySetDataSourceCompleted(err);
+                driver->notifySetDataSourceCompleted(mSrcId, err);
             }
             break;
         }
@@ -831,7 +845,7 @@
             if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
                 sp<NuPlayer2Driver> driver = mDriver.promote();
                 if (driver != NULL) {
-                    driver->notifyDuration(durationUs);
+                    driver->notifyDuration(mSrcId, durationUs);
                 }
             }
 
@@ -921,6 +935,7 @@
                 onStart();
             }
             mPausedByClient = false;
+            notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
             break;
         }
 
@@ -960,6 +975,7 @@
             if (err == OK) {
                 if (rate.mSpeed == 0.f) {
                     onPause();
+                    notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
                     mPausedByClient = true;
                     // save all other settings (using non-paused speed)
                     // so we can restore them on start
@@ -1114,9 +1130,9 @@
                     // video tracks found) and we just ran out of input data.
 
                     if (err == ERROR_END_OF_STREAM) {
-                        notifyListener(MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+                        notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
                     } else {
-                        notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+                        notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
                     }
                 }
                 break;
@@ -1201,7 +1217,7 @@
                         mSource->getFormat(false /* audio */);
 
                 setVideoScalingMode(mVideoScalingMode);
-                updateVideoSize(inputFormat, format);
+                updateVideoSize(mSrcId, inputFormat, format);
             } else if (what == DecoderBase::kWhatShutdownCompleted) {
                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
                 if (audio) {
@@ -1275,10 +1291,10 @@
                                 || mVideoDecoder == NULL) {
                             // When both audio and video have error, or this stream has only audio
                             // which has error, notify client of error.
-                            notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+                            notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
                         } else {
                             // Only audio track has error. Video track could be still good to play.
-                            notifyListener(MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
+                            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
                         }
                         mAudioDecoderError = true;
                     } else {
@@ -1286,10 +1302,10 @@
                                 || mAudioSink == NULL || mAudioDecoder == NULL) {
                             // When both audio and video have error, or this stream has only video
                             // which has error, notify client of error.
-                            notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+                            notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
                         } else {
                             // Only video track has error. Audio track could be still good to play.
-                            notifyListener(MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
+                            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
                         }
                         mVideoDecoderError = true;
                     }
@@ -1339,12 +1355,12 @@
                          audio ? "audio" : "video", finalResult);
 
                     notifyListener(
-                            MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
+                            mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
                 }
 
                 if ((mAudioEOS || mAudioDecoder == NULL)
                         && (mVideoEOS || mVideoDecoder == NULL)) {
-                    notifyListener(MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+                    notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
                 }
             } else if (what == Renderer::kWhatFlushComplete) {
                 int32_t audio;
@@ -1365,10 +1381,10 @@
                 handleFlushComplete(audio, false /* isDecoder */);
                 finishFlushIfPossible();
             } else if (what == Renderer::kWhatVideoRenderingStart) {
-                notifyListener(MEDIA2_INFO, MEDIA2_INFO_RENDERING_START, 0);
+                notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_RENDERING_START, 0);
             } else if (what == Renderer::kWhatMediaRenderingStart) {
                 ALOGV("media rendering started");
-                notifyListener(MEDIA2_STARTED, 0, 0);
+                notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
             } else if (what == Renderer::kWhatAudioTearDown) {
                 int32_t reason;
                 CHECK(msg->findInt32("reason", &reason));
@@ -1421,7 +1437,7 @@
             int64_t timerUs;
             CHECK(msg->findInt64("timerUs", &timerUs));
 
-            notifyListener(MEDIA2_NOTIFY_TIME, timerUs, 0);
+            notifyListener(mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
             break;
         }
 
@@ -1437,6 +1453,9 @@
             ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
                     (long long)seekTimeUs, mode, needNotify);
 
+            // seeks can take a while, so we essentially paused
+            notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
+
             if (!mStarted) {
                 // Seek before the player is started. In order to preview video,
                 // need to start the player and pause it. This branch is called
@@ -1449,7 +1468,7 @@
                     mPausedByClient = true;
                 }
                 if (needNotify) {
-                    notifyDriverSeekComplete();
+                    notifyDriverSeekComplete(mSrcId);
                 }
                 break;
             }
@@ -1474,6 +1493,7 @@
         case kWhatPause:
         {
             onPause();
+            notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
             mPausedByClient = true;
             break;
         }
@@ -1577,7 +1597,7 @@
         ALOGE("no metadata for either audio or video source");
         mSource->stop();
         mSourceStarted = false;
-        notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
+        notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
         return;
     }
     ALOGV_IF(!hasAudio, "no metadata for audio source");  // video only stream
@@ -1616,7 +1636,7 @@
     if (err != OK) {
         mSource->stop();
         mSourceStarted = false;
-        notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+        notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
         return;
     }
 
@@ -1658,7 +1678,7 @@
             ALOGV("stopPlaybackTimer()  log  %20" PRId64 "", played);
 
             if (played > 0) {
-                driver->notifyMorePlayingTimeUs((played+500)/1000);
+                driver->notifyMorePlayingTimeUs(mSrcId, (played+500)/1000);
             }
         }
         mLastStartedPlayingTimeNs = 0;
@@ -1686,9 +1706,9 @@
             ALOGV("stopRebufferingTimer()  log  %20" PRId64 "", rebuffered);
 
             if (rebuffered > 0) {
-                driver->notifyMoreRebufferingTimeUs((rebuffered+500)/1000);
+                driver->notifyMoreRebufferingTimeUs(mSrcId, (rebuffered+500)/1000);
                 if (exitingPlayback) {
-                    driver->notifyRebufferingWhenExit(true);
+                    driver->notifyRebufferingWhenExit(mSrcId, true);
                 }
             }
         }
@@ -2005,11 +2025,12 @@
 }
 
 void NuPlayer2::updateVideoSize(
+        int64_t srcId,
         const sp<AMessage> &inputFormat,
         const sp<AMessage> &outputFormat) {
     if (inputFormat == NULL) {
         ALOGW("Unknown video size, reporting 0x0!");
-        notifyListener(MEDIA2_SET_VIDEO_SIZE, 0, 0);
+        notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
         return;
     }
     int32_t err = OK;
@@ -2088,12 +2109,13 @@
     }
 
     notifyListener(
+            srcId,
             MEDIA2_SET_VIDEO_SIZE,
             displayWidth,
             displayHeight);
 }
 
-void NuPlayer2::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
+void NuPlayer2::notifyListener(int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
     if (mDriver == NULL) {
         return;
     }
@@ -2104,7 +2126,7 @@
         return;
     }
 
-    driver->notifyListener(msg, ext1, ext2, in);
+    driver->notifyListener(srcId, msg, ext1, ext2, in);
 }
 
 void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
@@ -2369,7 +2391,7 @@
     if (mDriver != NULL) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
         if (driver != NULL) {
-            driver->notifyResetComplete();
+            driver->notifyResetComplete(mSrcId);
         }
     }
 
@@ -2411,7 +2433,7 @@
     if (mDriver != NULL) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
         if (driver != NULL) {
-            driver->notifySetSurfaceComplete();
+            driver->notifySetSurfaceComplete(mSrcId);
         }
     }
 }
@@ -2443,15 +2465,15 @@
 void NuPlayer2::finishResume() {
     if (mResumePending) {
         mResumePending = false;
-        notifyDriverSeekComplete();
+        notifyDriverSeekComplete(mSrcId);
     }
 }
 
-void NuPlayer2::notifyDriverSeekComplete() {
+void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
     if (mDriver != NULL) {
         sp<NuPlayer2Driver> driver = mDriver.promote();
         if (driver != NULL) {
-            driver->notifySeekComplete();
+            driver->notifySeekComplete(srcId);
         }
     }
 }
@@ -2460,7 +2482,8 @@
     int32_t what;
     CHECK(msg->findInt32("what", &what));
 
-    // TODO: tell this is for mSource or mNextSource.
+    int64_t srcId;
+    CHECK(msg->findInt64("srcId", &srcId));
     switch (what) {
         case Source::kWhatPrepared:
         {
@@ -2491,9 +2514,9 @@
                 // the app received the "prepare complete" callback.
                 int64_t durationUs;
                 if (mSource->getDuration(&durationUs) == OK) {
-                    driver->notifyDuration(durationUs);
+                    driver->notifyDuration(srcId, durationUs);
                 }
-                driver->notifyPrepareCompleted(err);
+                driver->notifyPrepareCompleted(srcId, err);
             }
 
             break;
@@ -2510,7 +2533,7 @@
             ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p  parcel size: %zu",
                     drmInfo.get(), parcel.dataSize());
 
-            notifyListener(MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
+            notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
 
             break;
         }
@@ -2537,9 +2560,9 @@
 
                 if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
                     driver->notifyListener(
-                            MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
+                            srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
                 }
-                driver->notifyFlagsChanged(flags);
+                driver->notifyFlagsChanged(srcId, flags);
             }
 
             if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
@@ -2560,7 +2583,7 @@
             sp<AMessage> format;
             CHECK(msg->findMessage("format", &format));
 
-            updateVideoSize(format);
+            updateVideoSize(srcId, format);
             break;
         }
 
@@ -2569,7 +2592,7 @@
             int32_t percentage;
             CHECK(msg->findInt32("percentage", &percentage));
 
-            notifyListener(MEDIA2_BUFFERING_UPDATE, percentage, 0);
+            notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
             break;
         }
 
@@ -2583,7 +2606,7 @@
                 mPausedForBuffering = true;
                 onPause();
             }
-            notifyListener(MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
+            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
             break;
         }
 
@@ -2601,7 +2624,7 @@
                     onResume();
                 }
             }
-            notifyListener(MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
+            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
             break;
         }
 
@@ -2610,7 +2633,7 @@
             int32_t kbps;
             CHECK(msg->findInt32("bandwidth", &kbps));
 
-            notifyListener(MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
+            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
             break;
         }
 
@@ -2627,7 +2650,7 @@
         {
             sp<ABuffer> buffer;
             if (!msg->findBuffer("buffer", &buffer)) {
-                notifyListener(MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
+                notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
             } else {
                 sendTimedMetaData(buffer);
             }
@@ -2682,7 +2705,7 @@
 
         case Source::kWhatDrmNoLicense:
         {
-            notifyListener(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
+            notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
             break;
         }
 
@@ -2712,7 +2735,7 @@
 
         case NuPlayer2::CCDecoder::kWhatTrackAdded:
         {
-            notifyListener(MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
+            notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
 
             break;
         }
@@ -2739,7 +2762,7 @@
     in.writeInt32(buffer->size());
     in.write(buffer->data(), buffer->size());
 
-    notifyListener(MEDIA2_SUBTITLE_DATA, 0, 0, &in);
+    notifyListener(mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &in);
 }
 
 void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
@@ -2752,7 +2775,7 @@
     in.writeInt32(buffer->size());
     in.write(buffer->data(), buffer->size());
 
-    notifyListener(MEDIA2_META_DATA, 0, 0, &in);
+    notifyListener(mSrcId, MEDIA2_META_DATA, 0, 0, &in);
 }
 
 void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
@@ -2782,9 +2805,9 @@
     }
 
     if ((parcel.dataSize() > 0)) {
-        notifyListener(MEDIA2_TIMED_TEXT, 0, 0, &parcel);
+        notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &parcel);
     } else {  // send an empty timed text
-        notifyListener(MEDIA2_TIMED_TEXT, 0, 0);
+        notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
     }
 }
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
index bf55b65..e884b92 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
@@ -284,10 +284,11 @@
             bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange = true);
 
     void updateVideoSize(
+            int64_t srcId,
             const sp<AMessage> &inputFormat,
             const sp<AMessage> &outputFormat = NULL);
 
-    void notifyListener(int msg, int ext1, int ext2, const Parcel *in = NULL);
+    void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const Parcel *in = NULL);
 
     void handleFlushComplete(bool audio, bool isDecoder);
     void finishFlushIfPossible();
@@ -303,7 +304,7 @@
     void flushDecoder(bool audio, bool needShutdown);
 
     void finishResume();
-    void notifyDriverSeekComplete();
+    void notifyDriverSeekComplete(int64_t srcId);
 
     void postScanSources();
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
index 2a1e904..245e3ca 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
@@ -25,6 +25,7 @@
 #include "NuPlayer2.h"
 #include "NuPlayer2Source.h"
 
+#include <media/DataSourceDesc.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AUtils.h>
@@ -103,6 +104,7 @@
     : mState(STATE_IDLE),
       mIsAsyncPrepare(false),
       mAsyncResult(UNKNOWN_ERROR),
+      mSrcId(0),
       mSetSurfaceInProgress(false),
       mDurationUs(-1),
       mPositionUs(-1),
@@ -174,6 +176,7 @@
         return INVALID_OPERATION;
     }
 
+    mSrcId = dsd->mId;
     mState = STATE_SET_DATASOURCE_PENDING;
 
     mPlayer->setDataSourceAsync(dsd);
@@ -356,7 +359,7 @@
 
         case STATE_PAUSED:
             mState = STATE_STOPPED;
-            notifyListener_l(MEDIA2_STOPPED);
+            //notifyListener_l(MEDIA2_STOPPED);
             break;
 
         case STATE_PREPARED:
@@ -391,7 +394,6 @@
 
         case STATE_RUNNING:
             mState = STATE_PAUSED;
-            notifyListener_l(MEDIA2_PAUSED);
             mPlayer->pause();
             break;
 
@@ -415,7 +417,6 @@
         Mutex::Autolock autoLock(mLock);
         if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
             mState = STATE_PAUSED;
-            notifyListener_l(MEDIA2_PAUSED);
         } else if (rate.mSpeed != 0.f
                 && (mState == STATE_PAUSED
                     || mState == STATE_STOPPED_AND_PREPARED
@@ -452,8 +453,6 @@
         {
             mAtEOS = false;
             mSeekInProgress = true;
-            // seeks can take a while, so we essentially paused
-            notifyListener_l(MEDIA2_PAUSED);
             mPlayer->seekToAsync(seekTimeUs, mode, true /* needNotify */);
             break;
         }
@@ -624,7 +623,7 @@
         {
             CHECK(mIsAsyncPrepare);
 
-            notifyListener_l(MEDIA2_PREPARED);
+            notifyListener_l(mSrcId, MEDIA2_PREPARED);
             break;
         }
 
@@ -633,7 +632,7 @@
     }
 
     if (mState != STATE_STOPPED) {
-        notifyListener_l(MEDIA2_STOPPED);
+        // notifyListener_l(MEDIA2_STOPPED);
     }
 
     mState = STATE_RESET_IN_PROGRESS;
@@ -767,7 +766,7 @@
     return OK;
 }
 
-void NuPlayer2Driver::notifyResetComplete() {
+void NuPlayer2Driver::notifyResetComplete(int64_t /* srcId */) {
     ALOGD("notifyResetComplete(%p)", this);
     Mutex::Autolock autoLock(mLock);
 
@@ -776,7 +775,7 @@
     mCondition.broadcast();
 }
 
-void NuPlayer2Driver::notifySetSurfaceComplete() {
+void NuPlayer2Driver::notifySetSurfaceComplete(int64_t /* srcId */) {
     ALOGV("notifySetSurfaceComplete(%p)", this);
     Mutex::Autolock autoLock(mLock);
 
@@ -786,35 +785,35 @@
     mCondition.broadcast();
 }
 
-void NuPlayer2Driver::notifyDuration(int64_t durationUs) {
+void NuPlayer2Driver::notifyDuration(int64_t /* srcId */, int64_t durationUs) {
     Mutex::Autolock autoLock(mLock);
     mDurationUs = durationUs;
 }
 
-void NuPlayer2Driver::notifyMorePlayingTimeUs(int64_t playingUs) {
+void NuPlayer2Driver::notifyMorePlayingTimeUs(int64_t /* srcId */, int64_t playingUs) {
     Mutex::Autolock autoLock(mLock);
     mPlayingTimeUs += playingUs;
 }
 
-void NuPlayer2Driver::notifyMoreRebufferingTimeUs(int64_t rebufferingUs) {
+void NuPlayer2Driver::notifyMoreRebufferingTimeUs(int64_t /* srcId */, int64_t rebufferingUs) {
     Mutex::Autolock autoLock(mLock);
     mRebufferingTimeUs += rebufferingUs;
     mRebufferingEvents++;
 }
 
-void NuPlayer2Driver::notifyRebufferingWhenExit(bool status) {
+void NuPlayer2Driver::notifyRebufferingWhenExit(int64_t /* srcId */, bool status) {
     Mutex::Autolock autoLock(mLock);
     mRebufferingAtExit = status;
 }
 
-void NuPlayer2Driver::notifySeekComplete() {
+void NuPlayer2Driver::notifySeekComplete(int64_t srcId) {
     ALOGV("notifySeekComplete(%p)", this);
     Mutex::Autolock autoLock(mLock);
     mSeekInProgress = false;
-    notifySeekComplete_l();
+    notifySeekComplete_l(srcId);
 }
 
-void NuPlayer2Driver::notifySeekComplete_l() {
+void NuPlayer2Driver::notifySeekComplete_l(int64_t srcId) {
     bool wasSeeking = true;
     if (mState == STATE_STOPPED_AND_PREPARING) {
         wasSeeking = false;
@@ -828,7 +827,7 @@
         // no need to notify listener
         return;
     }
-    notifyListener_l(wasSeeking ? MEDIA2_SEEK_COMPLETE : MEDIA2_PREPARED);
+    notifyListener_l(srcId, wasSeeking ? MEDIA2_SEEK_COMPLETE : MEDIA2_PREPARED);
 }
 
 status_t NuPlayer2Driver::dump(
@@ -911,9 +910,11 @@
 void NuPlayer2Driver::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatNotifyListener: {
+            int64_t srcId;
             int32_t msgId;
             int32_t ext1 = 0;
             int32_t ext2 = 0;
+            CHECK(msg->findInt64("srcId", &srcId));
             CHECK(msg->findInt32("messageId", &msgId));
             msg->findInt32("ext1", &ext1);
             msg->findInt32("ext2", &ext2);
@@ -922,7 +923,7 @@
             if (msg->findObject("parcel", &obj) && obj != NULL) {
                 in = static_cast<ParcelWrapper *>(obj.get());
             }
-            sendEvent(msgId, ext1, ext2, (in == NULL ? NULL : in->getParcel()));
+            sendEvent(srcId, msgId, ext1, ext2, (in == NULL ? NULL : in->getParcel()));
             break;
         }
         default:
@@ -931,15 +932,16 @@
 }
 
 void NuPlayer2Driver::notifyListener(
-        int msg, int ext1, int ext2, const Parcel *in) {
+        int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
     Mutex::Autolock autoLock(mLock);
-    notifyListener_l(msg, ext1, ext2, in);
+    notifyListener_l(srcId, msg, ext1, ext2, in);
 }
 
 void NuPlayer2Driver::notifyListener_l(
-        int msg, int ext1, int ext2, const Parcel *in) {
-    ALOGD("notifyListener_l(%p), (%d, %d, %d, %d), loop setting(%d, %d)",
-            this, msg, ext1, ext2, (in == NULL ? -1 : (int)in->dataSize()), mAutoLoop, mLooping);
+        int64_t srcId, int msg, int ext1, int ext2, const Parcel *in) {
+    ALOGD("notifyListener_l(%p), (%lld, %d, %d, %d, %d), loop setting(%d, %d)",
+            this, (long long)srcId, msg, ext1, ext2,
+            (in == NULL ? -1 : (int)in->dataSize()), mAutoLoop, mLooping);
     switch (msg) {
         case MEDIA2_PLAYBACK_COMPLETE:
         {
@@ -995,6 +997,7 @@
     }
 
     sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
+    notify->setInt64("srcId", srcId);
     notify->setInt32("messageId", msg);
     notify->setInt32("ext1", ext1);
     notify->setInt32("ext2", ext2);
@@ -1002,7 +1005,7 @@
     notify->post();
 }
 
-void NuPlayer2Driver::notifySetDataSourceCompleted(status_t err) {
+void NuPlayer2Driver::notifySetDataSourceCompleted(int64_t /* srcId */, status_t err) {
     Mutex::Autolock autoLock(mLock);
 
     CHECK_EQ(mState, STATE_SET_DATASOURCE_PENDING);
@@ -1012,7 +1015,7 @@
     mCondition.broadcast();
 }
 
-void NuPlayer2Driver::notifyPrepareCompleted(status_t err) {
+void NuPlayer2Driver::notifyPrepareCompleted(int64_t srcId, status_t err) {
     ALOGV("notifyPrepareCompleted %d", err);
 
     Mutex::Autolock autoLock(mLock);
@@ -1034,12 +1037,12 @@
         // in response, NuPlayer2Driver has the right state
         mState = STATE_PREPARED;
         if (mIsAsyncPrepare) {
-            notifyListener_l(MEDIA2_PREPARED);
+            notifyListener_l(srcId, MEDIA2_PREPARED);
         }
     } else {
         mState = STATE_UNPREPARED;
         if (mIsAsyncPrepare) {
-            notifyListener_l(MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+            notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
         }
     }
 
@@ -1053,7 +1056,7 @@
     mCondition.broadcast();
 }
 
-void NuPlayer2Driver::notifyFlagsChanged(uint32_t flags) {
+void NuPlayer2Driver::notifyFlagsChanged(int64_t /* srcId */, uint32_t flags) {
     Mutex::Autolock autoLock(mLock);
 
     mPlayerFlags = flags;
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
index 087d2c2..4c57cfd 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
@@ -67,18 +67,19 @@
 
     virtual void onMessageReceived(const sp<AMessage> &msg) override;
 
-    void notifySetDataSourceCompleted(status_t err);
-    void notifyPrepareCompleted(status_t err);
-    void notifyResetComplete();
-    void notifySetSurfaceComplete();
-    void notifyDuration(int64_t durationUs);
-    void notifyMorePlayingTimeUs(int64_t timeUs);
-    void notifyMoreRebufferingTimeUs(int64_t timeUs);
-    void notifyRebufferingWhenExit(bool status);
-    void notifySeekComplete();
-    void notifySeekComplete_l();
-    void notifyListener(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
-    void notifyFlagsChanged(uint32_t flags);
+    void notifySetDataSourceCompleted(int64_t srcId, status_t err);
+    void notifyPrepareCompleted(int64_t srcId, status_t err);
+    void notifyResetComplete(int64_t srcId);
+    void notifySetSurfaceComplete(int64_t srcId);
+    void notifyDuration(int64_t srcId, int64_t durationUs);
+    void notifyMorePlayingTimeUs(int64_t srcId, int64_t timeUs);
+    void notifyMoreRebufferingTimeUs(int64_t srcId, int64_t timeUs);
+    void notifyRebufferingWhenExit(int64_t srcId, bool status);
+    void notifySeekComplete(int64_t srcId);
+    void notifySeekComplete_l(int64_t srcId);
+    void notifyListener(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
+                        const Parcel *in = NULL);
+    void notifyFlagsChanged(int64_t srcId, uint32_t flags);
 
     // Modular DRM
     virtual status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
@@ -118,6 +119,7 @@
 
     // The following are protected through "mLock"
     // >>>
+    int64_t mSrcId;
     bool mSetSurfaceInProgress;
     int64_t mDurationUs;
     int64_t mPositionUs;
@@ -147,7 +149,8 @@
 
     status_t prepare_l();
     status_t start_l();
-    void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
+    void notifyListener_l(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
+                          const Parcel *in = NULL);
 
     DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2Driver);
 };