NuPlayer2: send notification on helper thread avoid deadlock.
Test: MediaPlayer2 works for local file playback
Bug: 63934228
Change-Id: Idb1f9d865f9060a3886f465147d7c1e45a669455
diff --git a/media/libmedia/nuplayer2/NuPlayer2Driver.cpp b/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
index c0f0bad..fb99347 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
@@ -41,7 +41,7 @@
namespace android {
// key for media statistics
-static const char *kKeyPlayer = "nuplayer";
+static const char *kKeyPlayer = "nuplayer2";
// attrs for media statistics
static const char *kPlayerVMime = "android.media.mediaplayer.video.mime";
static const char *kPlayerVCodec = "android.media.mediaplayer.video.codec";
@@ -75,6 +75,7 @@
mRebufferingEvents(0),
mRebufferingAtExit(false),
mLooper(new ALooper),
+ mNuPlayer2Looper(new ALooper),
mMediaClock(new MediaClock),
mPlayer(new NuPlayer2(pid, mMediaClock)),
mPlayerFlags(0),
@@ -85,6 +86,7 @@
mAutoLoop(false) {
ALOGD("NuPlayer2Driver(%p) created, clientPid(%d)", this, pid);
mLooper->setName("NuPlayer2Driver Looper");
+ mNuPlayer2Looper->setName("NuPlayer2 Looper");
mMediaClock->init();
@@ -92,18 +94,19 @@
mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
mAnalyticsItem->generateSessionID();
- mLooper->start(
+ mNuPlayer2Looper->start(
false, /* runOnCallingThread */
true, /* canCallJava */
PRIORITY_AUDIO);
- mLooper->registerHandler(mPlayer);
+ mNuPlayer2Looper->registerHandler(mPlayer);
mPlayer->setDriver(this);
}
NuPlayer2Driver::~NuPlayer2Driver() {
ALOGV("~NuPlayer2Driver(%p)", this);
+ mNuPlayer2Looper->stop();
mLooper->stop();
// finalize any pending metrics, usually a no-op.
@@ -117,6 +120,12 @@
}
status_t NuPlayer2Driver::initCheck() {
+ mLooper->start(
+ false, /* runOnCallingThread */
+ true, /* canCallJava */
+ PRIORITY_AUDIO);
+
+ mLooper->registerHandler(this);
return OK;
}
@@ -381,7 +390,7 @@
case STATE_PAUSED:
mState = STATE_STOPPED;
- notifyListener_l(MEDIA2_STOPPED);
+ sendNotifyOnLooper(MEDIA2_STOPPED);
break;
case STATE_PREPARED:
@@ -416,7 +425,7 @@
case STATE_RUNNING:
mState = STATE_PAUSED;
- notifyListener_l(MEDIA2_PAUSED);
+ sendNotifyOnLooper(MEDIA2_PAUSED);
mPlayer->pause();
break;
@@ -440,7 +449,7 @@
Mutex::Autolock autoLock(mLock);
if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
mState = STATE_PAUSED;
- notifyListener_l(MEDIA2_PAUSED);
+ sendNotifyOnLooper(MEDIA2_PAUSED);
} else if (rate.mSpeed != 0.f
&& (mState == STATE_PAUSED
|| mState == STATE_STOPPED_AND_PREPARED
@@ -478,7 +487,7 @@
mAtEOS = false;
mSeekInProgress = true;
// seeks can take a while, so we essentially paused
- notifyListener_l(MEDIA2_PAUSED);
+ sendNotifyOnLooper(MEDIA2_PAUSED);
mPlayer->seekToAsync(seekTimeUs, mode, true /* needNotify */);
break;
}
@@ -651,7 +660,7 @@
{
CHECK(mIsAsyncPrepare);
- notifyListener_l(MEDIA2_PREPARED);
+ sendNotifyOnLooper(MEDIA2_PREPARED);
break;
}
@@ -660,7 +669,7 @@
}
if (mState != STATE_STOPPED) {
- notifyListener_l(MEDIA2_STOPPED);
+ sendNotifyOnLooper(MEDIA2_STOPPED);
}
mState = STATE_RESET_IN_PROGRESS;
@@ -704,7 +713,7 @@
int32_t methodId;
status_t ret = request.readInt32(&methodId);
if (ret != OK) {
- ALOGE("Failed to retrieve the requested method to invoke");
+ ALOGE("Failed to retrieve the requested method to invoke, err(%d)", ret);
return ret;
}
@@ -939,6 +948,19 @@
return OK;
}
+void NuPlayer2Driver::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatNotifyListener: {
+ int32_t msgId;
+ CHECK(msg->findInt32("messageId", &msgId));
+ notifyListener(msgId);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
void NuPlayer2Driver::notifyListener(
int msg, int ext1, int ext2, const Parcel *in) {
Mutex::Autolock autoLock(mLock);
@@ -1007,6 +1029,12 @@
mLock.lock();
}
+void NuPlayer2Driver::sendNotifyOnLooper(int msgId) {
+ sp<AMessage> msg = new AMessage(kWhatNotifyListener, this);
+ msg->setInt32("messageId", msgId);
+ msg->post();
+}
+
void NuPlayer2Driver::notifySetDataSourceCompleted(status_t err) {
Mutex::Autolock autoLock(mLock);