diff options
author | Pawin Vongmasa <pawin@google.com> | 2017-09-28 05:31:11 -0700 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-12-01 00:16:05 +0000 |
commit | 0f9dd0dedb62276f9505e824aad3cb849cdb08ba (patch) | |
tree | 44ebb3441dac7b6f2de3b3f2c4b8ded5cbcf2043 | |
parent | e5daa585192b4d929d6f03c94287c6faa93d4b15 (diff) | |
download | av-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.cpp | 83 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 4 |
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); |