From 76d4c7ffa9cdeed39c93d685c9c03b0915262a8b Mon Sep 17 00:00:00 2001 From: Ronghua Wu Date: Fri, 23 Oct 2015 15:01:53 -0700 Subject: Reduce lock time for dump to make sure not locked when calling back to IResourceManagerClient. Bug: 25166048 Change-Id: I35f9917079c4b783a7cf4cef94b3c7112760c0b8 --- .../ResourceManagerService.cpp | 37 +++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'services') diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp index 4790754..6781a36 100644 --- a/services/mediaresourcemanager/ResourceManagerService.cpp +++ b/services/mediaresourcemanager/ResourceManagerService.cpp @@ -90,11 +90,7 @@ static ResourceInfo& getResourceInfoForEdit( } status_t ResourceManagerService::dump(int fd, const Vector& /* args */) { - Mutex::Autolock lock(mLock); - String8 result; - const size_t SIZE = 256; - char buffer[SIZE]; if (checkCallingPermission(String16("android.permission.DUMP")) == false) { result.format("Permission Denial: " @@ -105,20 +101,35 @@ status_t ResourceManagerService::dump(int fd, const Vector& /* args */ return PERMISSION_DENIED; } + PidResourceInfosMap mapCopy; + bool supportsMultipleSecureCodecs; + bool supportsSecureWithNonSecureCodec; + String8 serviceLog; + { + Mutex::Autolock lock(mLock); + mapCopy = mMap; // Shadow copy, real copy will happen on write. + supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs; + supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec; + serviceLog = mServiceLog->toString(" " /* linePrefix */); + } + + const size_t SIZE = 256; + char buffer[SIZE]; snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this); result.append(buffer); result.append(" Policies:\n"); - snprintf(buffer, SIZE, " SupportsMultipleSecureCodecs: %d\n", mSupportsMultipleSecureCodecs); + snprintf(buffer, SIZE, " SupportsMultipleSecureCodecs: %d\n", supportsMultipleSecureCodecs); result.append(buffer); - snprintf(buffer, SIZE, " SupportsSecureWithNonSecureCodec: %d\n", mSupportsSecureWithNonSecureCodec); + snprintf(buffer, SIZE, " SupportsSecureWithNonSecureCodec: %d\n", + supportsSecureWithNonSecureCodec); result.append(buffer); result.append(" Processes:\n"); - for (size_t i = 0; i < mMap.size(); ++i) { - snprintf(buffer, SIZE, " Pid: %d\n", mMap.keyAt(i)); + for (size_t i = 0; i < mapCopy.size(); ++i) { + snprintf(buffer, SIZE, " Pid: %d\n", mapCopy.keyAt(i)); result.append(buffer); - const ResourceInfos &infos = mMap.valueAt(i); + const ResourceInfos &infos = mapCopy.valueAt(i); for (size_t j = 0; j < infos.size(); ++j) { result.append(" Client:\n"); snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId); @@ -136,7 +147,7 @@ status_t ResourceManagerService::dump(int fd, const Vector& /* args */ } } result.append(" Events logs (most recent at top):\n"); - result.append(mServiceLog->toString(" " /* linePrefix */)); + result.append(serviceLog); write(fd, result.string(), result.size()); return OK; @@ -307,6 +318,10 @@ bool ResourceManagerService::reclaimResource( } } + if (failedClient == NULL) { + return true; + } + { Mutex::Autolock lock(mLock); bool found = false; @@ -329,7 +344,7 @@ bool ResourceManagerService::reclaimResource( } } - return (failedClient == NULL); + return false; } bool ResourceManagerService::getAllClients_l( -- cgit v1.1 From 75c82b50951b21190f710a638c6a26ff7ee6d86d Mon Sep 17 00:00:00 2001 From: Zach Jang Date: Tue, 27 Oct 2015 01:24:55 +0000 Subject: Revert "AudioPolicyService: fix race in AudioCommandThread" This reverts commit 74ce88ff0f24a8c08fdab3a1140212183089c2b5. Change-Id: I39114c8cdd3021951ba93716aaa0c1c03e68538d --- .../audiopolicy/service/AudioPolicyService.cpp | 24 ++++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'services') diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index c77cc45..eefff3d 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -577,28 +577,22 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() } } waitTime = INT64_MAX; - // release mLock before releasing strong reference on the service as - // AudioPolicyService destructor calls AudioCommandThread::exit() which - // acquires mLock. - mLock.unlock(); - svc.clear(); - mLock.lock(); } else { waitTime = mAudioCommands[0]->mTime - curTime; break; } } - - // release delayed commands wake lock if the queue is empty - if (mAudioCommands.isEmpty()) { + // release mLock before releasing strong reference on the service as + // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock. + mLock.unlock(); + svc.clear(); + mLock.lock(); + if (!exitPending() && (mAudioCommands.isEmpty() || waitTime != INT64_MAX)) { + // release delayed commands wake lock release_wake_lock(mName.string()); - } - - // At this stage we have either an empty command queue or the first command in the queue - // has a finite delay. So unless we are exiting it is safe to wait. - if (!exitPending()) { ALOGV("AudioCommandThread() going to sleep"); mWaitWorkCV.waitRelative(mLock, waitTime); + ALOGV("AudioCommandThread() waking up"); } } // release delayed commands wake lock before quitting @@ -1009,8 +1003,6 @@ void AudioPolicyService::AudioCommandThread::exit() requestExit(); mWaitWorkCV.signal(); } - // Note that we can call it from the thread loop if all other references have been released - // but it will safely return WOULD_BLOCK in this case requestExitAndWait(); } -- cgit v1.1 From 26ce11a1dd2a9b70865aec1b42c365dd19172511 Mon Sep 17 00:00:00 2001 From: Zach Jang Date: Tue, 27 Oct 2015 01:25:27 +0000 Subject: Revert "audio policy: bind setMode() and setPhoneState() operations" This reverts commit 9ddf1c76121caef55a05c537d6a9a1d76c1d17be. Change-Id: I860ecc288a1798605dff46f39107f4450ca5cd56 --- services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'services') diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index ca365a5..793c26a 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -76,14 +76,10 @@ status_t AudioPolicyService::setPhoneState(audio_mode_t state) ALOGV("setPhoneState()"); - // acquire lock before calling setMode() so that setMode() + setPhoneState() are an atomic - // operation from policy manager standpoint (no other operation (e.g track start or stop) - // can be interleaved). - Mutex::Autolock _l(mLock); - // TODO: check if it is more appropriate to do it in platform specific policy manager AudioSystem::setMode(state); + Mutex::Autolock _l(mLock); mAudioPolicyManager->setPhoneState(state); mPhoneState = state; return NO_ERROR; -- cgit v1.1 From a754b4fa874f97a51ed2bee9257f2a870effe619 Mon Sep 17 00:00:00 2001 From: Zach Jang Date: Tue, 27 Oct 2015 01:29:34 +0000 Subject: Revert "Revert "AudioPolicyService: fix race in AudioCommandThread"" This reverts commit 75c82b50951b21190f710a638c6a26ff7ee6d86d. Change-Id: I1b1f147bedf205636ec20b84faf6ef597a781c0d --- .../audiopolicy/service/AudioPolicyService.cpp | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'services') diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index eefff3d..c77cc45 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -577,22 +577,28 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() } } waitTime = INT64_MAX; + // release mLock before releasing strong reference on the service as + // AudioPolicyService destructor calls AudioCommandThread::exit() which + // acquires mLock. + mLock.unlock(); + svc.clear(); + mLock.lock(); } else { waitTime = mAudioCommands[0]->mTime - curTime; break; } } - // release mLock before releasing strong reference on the service as - // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock. - mLock.unlock(); - svc.clear(); - mLock.lock(); - if (!exitPending() && (mAudioCommands.isEmpty() || waitTime != INT64_MAX)) { - // release delayed commands wake lock + + // release delayed commands wake lock if the queue is empty + if (mAudioCommands.isEmpty()) { release_wake_lock(mName.string()); + } + + // At this stage we have either an empty command queue or the first command in the queue + // has a finite delay. So unless we are exiting it is safe to wait. + if (!exitPending()) { ALOGV("AudioCommandThread() going to sleep"); mWaitWorkCV.waitRelative(mLock, waitTime); - ALOGV("AudioCommandThread() waking up"); } } // release delayed commands wake lock before quitting @@ -1003,6 +1009,8 @@ void AudioPolicyService::AudioCommandThread::exit() requestExit(); mWaitWorkCV.signal(); } + // Note that we can call it from the thread loop if all other references have been released + // but it will safely return WOULD_BLOCK in this case requestExitAndWait(); } -- cgit v1.1 From 3994ffdd2c280aa5fad9f3c41255371cd545c7cf Mon Sep 17 00:00:00 2001 From: Zach Jang Date: Tue, 27 Oct 2015 01:29:45 +0000 Subject: Revert "Revert "audio policy: bind setMode() and setPhoneState() operations"" This reverts commit 26ce11a1dd2a9b70865aec1b42c365dd19172511. Change-Id: I0affb97e7f2eb541ebd6f26c33e8f32261e9e221 --- services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'services') diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 793c26a..ca365a5 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -76,10 +76,14 @@ status_t AudioPolicyService::setPhoneState(audio_mode_t state) ALOGV("setPhoneState()"); + // acquire lock before calling setMode() so that setMode() + setPhoneState() are an atomic + // operation from policy manager standpoint (no other operation (e.g track start or stop) + // can be interleaved). + Mutex::Autolock _l(mLock); + // TODO: check if it is more appropriate to do it in platform specific policy manager AudioSystem::setMode(state); - Mutex::Autolock _l(mLock); mAudioPolicyManager->setPhoneState(state); mPhoneState = state; return NO_ERROR; -- cgit v1.1 From 113efbb3ac8e7306ea8645cb53a96d1e81c2d041 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 8 Jan 2016 17:16:42 -0800 Subject: audioflinger: fix standby delay on A2DP output Make sure that standby delay is never less than the audio flinger default on A2DP output. Due to variable latency and amount of buffering in A2DP sinks, an agressive standby delay could lead to truncated audio. Bug: 25830539. Change-Id: I38be37ad346f5f4bf8303d3db4e3e911bf637968 (cherry picked from commit 42537be61479e59c4718e1304364551c1454f63c) --- services/audioflinger/Threads.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'services') diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 71fc498..7d2d550 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1589,6 +1589,7 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector& dprintf(fd, " Mixer buffer: %p\n", mMixerBuffer); dprintf(fd, " Effect buffer: %p\n", mEffectBuffer); dprintf(fd, " Fast track availMask=%#x\n", mFastTrackAvailMask); + dprintf(fd, " Standby delay ns=%lld\n", (long long)mStandbyDelayNs); AudioStreamOut *output = mOutput; audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE; String8 flagsAsString = outputFlagsToString(flags); @@ -2513,7 +2514,8 @@ The derived values that are cached: - mSinkBufferSize from frame count * frame size - mActiveSleepTimeUs from activeSleepTimeUs() - mIdleSleepTimeUs from idleSleepTimeUs() - - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) + - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) or forced to at least + kDefaultStandbyTimeInNsecs when connected to an A2DP device. - maxPeriod from frame count and sample rate (MIXER only) The parameters that affect these derived values are: @@ -2532,6 +2534,15 @@ void AudioFlinger::PlaybackThread::cacheParameters_l() mSinkBufferSize = mNormalFrameCount * mFrameSize; mActiveSleepTimeUs = activeSleepTimeUs(); mIdleSleepTimeUs = idleSleepTimeUs(); + + // make sure standby delay is not too short when connected to an A2DP sink to avoid + // truncating audio when going to standby. + mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs; + if ((mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) { + if (mStandbyDelayNs < kDefaultStandbyTimeInNsecs) { + mStandbyDelayNs = kDefaultStandbyTimeInNsecs; + } + } } void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) @@ -4248,6 +4259,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa status_t& status) { bool reconfig = false; + bool a2dpDeviceChanged = false; status = NO_ERROR; @@ -4324,6 +4336,8 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa // forward device change to effects that have requested to be // aware of attached audio device. if (value != AUDIO_DEVICE_NONE) { + a2dpDeviceChanged = + (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP); mOutDevice = value; for (size_t i = 0; i < mEffectChains.size(); i++) { mEffectChains[i]->setDevice_l(mOutDevice); @@ -4367,7 +4381,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); } - return reconfig; + return reconfig || a2dpDeviceChanged; } @@ -4803,6 +4817,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key status_t& status) { bool reconfig = false; + bool a2dpDeviceChanged = false; status = NO_ERROR; @@ -4812,6 +4827,8 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key // forward device change to effects that have requested to be // aware of attached audio device. if (value != AUDIO_DEVICE_NONE) { + a2dpDeviceChanged = + (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP); mOutDevice = value; for (size_t i = 0; i < mEffectChains.size(); i++) { mEffectChains[i]->setDevice_l(mOutDevice); @@ -4844,7 +4861,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key } } - return reconfig; + return reconfig || a2dpDeviceChanged; } uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const -- cgit v1.1 From 6dd6c546513aa18dc1d7fba0f72d670edce34f77 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Mon, 7 Dec 2015 12:20:11 -0800 Subject: Camera: set mNumberOfNormalCameras correctly Need to set the number correctly when a camera HAL is not present. Bug: 25951590 Change-Id: I666acf7a2a523c51f2c2ae88ff690ca9dccda08c --- services/camera/libcameraservice/CameraService.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'services') diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 3deb396..897fa1b 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -153,6 +153,7 @@ void CameraService::onFirstRef() ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err)); logServiceError("Could not load camera HAL module", err); mNumberOfCameras = 0; + mNumberOfNormalCameras = 0; return; } -- cgit v1.1 From c4003965258404a19b99280ac0f475e2f290bf27 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 13 Jan 2016 10:07:04 -0800 Subject: Camera: Disallow dumping clients directly Camera service dumps should only be initiated through ICameraService::dump. Bug: 26265403 Change-Id: If3ca4718ed74bf33ad8a416192689203029e2803 --- services/camera/libcameraservice/CameraService.cpp | 10 +++++++++- services/camera/libcameraservice/CameraService.h | 8 +++++++- services/camera/libcameraservice/api1/Camera2Client.cpp | 4 ++++ services/camera/libcameraservice/api1/Camera2Client.h | 2 ++ services/camera/libcameraservice/api1/CameraClient.cpp | 4 ++++ services/camera/libcameraservice/api1/CameraClient.h | 4 +++- services/camera/libcameraservice/api2/CameraDeviceClient.cpp | 5 ++++- services/camera/libcameraservice/api2/CameraDeviceClient.h | 2 ++ services/camera/libcameraservice/common/Camera2ClientBase.cpp | 2 +- services/camera/libcameraservice/common/Camera2ClientBase.h | 2 +- 10 files changed, 37 insertions(+), 6 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 9a1101a..8391f26 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -1896,6 +1896,14 @@ void CameraService::BasicClient::disconnect() { mClientPid = 0; } +status_t CameraService::BasicClient::dump(int, const Vector&) { + // No dumping of clients directly over Binder, + // must go through CameraService::dump + android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403", + IPCThreadState::self()->getCallingUid(), NULL, 0); + return OK; +} + String16 CameraService::BasicClient::getPackageName() const { return mClientPackageName; } @@ -2328,7 +2336,7 @@ status_t CameraService::dump(int fd, const Vector& args) { String8(client->getPackageName()).string()); write(fd, result.string(), result.size()); - client->dump(fd, args); + client->dumpClient(fd, args); } if (stateLocked) mCameraStatesLock.unlock(); diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index b56c161..3905d62 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -84,6 +84,9 @@ public: // Default number of messages to store in eviction log static const size_t DEFAULT_EVENT_LOG_LENGTH = 100; + // Event log ID + static const int SN_EVENT_LOG_ID = 0x534e4554; + // Implementation of BinderService static char const* getServiceName() { return "media.camera"; } @@ -189,7 +192,10 @@ public: return mRemoteBinder; } - virtual status_t dump(int fd, const Vector& args) = 0; + // Disallows dumping over binder interface + virtual status_t dump(int fd, const Vector& args); + // Internal dump method to be called by CameraService + virtual status_t dumpClient(int fd, const Vector& args) = 0; // Return the package name for this client virtual String16 getPackageName() const; diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index 36e99dd..1695309 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -163,6 +163,10 @@ Camera2Client::~Camera2Client() { } status_t Camera2Client::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); +} + +status_t Camera2Client::dumpClient(int fd, const Vector& args) { String8 result; result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n", mCameraId, (getRemoteCallback() != NULL ? diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h index d50bf63..7e7a284 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.h +++ b/services/camera/libcameraservice/api1/Camera2Client.h @@ -100,6 +100,8 @@ public: virtual status_t dump(int fd, const Vector& args); + virtual status_t dumpClient(int fd, const Vector& args); + /** * Interface used by CameraDeviceBase */ diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index e552633..9e6ed4e 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -108,6 +108,10 @@ CameraClient::~CameraClient() { } status_t CameraClient::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); +} + +status_t CameraClient::dumpClient(int fd, const Vector& args) { const size_t SIZE = 256; char buffer[SIZE]; diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h index 95616b2..17999a5 100644 --- a/services/camera/libcameraservice/api1/CameraClient.h +++ b/services/camera/libcameraservice/api1/CameraClient.h @@ -70,7 +70,9 @@ public: status_t initialize(CameraModule *module); - status_t dump(int fd, const Vector& args); + virtual status_t dump(int fd, const Vector& args); + + virtual status_t dumpClient(int fd, const Vector& args); private: diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index c717a56..84c0c3e 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -750,8 +750,11 @@ status_t CameraDeviceClient::tearDown(int streamId) { return res; } - status_t CameraDeviceClient::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); +} + +status_t CameraDeviceClient::dumpClient(int fd, const Vector& args) { String8 result; result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n", mCameraId, diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 1f8b39d..486e68b 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -132,6 +132,8 @@ public: virtual status_t dump(int fd, const Vector& args); + virtual status_t dumpClient(int fd, const Vector& args); + /** * Device listener interface */ diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index ba0b264..fdb801e 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -123,7 +123,7 @@ Camera2ClientBase::~Camera2ClientBase() { } template -status_t Camera2ClientBase::dump(int fd, +status_t Camera2ClientBase::dumpClient(int fd, const Vector& args) { String8 result; result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n", diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h index f1cacdf..d66e11c 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.h +++ b/services/camera/libcameraservice/common/Camera2ClientBase.h @@ -57,7 +57,7 @@ public: virtual ~Camera2ClientBase(); virtual status_t initialize(CameraModule *module); - virtual status_t dump(int fd, const Vector& args); + virtual status_t dumpClient(int fd, const Vector& args); /** * CameraDeviceBase::NotificationListener implementation -- cgit v1.1 From 38f1da3889188fb3beeaf7fdfeb92b4444c9fb4b Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 13 Jan 2016 10:07:04 -0800 Subject: Camera: Disallow dumping clients directly Camera service dumps should only be initiated through ICameraService::dump. Bug: 26265403 Change-Id: If3ca4718ed74bf33ad8a416192689203029e2803 --- services/camera/libcameraservice/CameraService.cpp | 10 +++++++++- services/camera/libcameraservice/CameraService.h | 8 +++++++- services/camera/libcameraservice/api1/Camera2Client.cpp | 4 ++++ services/camera/libcameraservice/api1/Camera2Client.h | 2 ++ services/camera/libcameraservice/api1/CameraClient.cpp | 4 ++++ services/camera/libcameraservice/api1/CameraClient.h | 4 +++- services/camera/libcameraservice/api2/CameraDeviceClient.cpp | 5 ++++- services/camera/libcameraservice/api2/CameraDeviceClient.h | 2 ++ services/camera/libcameraservice/common/Camera2ClientBase.cpp | 2 +- services/camera/libcameraservice/common/Camera2ClientBase.h | 2 +- 10 files changed, 37 insertions(+), 6 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 3deb396..7c4594f 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -1944,6 +1944,14 @@ void CameraService::BasicClient::disconnect() { mClientPid = 0; } +status_t CameraService::BasicClient::dump(int, const Vector&) { + // No dumping of clients directly over Binder, + // must go through CameraService::dump + android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403", + IPCThreadState::self()->getCallingUid(), NULL, 0); + return OK; +} + String16 CameraService::BasicClient::getPackageName() const { return mClientPackageName; } @@ -2396,7 +2404,7 @@ status_t CameraService::dump(int fd, const Vector& args) { String8(client->getPackageName()).string()); write(fd, result.string(), result.size()); - client->dump(fd, args); + client->dumpClient(fd, args); } if (stateLocked) mCameraStatesLock.unlock(); diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 4b0eeb7..d2c1bd3 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -87,6 +87,9 @@ public: // Default number of messages to store in eviction log static const size_t DEFAULT_EVENT_LOG_LENGTH = 100; + // Event log ID + static const int SN_EVENT_LOG_ID = 0x534e4554; + // Implementation of BinderService static char const* getServiceName() { return "media.camera"; } @@ -201,7 +204,10 @@ public: return mRemoteBinder; } - virtual status_t dump(int fd, const Vector& args) = 0; + // Disallows dumping over binder interface + virtual status_t dump(int fd, const Vector& args); + // Internal dump method to be called by CameraService + virtual status_t dumpClient(int fd, const Vector& args) = 0; // Return the package name for this client virtual String16 getPackageName() const; diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index 4338d64..fbd4034 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -163,6 +163,10 @@ Camera2Client::~Camera2Client() { } status_t Camera2Client::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); +} + +status_t Camera2Client::dumpClient(int fd, const Vector& args) { String8 result; result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n", mCameraId, (getRemoteCallback() != NULL ? diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h index d50bf63..7e7a284 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.h +++ b/services/camera/libcameraservice/api1/Camera2Client.h @@ -100,6 +100,8 @@ public: virtual status_t dump(int fd, const Vector& args); + virtual status_t dumpClient(int fd, const Vector& args); + /** * Interface used by CameraDeviceBase */ diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 30b462b..6020e35 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -108,6 +108,10 @@ CameraClient::~CameraClient() { } status_t CameraClient::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); +} + +status_t CameraClient::dumpClient(int fd, const Vector& args) { const size_t SIZE = 256; char buffer[SIZE]; diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h index 95616b2..17999a5 100644 --- a/services/camera/libcameraservice/api1/CameraClient.h +++ b/services/camera/libcameraservice/api1/CameraClient.h @@ -70,7 +70,9 @@ public: status_t initialize(CameraModule *module); - status_t dump(int fd, const Vector& args); + virtual status_t dump(int fd, const Vector& args); + + virtual status_t dumpClient(int fd, const Vector& args); private: diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 0c531c3..bd9fea3 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -787,8 +787,11 @@ status_t CameraDeviceClient::tearDown(int streamId) { return res; } - status_t CameraDeviceClient::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); +} + +status_t CameraDeviceClient::dumpClient(int fd, const Vector& args) { String8 result; result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n", mCameraId, diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index d1e692c..b1d1762 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -135,6 +135,8 @@ public: virtual status_t dump(int fd, const Vector& args); + virtual status_t dumpClient(int fd, const Vector& args); + /** * Device listener interface */ diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index 5732f80..c7de56a 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -124,7 +124,7 @@ Camera2ClientBase::~Camera2ClientBase() { } template -status_t Camera2ClientBase::dump(int fd, +status_t Camera2ClientBase::dumpClient(int fd, const Vector& args) { String8 result; result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n", diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h index 220c5ad..4568af0 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.h +++ b/services/camera/libcameraservice/common/Camera2ClientBase.h @@ -57,7 +57,7 @@ public: virtual ~Camera2ClientBase(); virtual status_t initialize(CameraModule *module); - virtual status_t dump(int fd, const Vector& args); + virtual status_t dumpClient(int fd, const Vector& args); /** * CameraDeviceBase::NotificationListener implementation -- cgit v1.1 From 0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Thu, 14 Jan 2016 02:46:40 -0800 Subject: audiopolicy: Add notification when default effects are updated * In M, we now have the ability to define a default set of audio effect on a per-stream basis. This allows us to get around the problem of apps not sending the control intents so we can implement smart global effects for specific media types. * We still need a session id in order to get a handle and configure them from an app like AudioFX, so we'll need to add some plumbing in order to send an event to interested applications. * This patch implements the native side of this. The Java layer will call down thru AudioSystem and register a callback which will be invoked by the audio policy when default effects are updated on a stream. This callback will receive both the stream type as well as the session id. * Attaching this listener requires that the caller hold the MODIFY_AUDIO_ROUTING permission. Change-Id: I142b15f2585ffca6a953c3e828e2a7c07b24f56c --- services/audiopolicy/AudioPolicyInterface.h | 3 + .../audiopolicy/service/AudioPolicyClientImpl.cpp | 6 ++ .../audiopolicy/service/AudioPolicyEffects.cpp | 7 +- services/audiopolicy/service/AudioPolicyEffects.h | 6 +- .../audiopolicy/service/AudioPolicyService.cpp | 82 +++++++++++++++++++++- services/audiopolicy/service/AudioPolicyService.h | 27 ++++++- 6 files changed, 125 insertions(+), 6 deletions(-) (limited to 'services') diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index c1e7bc0..a5edc14 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -331,6 +331,9 @@ public: virtual audio_unique_id_t newAudioUniqueId() = 0; virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; + + virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added) = 0; }; extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp index 489a9be..d71daa4 100644 --- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp @@ -219,6 +219,12 @@ void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate( mAudioPolicyService->onDynamicPolicyMixStateUpdate(regId, state); } +void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate( + audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) +{ + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId, added); +} + audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId() { return AudioSystem::newAudioUniqueId(); diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 26857b1..d72e255 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "AudioPolicyService.h" #include "AudioPolicyEffects.h" #include "ServiceUtilities.h" @@ -37,7 +38,8 @@ namespace android { // AudioPolicyEffects Implementation // ---------------------------------------------------------------------------- -AudioPolicyEffects::AudioPolicyEffects() +AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) : + mAudioPolicyService(audioPolicyService) { // load automatic audio effect modules if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE2, R_OK) == 0) { @@ -244,6 +246,8 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); + + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, true); } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -299,6 +303,7 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false); ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", audioSession); } diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 3845050..2023784 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -31,6 +31,8 @@ namespace android { +class AudioPolicyService; + // ---------------------------------------------------------------------------- // AudioPolicyEffects class @@ -44,7 +46,7 @@ public: // The constructor will parse audio_effects.conf // First it will look whether vendor specific file exists, // otherwise it will parse the system default file. - AudioPolicyEffects(); + AudioPolicyEffects(AudioPolicyService *audioPolicyService); virtual ~AudioPolicyEffects(); // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService @@ -192,6 +194,8 @@ private: KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams; // Automatic output effects are unique for audiosession ID KeyedVector< int32_t, EffectVector* > mOutputSessions; + + AudioPolicyService *mAudioPolicyService; }; }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index 12cca65..dbeed80 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -116,7 +116,7 @@ void AudioPolicyService::onFirstRef() #endif } // load audio processing modules - spaudioPolicyEffects = new AudioPolicyEffects(); + spaudioPolicyEffects = new AudioPolicyEffects(this); { Mutex::Autolock _l(mLock); mAudioPolicyEffects = audioPolicyEffects; @@ -177,6 +177,23 @@ void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); } +status_t AudioPolicyService::setEffectSessionCallbacksEnabled(bool enabled) +{ + Mutex::Autolock _l(mNotificationClientsLock); + + uid_t uid = IPCThreadState::self()->getCallingUid(); + if (mNotificationClients.indexOfKey(uid) < 0) { + return NO_INIT; + } + if (!modifyAudioRoutingAllowed()) { + ALOGE("setEffectSessionCallbacksEnabled requires MODIFY_AUDIO_ROUTING"); + return PERMISSION_DENIED; + } + mNotificationClients.valueFor(uid)->setEffectSessionCallbacksEnabled(enabled); + return OK; +} + + // removeNotificationClient() is called when the client process dies. void AudioPolicyService::removeNotificationClient(uid_t uid) { @@ -254,11 +271,31 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); } +void AudioPolicyService::onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, + bool added) +{ + ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)", + stream, sessionId, added); + mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, added); +} + +void AudioPolicyService::doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, + bool added) +{ + Mutex::Autolock _l(mNotificationClientsLock); + for (size_t i = 0; i < mNotificationClients.size(); i++) { + mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, added); + } +} + AudioPolicyService::NotificationClient::NotificationClient(const sp& service, const sp& client, uid_t uid) : mService(service), mUid(uid), mAudioPolicyServiceClient(client), - mAudioPortCallbacksEnabled(false) + mAudioPortCallbacksEnabled(false), + mEffectSessionCallbacksEnabled(false) { } @@ -289,6 +326,14 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() } } +void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate( + audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) +{ + if (mAudioPolicyServiceClient != 0 && mEffectSessionCallbacksEnabled) { + mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, added); + } +} + void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( String8 regId, int32_t state) { @@ -302,6 +347,10 @@ void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool e mAudioPortCallbacksEnabled = enabled; } +void AudioPolicyService::NotificationClient::setEffectSessionCallbacksEnabled(bool enabled) +{ + mEffectSessionCallbacksEnabled = enabled; +} void AudioPolicyService::binderDied(const wp& who) { ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), @@ -579,6 +628,20 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); mLock.lock(); } break; + case EFFECT_SESSION_UPDATE: { + EffectSessionUpdateData *data = + (EffectSessionUpdateData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing effect session update %d %d %d", + data->mStream, data->mSessionId, data->mAdded); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded); + mLock.lock(); + } break; + default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -851,6 +914,21 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( sendCommand(command); } +void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( + audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) +{ + sp command = new AudioCommand(); + command->mCommand = EFFECT_SESSION_UPDATE; + EffectSessionUpdateData *data = new EffectSessionUpdateData(); + data->mStream = stream; + data->mSessionId = sessionId; + data->mAdded = added; + command->mParam = data; + ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)", + stream, sessionId, added); + sendCommand(command); +} + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp& command, int delayMs) { { diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index d11294b..27a62f4 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -202,6 +202,8 @@ public: audio_io_handle_t *handle); virtual status_t stopAudioSource(audio_io_handle_t handle); + virtual status_t setEffectSessionCallbacksEnabled(bool enabled); + status_t doStartOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -229,6 +231,11 @@ public: void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); + void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); + private: AudioPolicyService() ANDROID_API; virtual ~AudioPolicyService(); @@ -260,7 +267,8 @@ private: UPDATE_AUDIOPORT_LIST, UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, - DYN_POLICY_MIX_STATE_UPDATE + DYN_POLICY_MIX_STATE_UPDATE, + EFFECT_SESSION_UPDATE }; AudioCommandThread (String8 name, const wp& service); @@ -303,6 +311,8 @@ private: int delayMs); void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state); void insertCommand_l(AudioCommand *command, int delayMs = 0); + void effectSessionUpdateCommand(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); private: class AudioCommandData; @@ -399,6 +409,13 @@ private: int32_t mState; }; + class EffectSessionUpdateData : public AudioCommandData { + public: + audio_stream_type_t mStream; + audio_unique_id_t mSessionId; + bool mAdded; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands @@ -508,6 +525,9 @@ private: virtual audio_unique_id_t newAudioUniqueId(); + virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); + private: AudioPolicyService *mAudioPolicyService; }; @@ -524,7 +544,9 @@ private: void onAudioPatchListUpdate(); void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void setAudioPortCallbacksEnabled(bool enabled); - + void setEffectSessionCallbacksEnabled(bool enabled); + void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); // IBinder::DeathRecipient virtual void binderDied(const wp& who); @@ -536,6 +558,7 @@ private: const uid_t mUid; const sp mAudioPolicyServiceClient; bool mAudioPortCallbacksEnabled; + bool mEffectSessionCallbacksEnabled; }; // Internal dump utilities. -- cgit v1.1 From 47f8c7303c9e2054f1492b02b6c7472385c52dc9 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 7 Mar 2016 03:43:14 -0800 Subject: audiopolicy: Defer release of output session effects * Some effects modules are racy and don't tolerate being destroyed and immediately resurrected on the same session. This is the common case when switching tracks, and the use of default output effects makes the problem even worse. Certain apps which handle gapless in a sloppy way are also to blame. * Instead of immediately nuking the entire descriptor with the stream, just decrease the refcount and defer it for 10 seconds. If it needs resurrected, the refcount will be increased and the delayed release command will not shoot it in the face. Change-Id: I068dd72c4180023a74eb9ccbe8a180f6f0683dbf --- .../audiopolicy/service/AudioPolicyEffects.cpp | 35 ++++++++++++++++++- services/audiopolicy/service/AudioPolicyEffects.h | 6 ++++ .../audiopolicy/service/AudioPolicyService.cpp | 39 ++++++++++++++++++++++ services/audiopolicy/service/AudioPolicyService.h | 18 +++++++++- 4 files changed, 96 insertions(+), 2 deletions(-) (limited to 'services') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index d72e255..f2d7f6f 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -295,16 +295,49 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu } EffectVector *procDesc = mOutputSessions.valueAt(index); + + // just in case it already has a death wish + if (procDesc->mRefCount == 0) { + return NO_ERROR; + } + procDesc->mRefCount--; ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", audioSession, procDesc->mRefCount); + + if (procDesc->mRefCount == 0) { + mAudioPolicyService->releaseOutputSessionEffectsDelayed( + output, stream, audioSession, 10000); + } + + return status; +} + +status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + int audioSession) +{ + status_t status = NO_ERROR; + (void) output; // argument not used for now + + Mutex::Autolock _l(mLock); + ssize_t index = mOutputSessions.indexOfKey(audioSession); + if (index < 0) { + ALOGV("doReleaseOutputSessionEffects: no output processing was attached to this stream"); + return NO_ERROR; + } + + EffectVector *procDesc = mOutputSessions.valueAt(index); + ALOGV("doReleaseOutputSessionEffects(): session: %d, refCount: %d", + audioSession, procDesc->mRefCount); + if (procDesc->mRefCount == 0) { procDesc->setProcessorEnabled(false); procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false); - ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", + ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", audioSession); } return status; diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 2023784..7988515 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -86,6 +86,12 @@ public: audio_stream_type_t stream, int audioSession); + // For deferred release + status_t doReleaseOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + int audioSession); + + private: // class to store the description of an effects and its parameters diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index dbeed80..58cfe37 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -357,6 +357,13 @@ void AudioPolicyService::binderDied(const wp& who) { IPCThreadState::self()->getCallingPid()); } +void AudioPolicyService::releaseOutputSessionEffectsDelayed( + audio_io_handle_t output, audio_stream_type_t stream, + audio_unique_id_t sessionId, int delayMs) +{ + mAudioCommandThread->releaseOutputSessionEffectsCommand(output, stream, sessionId, delayMs); +} + static bool tryLock(Mutex& mutex) { bool locked = false; @@ -641,6 +648,21 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded); mLock.lock(); } break; + case RELEASE_OUTPUT_SESSION_EFFECTS: { + ReleaseOutputSessionEffectsData *data = + (ReleaseOutputSessionEffectsData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing release output session effects %d %d %d", + data->mOutput, data->mStream, data->mSessionId); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->mAudioPolicyEffects->doReleaseOutputSessionEffects( + data->mOutput, data->mStream, data->mSessionId); + mLock.lock(); + } break; + default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); @@ -929,6 +951,23 @@ void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( sendCommand(command); } +void AudioPolicyService::AudioCommandThread::releaseOutputSessionEffectsCommand( + audio_io_handle_t output, audio_stream_type_t stream, + audio_unique_id_t sessionId, int delayMs) +{ + sp command = new AudioCommand(); + command->mCommand = RELEASE_OUTPUT_SESSION_EFFECTS; + ReleaseOutputSessionEffectsData *data = new ReleaseOutputSessionEffectsData(); + data->mOutput = output; + data->mStream = stream; + data->mSessionId = sessionId; + command->mParam = data; + ALOGV("AudioCommandThread() sending release output session effects (id=%d) for stream %d", + sessionId, stream); + sendCommand(command, delayMs); +} + + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp& command, int delayMs) { { diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 27a62f4..9b17a26 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -235,6 +235,10 @@ public: audio_unique_id_t sessionId, bool added); void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, audio_unique_id_t sessionId, bool added); + void releaseOutputSessionEffectsDelayed(audio_io_handle_t output, + audio_stream_type_t stream, + audio_unique_id_t sessionId, + int delayMs); private: AudioPolicyService() ANDROID_API; @@ -268,7 +272,8 @@ private: UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, DYN_POLICY_MIX_STATE_UPDATE, - EFFECT_SESSION_UPDATE + EFFECT_SESSION_UPDATE, + RELEASE_OUTPUT_SESSION_EFFECTS, }; AudioCommandThread (String8 name, const wp& service); @@ -313,6 +318,10 @@ private: void insertCommand_l(AudioCommand *command, int delayMs = 0); void effectSessionUpdateCommand(audio_stream_type_t stream, audio_unique_id_t sessionId, bool added); + void releaseOutputSessionEffectsCommand(audio_io_handle_t output, + audio_stream_type_t stream, + audio_unique_id_t sessionId, + int delayMs = 0); private: class AudioCommandData; @@ -416,6 +425,13 @@ private: bool mAdded; }; + class ReleaseOutputSessionEffectsData : public AudioCommandData { + public: + audio_io_handle_t mOutput; + audio_stream_type_t mStream; + audio_unique_id_t mSessionId; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands -- cgit v1.1 From ba3877845ec7b34fd13393aeed7ad74dcb727a4c Mon Sep 17 00:00:00 2001 From: c457 Date: Tue, 5 Jan 2016 21:06:56 -0600 Subject: audiopolicy: squashed support for pre-kitkat audio blobs Squash of the following: commit 40c41a743a4345ad26b6eab41755c5b474f75853 Author: chrmhoffmann Date: Sat Nov 29 19:32:27 2014 +0100 pre kitkat audio legacy policy fix for hotword (ok google) Change-Id: I5bb90fb90f373461a98609226a5cea50ac5266e9 commit d47b306954b96142323c79b976edeb3eaa3b46dd Author: chrmhoffmann Date: Sun Nov 23 18:22:35 2014 +0100 commit d47b306954b96142323c79b976edeb3eaa3b46dd Author: chrmhoffmann Date: Sun Nov 23 18:22:35 2014 +0100 pre-kitkat audio policy blobs re-activated. Change-Id: Idfcb03d0a4aa0a099bf5a17b7bf592ab402e3255 Change-Id: Iae65c6ccb6dcb120a6fc20978b8a69e6af39a51a --- services/audiopolicy/Android.mk | 4 ++++ services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp | 5 +++++ services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp | 9 +++++++++ 3 files changed, 18 insertions(+) (limited to 'services') diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk index 5b38e1c..69fc0e8 100644 --- a/services/audiopolicy/Android.mk +++ b/services/audiopolicy/Android.mk @@ -40,6 +40,10 @@ LOCAL_SHARED_LIBRARIES += \ libaudiopolicymanager endif +ifeq ($(BOARD_HAVE_PRE_KITKAT_AUDIO_POLICY_BLOB),true) + LOCAL_CFLAGS += -DHAVE_PRE_KITKAT_AUDIO_POLICY_BLOB +endif + LOCAL_STATIC_LIBRARIES := \ libmedia_helper \ libaudiopolicycomponents diff --git a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp index a79f8ae..36c85f1 100644 --- a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp @@ -125,8 +125,13 @@ audio_io_handle_t aps_open_output_on_module(void *service __unused, audio_output_flags_t flags, const audio_offload_info_t *offloadInfo) { +#ifdef HAVE_PRE_KITKAT_AUDIO_POLICY_BLOB + return open_output(module, pDevices, pSamplingRate, pFormat, pChannelMask, + pLatencyMs, flags, NULL); +#else return open_output(module, pDevices, pSamplingRate, pFormat, pChannelMask, pLatencyMs, flags, offloadInfo); +#endif } audio_io_handle_t aps_open_dup_output(void *service __unused, diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index f76b5c8..318c6d2 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -275,6 +275,11 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, return BAD_VALUE; } +#ifdef HAVE_PRE_KITKAT_AUDIO_POLICY_BLOB + if (inputSource == AUDIO_SOURCE_HOTWORD) + inputSource = AUDIO_SOURCE_VOICE_RECOGNITION; +#endif + spaudioPolicyEffects; { Mutex::Autolock _l(mLock); @@ -524,6 +529,9 @@ status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession, bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info) { +#ifdef HAVE_PRE_KITKAT_AUDIO_POLICY_BLOB + return false; +#else if (mpAudioPolicy == NULL) { ALOGV("mpAudioPolicy == NULL"); return false; @@ -535,6 +543,7 @@ bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info) } return mpAudioPolicy->is_offload_supported(mpAudioPolicy, &info); +#endif } status_t AudioPolicyService::listAudioPorts(audio_port_role_t role __unused, -- cgit v1.1 From 8c2e9d8867ccaba1a617f133b37103e2ac77e871 Mon Sep 17 00:00:00 2001 From: Arne Coucheron Date: Thu, 17 Mar 2016 00:25:51 +0100 Subject: audio: Remove LEGACY_ALSA_AUDIO ifdefs from AudioPolicyManager.cpp This is moved to custom policy manager in HAL sources. Change-Id: I716580f7d3399f1628c26bd3b79bd6c6a52fbbf6 --- .../managerdefault/AudioPolicyManager.cpp | 54 ---------------------- 1 file changed, 54 deletions(-) (limited to 'services') diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index 50b5087..13499ae 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -88,20 +88,6 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, } ALOGV("setDeviceConnectionState() connecting device %x", device); -#ifdef LEGACY_ALSA_AUDIO - if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { - AudioParameter param; - param.add(String8("a2dp_connected"), String8("true")); - mpClientInterface->setParameters(0, param.toString()); - } - - if (device & AUDIO_DEVICE_OUT_USB_ACCESSORY) { - AudioParameter param; - param.add(String8("usb_connected"), String8("true")); - mpClientInterface->setParameters(0, param.toString()); - } -#endif - // register new device as available index = mAvailableOutputDevices.add(devDesc); if (index >= 0) { @@ -153,20 +139,6 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, // remove device from available output devices mAvailableOutputDevices.remove(devDesc); -#ifdef LEGACY_ALSA_AUDIO - if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { - AudioParameter param; - param.add(String8("a2dp_connected"), String8("false")); - mpClientInterface->setParameters(0, param.toString()); - } - - if (device & AUDIO_DEVICE_OUT_USB_ACCESSORY) { - AudioParameter param; - param.add(String8("usb_connected"), String8("true")); - mpClientInterface->setParameters(0, param.toString()); - } -#endif - checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress); // Propagate device availability to Engine @@ -333,11 +305,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs if(!hasPrimaryOutput()) { return; } -#ifdef LEGACY_ALSA_AUDIO - audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_CALL); -#else audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); -#endif ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice); // release existing RX patch if any @@ -1423,22 +1391,6 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, } else { *inputType = API_INPUT_LEGACY; } -#ifdef LEGACY_ALSA_AUDIO - // adapt channel selection to input source - switch (inputSource) { - case AUDIO_SOURCE_VOICE_UPLINK: - channelMask |= AUDIO_CHANNEL_IN_VOICE_UPLINK; - break; - case AUDIO_SOURCE_VOICE_DOWNLINK: - channelMask |= AUDIO_CHANNEL_IN_VOICE_DNLINK; - break; - case AUDIO_SOURCE_VOICE_CALL: - channelMask |= AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; - break; - default: - break; - } -#endif if (inputSource == AUDIO_SOURCE_HOTWORD) { ssize_t index = mSoundTriggerSessions.indexOfKey(session); if (index >= 0) { @@ -3947,13 +3899,11 @@ void AudioPolicyManager::checkOutputForAllStrategies() void AudioPolicyManager::checkA2dpSuspend() { -#ifndef LEGACY_ALSA_AUDIO audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput(); if (a2dpOutput == 0) { mA2dpSuspended = false; return; } -#endif bool isScoConnected = ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET & @@ -3978,9 +3928,7 @@ void AudioPolicyManager::checkA2dpSuspend() ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) && (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) { -#ifndef LEGACY_ALSA_AUDIO mpClientInterface->restoreOutput(a2dpOutput); -#endif mA2dpSuspended = false; } } else { @@ -3990,9 +3938,7 @@ void AudioPolicyManager::checkA2dpSuspend() ((mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) || (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) { -#ifndef LEGACY_ALSA_AUDIO mpClientInterface->suspendOutput(a2dpOutput); -#endif mA2dpSuspended = true; } } -- cgit v1.1