summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawin Vongmasa <pawin@google.com>2017-09-28 05:31:11 -0700
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-12-01 00:16:05 +0000
commit0f9dd0dedb62276f9505e824aad3cb849cdb08ba (patch)
tree44ebb3441dac7b6f2de3b3f2c4b8ded5cbcf2043
parente5daa585192b4d929d6f03c94287c6faa93d4b15 (diff)
downloadav-0f9dd0dedb62276f9505e824aad3cb849cdb08ba.tar.gz
RESTRICT AUTOMERGE Protect against possible race conditions
Test: make cts -j123 && cts-tradefed run cts-dev -m \ CtsMediaTestCases --compatibility:module-arg \ CtsMediaTestCases:include-annotation:\ android.platform.test.annotations.RequiresDevice Test: Run the poc in b/38234812 Bug: 38234812 Change-Id: I28322e5a812c02c8e449ab8773715f60b9f5d976 (cherry picked from commit 27a40ba369e04e7f4961ea1731ea45c27e9249e4)
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp83
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h4
2 files changed, 53 insertions, 34 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 98d0faccf1..04724e4027 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -650,7 +650,10 @@ void MediaPlayerService::Client::disconnect()
p->reset();
}
- disconnectNativeWindow();
+ {
+ Mutex::Autolock l(mLock);
+ disconnectNativeWindow_l();
+ }
IPCThreadState::self()->flushCommands();
}
@@ -709,15 +712,21 @@ sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.extractor"));
- mExtractorDeathListener = new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
- binder->linkToDeath(mExtractorDeathListener);
+ sp<ServiceDeathNotifier> extractorDeathListener =
+ new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
+ binder->linkToDeath(extractorDeathListener);
binder = sm->getService(String16("media.codec"));
- mCodecDeathListener = new ServiceDeathNotifier(binder, p, MEDIACODEC_PROCESS_DEATH);
- binder->linkToDeath(mCodecDeathListener);
+ sp<ServiceDeathNotifier> codecDeathListener =
+ new ServiceDeathNotifier(binder, p, MEDIACODEC_PROCESS_DEATH);
+ binder->linkToDeath(codecDeathListener);
+
+ Mutex::Autolock lock(mLock);
+
+ mExtractorDeathListener = extractorDeathListener;
+ mCodecDeathListener = codecDeathListener;
if (!p->hardwareOutput()) {
- Mutex::Autolock l(mLock);
mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
mPid, mAudioAttributes);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
@@ -726,29 +735,29 @@ sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
return p;
}
-void MediaPlayerService::Client::setDataSource_post(
+status_t MediaPlayerService::Client::setDataSource_post(
const sp<MediaPlayerBase>& p,
status_t status)
{
ALOGV(" setDataSource");
- mStatus = status;
- if (mStatus != OK) {
- ALOGE(" error: %d", mStatus);
- return;
+ if (status != OK) {
+ ALOGE(" error: %d", status);
+ return status;
}
// Set the re-transmission endpoint if one was chosen.
if (mRetransmitEndpointValid) {
- mStatus = p->setRetransmitEndpoint(&mRetransmitEndpoint);
- if (mStatus != NO_ERROR) {
- ALOGE("setRetransmitEndpoint error: %d", mStatus);
+ status = p->setRetransmitEndpoint(&mRetransmitEndpoint);
+ if (status != NO_ERROR) {
+ ALOGE("setRetransmitEndpoint error: %d", status);
}
}
- if (mStatus == OK) {
- Mutex::Autolock l(mLock);
+ if (status == OK) {
+ Mutex::Autolock lock(mLock);
mPlayer = p;
}
+ return status;
}
status_t MediaPlayerService::Client::setDataSource(
@@ -779,9 +788,9 @@ status_t MediaPlayerService::Client::setDataSource(
ALOGE("Couldn't open fd for %s", url);
return UNKNOWN_ERROR;
}
- setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
+ status_t status = setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
close(fd);
- return mStatus;
+ return mStatus = status;
} else {
player_type playerType = MediaPlayerFactory::getPlayerType(this, url);
sp<MediaPlayerBase> p = setDataSource_pre(playerType);
@@ -789,8 +798,9 @@ status_t MediaPlayerService::Client::setDataSource(
return NO_INIT;
}
- setDataSource_post(p, p->setDataSource(httpService, url, headers));
- return mStatus;
+ return mStatus =
+ setDataSource_post(
+ p, p->setDataSource(httpService, url, headers));
}
}
@@ -830,8 +840,7 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64
}
// now set data source
- setDataSource_post(p, p->setDataSource(fd, offset, length));
- return mStatus;
+ return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length));
}
status_t MediaPlayerService::Client::setDataSource(
@@ -844,8 +853,7 @@ status_t MediaPlayerService::Client::setDataSource(
}
// now set data source
- setDataSource_post(p, p->setDataSource(source));
- return mStatus;
+ return mStatus = setDataSource_post(p, p->setDataSource(source));
}
status_t MediaPlayerService::Client::setDataSource(
@@ -857,11 +865,10 @@ status_t MediaPlayerService::Client::setDataSource(
return NO_INIT;
}
// now set data source
- setDataSource_post(p, p->setDataSource(dataSource));
- return mStatus;
+ return mStatus = setDataSource_post(p, p->setDataSource(dataSource));
}
-void MediaPlayerService::Client::disconnectNativeWindow() {
+void MediaPlayerService::Client::disconnectNativeWindow_l() {
if (mConnectedWindow != NULL) {
status_t err = native_window_api_disconnect(mConnectedWindow.get(),
NATIVE_WINDOW_API_MEDIA);
@@ -899,7 +906,8 @@ status_t MediaPlayerService::Client::setVideoSurfaceTexture(
// ANW, which may result in errors.
reset();
- disconnectNativeWindow();
+ Mutex::Autolock lock(mLock);
+ disconnectNativeWindow_l();
return err;
}
@@ -910,14 +918,22 @@ status_t MediaPlayerService::Client::setVideoSurfaceTexture(
// on the disconnected ANW, which may result in errors.
status_t err = p->setVideoSurfaceTexture(bufferProducer);
- disconnectNativeWindow();
-
- mConnectedWindow = anw;
+ mLock.lock();
+ disconnectNativeWindow_l();
if (err == OK) {
+ mConnectedWindow = anw;
mConnectedWindowBinder = binder;
+ mLock.unlock();
} else {
- disconnectNativeWindow();
+ mLock.unlock();
+ status_t err = native_window_api_disconnect(
+ anw.get(), NATIVE_WINDOW_API_MEDIA);
+
+ if (err != OK) {
+ ALOGW("native_window_api_disconnect returned an error: %s (%d)",
+ strerror(-err), err);
+ }
}
return err;
@@ -1273,9 +1289,11 @@ status_t MediaPlayerService::Client::setRetransmitEndpoint(
if (p != 0) return INVALID_OPERATION;
if (NULL != endpoint) {
+ Mutex::Autolock lock(mLock);
mRetransmitEndpoint = *endpoint;
mRetransmitEndpointValid = true;
} else {
+ Mutex::Autolock lock(mLock);
mRetransmitEndpointValid = false;
}
@@ -1293,6 +1311,7 @@ status_t MediaPlayerService::Client::getRetransmitEndpoint(
if (p != NULL)
return p->getRetransmitEndpoint(endpoint);
+ Mutex::Autolock lock(mLock);
if (!mRetransmitEndpointValid)
return NO_INIT;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 19f12bc5c4..ca276455c6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -331,7 +331,7 @@ private:
sp<MediaPlayerBase> setDataSource_pre(player_type playerType);
- void setDataSource_post(const sp<MediaPlayerBase>& p,
+ status_t setDataSource_post(const sp<MediaPlayerBase>& p,
status_t status);
static void notify(void* cookie, int msg,
@@ -386,7 +386,7 @@ private:
void addNewMetadataUpdate(media::Metadata::Type type);
// Disconnect from the currently connected ANativeWindow.
- void disconnectNativeWindow();
+ void disconnectNativeWindow_l();
status_t setAudioAttributes_l(const Parcel &request);