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);
diff --git a/media/libmedia/nuplayer2/NuPlayer2Driver.h b/media/libmedia/nuplayer2/NuPlayer2Driver.h
index edd4556..051eba5 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Driver.h
+++ b/media/libmedia/nuplayer2/NuPlayer2Driver.h
@@ -78,6 +78,8 @@
virtual status_t dump(int fd, const Vector<String16> &args) const;
+ virtual void onMessageReceived(const sp<AMessage> &msg) override;
+
void notifySetDataSourceCompleted(status_t err);
void notifyPrepareCompleted(status_t err);
void notifyResetComplete();
@@ -113,6 +115,10 @@
STATE_STOPPED_AND_PREPARED, // equivalent to PAUSED, but seek complete
};
+ enum {
+ kWhatNotifyListener,
+ };
+
mutable Mutex mLock;
Condition mCondition;
@@ -134,6 +140,7 @@
// <<<
sp<ALooper> mLooper;
+ sp<ALooper> mNuPlayer2Looper;
const sp<MediaClock> mMediaClock;
const sp<NuPlayer2> mPlayer;
sp<AudioSink> mAudioSink;
@@ -146,13 +153,13 @@
bool mLooping;
bool mAutoLoop;
-
void updateMetrics(const char *where);
void logMetrics(const char *where);
status_t prepare_l();
status_t start_l();
void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
+ void sendNotifyOnLooper(int msgId);
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2Driver);
};