blob: 15aced0835d639c23864ff0da3da5da2f511e3c7 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AudioPolicyService"
18//#define LOG_NDEBUG 0
19
Glenn Kasten153b9fe2013-07-15 11:23:36 -070020#include "Configuration.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070021#undef __STRICT_ANSI__
22#define __STDINT_LIMITS
23#define __STDC_LIMIT_MACROS
24#include <stdint.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070025#include <sys/time.h>
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053026#include <dlfcn.h>
Mikhail Naganov959e2d02019-03-28 11:08:19 -070027
Atneya Nairdc4f3752023-08-09 16:21:48 -070028#include <android/content/pm/IPackageManagerNative.h>
Mikhail Naganov959e2d02019-03-28 11:08:19 -070029#include <audio_utils/clock.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070030#include <binder/IServiceManager.h>
31#include <utils/Log.h>
32#include <cutils/properties.h>
33#include <binder/IPCThreadState.h>
Svet Ganovf4ddfef2018-01-16 07:37:58 -080034#include <binder/PermissionController.h>
35#include <binder/IResultReceiver.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <utils/String16.h>
37#include <utils/threads.h>
38#include "AudioPolicyService.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070039#include <hardware_legacy/power.h>
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -080040#include <media/AidlConversion.h>
Eric Laurent7c7f10b2011-06-17 21:29:58 -070041#include <media/AudioEffect.h>
Chih-Hung Hsiehc84d9d22014-11-14 13:33:34 -080042#include <media/AudioParameter.h>
Andy Hungc747c532022-03-07 21:41:14 -080043#include <mediautils/MethodStatistics.h>
Andy Hungab7ef302018-05-15 19:35:29 -070044#include <mediautils/ServiceUtilities.h>
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -080045#include <mediautils/TimeCheck.h>
Michael Groovercfd28302018-12-11 19:16:46 -080046#include <sensorprivacy/SensorPrivacyManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070047
Dima Zavin64760242011-05-11 14:15:23 -070048#include <system/audio.h>
Dima Zavin7394a4f2011-06-13 18:16:26 -070049#include <system/audio_policy.h>
Mikhail Naganov68e3f642023-04-28 13:06:32 -070050#include <AudioPolicyConfig.h>
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053051#include <AudioPolicyManager.h>
Mikhail Naganov61a4fac2016-10-13 14:44:18 -070052
Mathias Agopian65ab4712010-07-14 17:59:35 -070053namespace android {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -080054using binder::Status;
Mathias Agopian65ab4712010-07-14 17:59:35 -070055
Glenn Kasten8dad0e32012-01-09 08:41:22 -080056static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
57static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053058static const char kAudioPolicyManagerCustomPath[] = "libaudiopolicymanagercustom.so";
Mathias Agopian65ab4712010-07-14 17:59:35 -070059
Mikhail Naganov959e2d02019-03-28 11:08:19 -070060static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Mathias Agopian65ab4712010-07-14 17:59:35 -070061
Eric Laurent0ede8922014-05-09 18:04:42 -070062static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
Christer Fletcher5fa8c4b2013-01-18 15:27:03 +010063
Svet Ganovf4ddfef2018-01-16 07:37:58 -080064static const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY");
Dima Zavinfce7a472011-04-19 22:30:36 -070065
Andy Hungc747c532022-03-07 21:41:14 -080066// Creates an association between Binder code to name for IAudioPolicyService.
67#define IAUDIOPOLICYSERVICE_BINDER_METHOD_MACRO_LIST \
68BINDER_METHOD_ENTRY(onNewAudioModulesAvailable) \
69BINDER_METHOD_ENTRY(setDeviceConnectionState) \
70BINDER_METHOD_ENTRY(getDeviceConnectionState) \
71BINDER_METHOD_ENTRY(handleDeviceConfigChange) \
72BINDER_METHOD_ENTRY(setPhoneState) \
73BINDER_METHOD_ENTRY(setForceUse) \
74BINDER_METHOD_ENTRY(getForceUse) \
75BINDER_METHOD_ENTRY(getOutput) \
76BINDER_METHOD_ENTRY(getOutputForAttr) \
77BINDER_METHOD_ENTRY(startOutput) \
78BINDER_METHOD_ENTRY(stopOutput) \
79BINDER_METHOD_ENTRY(releaseOutput) \
80BINDER_METHOD_ENTRY(getInputForAttr) \
81BINDER_METHOD_ENTRY(startInput) \
82BINDER_METHOD_ENTRY(stopInput) \
83BINDER_METHOD_ENTRY(releaseInput) \
84BINDER_METHOD_ENTRY(initStreamVolume) \
85BINDER_METHOD_ENTRY(setStreamVolumeIndex) \
86BINDER_METHOD_ENTRY(getStreamVolumeIndex) \
87BINDER_METHOD_ENTRY(setVolumeIndexForAttributes) \
88BINDER_METHOD_ENTRY(getVolumeIndexForAttributes) \
89BINDER_METHOD_ENTRY(getMaxVolumeIndexForAttributes) \
90BINDER_METHOD_ENTRY(getMinVolumeIndexForAttributes) \
91BINDER_METHOD_ENTRY(getStrategyForStream) \
92BINDER_METHOD_ENTRY(getDevicesForAttributes) \
93BINDER_METHOD_ENTRY(getOutputForEffect) \
94BINDER_METHOD_ENTRY(registerEffect) \
95BINDER_METHOD_ENTRY(unregisterEffect) \
96BINDER_METHOD_ENTRY(setEffectEnabled) \
97BINDER_METHOD_ENTRY(moveEffectsToIo) \
98BINDER_METHOD_ENTRY(isStreamActive) \
99BINDER_METHOD_ENTRY(isStreamActiveRemotely) \
100BINDER_METHOD_ENTRY(isSourceActive) \
101BINDER_METHOD_ENTRY(queryDefaultPreProcessing) \
102BINDER_METHOD_ENTRY(addSourceDefaultEffect) \
103BINDER_METHOD_ENTRY(addStreamDefaultEffect) \
104BINDER_METHOD_ENTRY(removeSourceDefaultEffect) \
105BINDER_METHOD_ENTRY(removeStreamDefaultEffect) \
106BINDER_METHOD_ENTRY(setSupportedSystemUsages) \
107BINDER_METHOD_ENTRY(setAllowedCapturePolicy) \
108BINDER_METHOD_ENTRY(getOffloadSupport) \
109BINDER_METHOD_ENTRY(isDirectOutputSupported) \
110BINDER_METHOD_ENTRY(listAudioPorts) \
111BINDER_METHOD_ENTRY(getAudioPort) \
112BINDER_METHOD_ENTRY(createAudioPatch) \
113BINDER_METHOD_ENTRY(releaseAudioPatch) \
114BINDER_METHOD_ENTRY(listAudioPatches) \
115BINDER_METHOD_ENTRY(setAudioPortConfig) \
116BINDER_METHOD_ENTRY(registerClient) \
117BINDER_METHOD_ENTRY(setAudioPortCallbacksEnabled) \
118BINDER_METHOD_ENTRY(setAudioVolumeGroupCallbacksEnabled) \
119BINDER_METHOD_ENTRY(acquireSoundTriggerSession) \
120BINDER_METHOD_ENTRY(releaseSoundTriggerSession) \
121BINDER_METHOD_ENTRY(getPhoneState) \
122BINDER_METHOD_ENTRY(registerPolicyMixes) \
123BINDER_METHOD_ENTRY(setUidDeviceAffinities) \
124BINDER_METHOD_ENTRY(removeUidDeviceAffinities) \
125BINDER_METHOD_ENTRY(setUserIdDeviceAffinities) \
126BINDER_METHOD_ENTRY(removeUserIdDeviceAffinities) \
127BINDER_METHOD_ENTRY(startAudioSource) \
128BINDER_METHOD_ENTRY(stopAudioSource) \
129BINDER_METHOD_ENTRY(setMasterMono) \
130BINDER_METHOD_ENTRY(getMasterMono) \
131BINDER_METHOD_ENTRY(getStreamVolumeDB) \
132BINDER_METHOD_ENTRY(getSurroundFormats) \
133BINDER_METHOD_ENTRY(getReportedSurroundFormats) \
134BINDER_METHOD_ENTRY(getHwOffloadFormatsSupportedForBluetoothMedia) \
135BINDER_METHOD_ENTRY(setSurroundFormatEnabled) \
136BINDER_METHOD_ENTRY(setAssistantServicesUids) \
137BINDER_METHOD_ENTRY(setActiveAssistantServicesUids) \
138BINDER_METHOD_ENTRY(setA11yServicesUids) \
139BINDER_METHOD_ENTRY(setCurrentImeUid) \
140BINDER_METHOD_ENTRY(isHapticPlaybackSupported) \
141BINDER_METHOD_ENTRY(isUltrasoundSupported) \
Atneya Nair698f5ef2022-12-15 16:15:09 -0800142BINDER_METHOD_ENTRY(isHotwordStreamSupported) \
Andy Hungc747c532022-03-07 21:41:14 -0800143BINDER_METHOD_ENTRY(listAudioProductStrategies) \
144BINDER_METHOD_ENTRY(getProductStrategyFromAudioAttributes) \
145BINDER_METHOD_ENTRY(listAudioVolumeGroups) \
146BINDER_METHOD_ENTRY(getVolumeGroupFromAudioAttributes) \
147BINDER_METHOD_ENTRY(setRttEnabled) \
148BINDER_METHOD_ENTRY(isCallScreenModeSupported) \
149BINDER_METHOD_ENTRY(setDevicesRoleForStrategy) \
150BINDER_METHOD_ENTRY(removeDevicesRoleForStrategy) \
Paul Wang5d7cdb52022-11-22 09:45:06 +0000151BINDER_METHOD_ENTRY(clearDevicesRoleForStrategy) \
Andy Hungc747c532022-03-07 21:41:14 -0800152BINDER_METHOD_ENTRY(getDevicesForRoleAndStrategy) \
153BINDER_METHOD_ENTRY(setDevicesRoleForCapturePreset) \
154BINDER_METHOD_ENTRY(addDevicesRoleForCapturePreset) \
155BINDER_METHOD_ENTRY(removeDevicesRoleForCapturePreset) \
156BINDER_METHOD_ENTRY(clearDevicesRoleForCapturePreset) \
157BINDER_METHOD_ENTRY(getDevicesForRoleAndCapturePreset) \
158BINDER_METHOD_ENTRY(registerSoundTriggerCaptureStateListener) \
159BINDER_METHOD_ENTRY(getSpatializer) \
160BINDER_METHOD_ENTRY(canBeSpatialized) \
161BINDER_METHOD_ENTRY(getDirectPlaybackSupport) \
jiabina84c3d32022-12-02 18:59:55 +0000162BINDER_METHOD_ENTRY(getDirectProfilesForAttributes) \
163BINDER_METHOD_ENTRY(getSupportedMixerAttributes) \
164BINDER_METHOD_ENTRY(setPreferredMixerAttributes) \
165BINDER_METHOD_ENTRY(getPreferredMixerAttributes) \
166BINDER_METHOD_ENTRY(clearPreferredMixerAttributes) \
Andy Hungc747c532022-03-07 21:41:14 -0800167
168// singleton for Binder Method Statistics for IAudioPolicyService
169static auto& getIAudioPolicyServiceStatistics() {
170 using Code = int;
171
172#pragma push_macro("BINDER_METHOD_ENTRY")
173#undef BINDER_METHOD_ENTRY
174#define BINDER_METHOD_ENTRY(ENTRY) \
175 {(Code)media::BnAudioPolicyService::TRANSACTION_##ENTRY, #ENTRY},
176
177 static mediautils::MethodStatistics<Code> methodStatistics{
178 IAUDIOPOLICYSERVICE_BINDER_METHOD_MACRO_LIST
179 METHOD_STATISTICS_BINDER_CODE_NAMES(Code)
180 };
181#pragma pop_macro("BINDER_METHOD_ENTRY")
182
183 return methodStatistics;
184}
185
Mathias Agopian65ab4712010-07-14 17:59:35 -0700186// ----------------------------------------------------------------------------
187
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530188static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
189{
Mikhail Naganov741c3472023-05-05 17:36:39 -0700190 AudioPolicyManager *apm = nullptr;
191 media::AudioPolicyConfig apmConfig;
192 if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
193 auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
194 LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix() !=
195 AudioPolicyConfig::kDefaultEngineLibraryNameSuffix,
196 "Only default engine is currently supported with the AIDL HAL");
197 apm = new AudioPolicyManager(config,
198 loadApmEngineLibraryAndCreateEngine(
199 config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
200 clientInterface);
201 } else {
202 auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This can't fail.
203 apm = new AudioPolicyManager(config,
204 loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
205 clientInterface);
206 }
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530207 status_t status = apm->initialize();
208 if (status != NO_ERROR) {
209 delete apm;
210 apm = nullptr;
211 }
212 return apm;
213}
214
215static void destroyAudioPolicyManager(AudioPolicyInterface *interface)
216{
217 delete interface;
218}
Atneya Nairdc4f3752023-08-09 16:21:48 -0700219
220namespace {
221int getTargetSdkForPackageName(std::string_view packageName) {
222 const auto binder = defaultServiceManager()->checkService(String16{"package_native"});
223 int targetSdk = -1;
224 if (binder != nullptr) {
225 const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
226 if (pm != nullptr) {
227 const auto status = pm->getTargetSdkVersionForPackage(
228 String16{packageName.data(), packageName.size()}, &targetSdk);
229 ALOGI("Capy check package %s, sdk %d", packageName.data(), targetSdk);
230 return status.isOk() ? targetSdk : -1;
231 }
232 }
233 return targetSdk;
234}
235
236bool doesPackageTargetAtLeastU(std::string_view packageName) {
237 return getTargetSdkForPackageName(packageName) >= __ANDROID_API_U__;
238}
239} // anonymous
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530240// ----------------------------------------------------------------------------
241
Mathias Agopian65ab4712010-07-14 17:59:35 -0700242AudioPolicyService::AudioPolicyService()
Ytai Ben-Tsvi85093d52020-03-26 09:41:15 -0700243 : BnAudioPolicyService(),
Ytai Ben-Tsvi85093d52020-03-26 09:41:15 -0700244 mAudioPolicyManager(NULL),
245 mAudioPolicyClient(NULL),
246 mPhoneState(AUDIO_MODE_INVALID),
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530247 mCaptureStateNotifier(false),
248 mCreateAudioPolicyManager(createAudioPolicyManager),
Eric Laurent0d13fea2022-11-04 17:12:08 +0100249 mDestroyAudioPolicyManager(destroyAudioPolicyManager),
250 mUsecaseValidator(media::createUsecaseValidator()) {
Andy Hung225aef62022-12-06 16:33:20 -0800251 setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530252}
253
254void AudioPolicyService::loadAudioPolicyManager()
255{
256 mLibraryHandle = dlopen(kAudioPolicyManagerCustomPath, RTLD_NOW);
257 if (mLibraryHandle != nullptr) {
258 ALOGI("%s loading %s", __func__, kAudioPolicyManagerCustomPath);
259 mCreateAudioPolicyManager = reinterpret_cast<CreateAudioPolicyManagerInstance>
260 (dlsym(mLibraryHandle, "createAudioPolicyManager"));
261 const char *lastError = dlerror();
262 ALOGW_IF(mCreateAudioPolicyManager == nullptr, "%s createAudioPolicyManager is null %s",
263 __func__, lastError != nullptr ? lastError : "no error");
264
265 mDestroyAudioPolicyManager = reinterpret_cast<DestroyAudioPolicyManagerInstance>(
266 dlsym(mLibraryHandle, "destroyAudioPolicyManager"));
267 lastError = dlerror();
268 ALOGW_IF(mDestroyAudioPolicyManager == nullptr, "%s destroyAudioPolicyManager is null %s",
269 __func__, lastError != nullptr ? lastError : "no error");
270 if (mCreateAudioPolicyManager == nullptr || mDestroyAudioPolicyManager == nullptr){
271 unloadAudioPolicyManager();
272 LOG_ALWAYS_FATAL("could not find audiopolicymanager interface methods");
273 }
274 }
Eric Laurentf5ada6e2014-10-09 17:49:00 -0700275}
276
277void AudioPolicyService::onFirstRef()
278{
Andy Hungd47aca22022-03-15 11:50:51 -0700279 // Log an AudioPolicy "constructor" mediametrics event on first ref.
280 // This records the time it takes to load the audio modules and devices.
281 mediametrics::Defer defer([beginNs = systemTime()] {
282 mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_POLICY)
283 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR)
284 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
285 .record(); });
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700286 {
287 Mutex::Autolock _l(mLock);
Eric Laurent93575202011-01-18 18:39:02 -0800288
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700289 // start audio commands thread
290 mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
291 // start output activity command thread
292 mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
Eric Laurentdce54a12014-03-10 12:19:46 -0700293
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700294 mAudioPolicyClient = new AudioPolicyClient(this);
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530295
296 loadAudioPolicyManager();
297 mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700298 }
Eric Laurentd66d7a12021-07-13 13:35:32 +0200299
bryant_liuba2b4392014-06-11 16:49:30 +0800300 // load audio processing modules
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000301 const sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
302 sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects(effectsFactoryHal);
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000303 sp<UidPolicy> uidPolicy = new UidPolicy(this);
304 sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700305 {
306 Mutex::Autolock _l(mLock);
307 mAudioPolicyEffects = audioPolicyEffects;
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000308 mUidPolicy = uidPolicy;
309 mSensorPrivacyPolicy = sensorPrivacyPolicy;
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700310 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000311 uidPolicy->registerSelf();
312 sensorPrivacyPolicy->registerSelf();
Eric Laurentd66d7a12021-07-13 13:35:32 +0200313
Eric Laurent81dd0f52021-07-05 11:54:40 +0200314 // Create spatializer if supported
Eric Laurent52b0bd52021-09-27 15:25:40 +0200315 if (mAudioPolicyManager != nullptr) {
316 Mutex::Autolock _l(mLock);
317 const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
318 AudioDeviceTypeAddrVector devices;
319 bool hasSpatializer = mAudioPolicyManager->canBeSpatialized(&attr, nullptr, devices);
320 if (hasSpatializer) {
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000321 mSpatializer = Spatializer::create(this, effectsFactoryHal);
Eric Laurent52b0bd52021-09-27 15:25:40 +0200322 }
Andy Hung8aa43c02022-09-13 18:53:06 -0700323 if (mSpatializer == nullptr) {
324 // No spatializer created, signal the reason: NO_INIT a failure, OK means intended.
325 const status_t createStatus = hasSpatializer ? NO_INIT : OK;
326 Spatializer::sendEmptyCreateSpatializerMetricWithStatus(createStatus);
327 }
Eric Laurent81dd0f52021-07-05 11:54:40 +0200328 }
Eric Laurentd66d7a12021-07-13 13:35:32 +0200329 AudioSystem::audioPolicyReady();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700330}
331
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530332void AudioPolicyService::unloadAudioPolicyManager()
333{
334 ALOGV("%s ", __func__);
335 if (mLibraryHandle != nullptr) {
336 dlclose(mLibraryHandle);
337 }
338 mLibraryHandle = nullptr;
339 mCreateAudioPolicyManager = nullptr;
340 mDestroyAudioPolicyManager = nullptr;
341}
342
Mathias Agopian65ab4712010-07-14 17:59:35 -0700343AudioPolicyService::~AudioPolicyService()
344{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700345 mAudioCommandThread->exit();
Eric Laurent657ff612014-05-07 11:58:24 -0700346 mOutputCommandThread->exit();
Eric Laurent7c7f10b2011-06-17 21:29:58 -0700347
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530348 mDestroyAudioPolicyManager(mAudioPolicyManager);
349 unloadAudioPolicyManager();
350
Eric Laurentdce54a12014-03-10 12:19:46 -0700351 delete mAudioPolicyClient;
Eric Laurentb52c1522014-05-20 11:27:36 -0700352
353 mNotificationClients.clear();
bryant_liuba2b4392014-06-11 16:49:30 +0800354 mAudioPolicyEffects.clear();
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800355
356 mUidPolicy->unregisterSelf();
Michael Groovercfd28302018-12-11 19:16:46 -0800357 mSensorPrivacyPolicy->unregisterSelf();
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000358
359 mUidPolicy.clear();
Michael Groovercfd28302018-12-11 19:16:46 -0800360 mSensorPrivacyPolicy.clear();
Eric Laurentb52c1522014-05-20 11:27:36 -0700361}
362
363// A notification client is always registered by AudioSystem when the client process
364// connects to AudioPolicyService.
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800365Status AudioPolicyService::registerClient(const sp<media::IAudioPolicyServiceClient>& client)
Eric Laurentb52c1522014-05-20 11:27:36 -0700366{
Eric Laurent12590252015-08-21 18:40:20 -0700367 if (client == 0) {
368 ALOGW("%s got NULL client", __FUNCTION__);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800369 return Status::ok();
Eric Laurent12590252015-08-21 18:40:20 -0700370 }
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800371 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700372
373 uid_t uid = IPCThreadState::self()->getCallingUid();
luochaojiang908c7d72018-06-21 14:58:04 +0800374 pid_t pid = IPCThreadState::self()->getCallingPid();
375 int64_t token = ((int64_t)uid<<32) | pid;
376
377 if (mNotificationClients.indexOfKey(token) < 0) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700378 sp<NotificationClient> notificationClient = new NotificationClient(this,
379 client,
luochaojiang908c7d72018-06-21 14:58:04 +0800380 uid,
381 pid);
382 ALOGV("registerClient() client %p, uid %d pid %d", client.get(), uid, pid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700383
luochaojiang908c7d72018-06-21 14:58:04 +0800384 mNotificationClients.add(token, notificationClient);
Eric Laurentb52c1522014-05-20 11:27:36 -0700385
Marco Nelissenf8880202014-11-14 07:58:25 -0800386 sp<IBinder> binder = IInterface::asBinder(client);
Eric Laurentb52c1522014-05-20 11:27:36 -0700387 binder->linkToDeath(notificationClient);
388 }
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800389 return Status::ok();
Eric Laurentb52c1522014-05-20 11:27:36 -0700390}
391
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800392Status AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
Eric Laurente8726fe2015-06-26 09:39:24 -0700393{
394 Mutex::Autolock _l(mNotificationClientsLock);
395
396 uid_t uid = IPCThreadState::self()->getCallingUid();
luochaojiang908c7d72018-06-21 14:58:04 +0800397 pid_t pid = IPCThreadState::self()->getCallingPid();
398 int64_t token = ((int64_t)uid<<32) | pid;
399
400 if (mNotificationClients.indexOfKey(token) < 0) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800401 return Status::ok();
Eric Laurente8726fe2015-06-26 09:39:24 -0700402 }
luochaojiang908c7d72018-06-21 14:58:04 +0800403 mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800404 return Status::ok();
Eric Laurente8726fe2015-06-26 09:39:24 -0700405}
406
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800407Status AudioPolicyService::setAudioVolumeGroupCallbacksEnabled(bool enabled)
François Gaffiecfe17322018-11-07 13:41:29 +0100408{
409 Mutex::Autolock _l(mNotificationClientsLock);
410
411 uid_t uid = IPCThreadState::self()->getCallingUid();
412 pid_t pid = IPCThreadState::self()->getCallingPid();
413 int64_t token = ((int64_t)uid<<32) | pid;
414
415 if (mNotificationClients.indexOfKey(token) < 0) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800416 return Status::ok();
François Gaffiecfe17322018-11-07 13:41:29 +0100417 }
418 mNotificationClients.valueFor(token)->setAudioVolumeGroupCallbacksEnabled(enabled);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800419 return Status::ok();
François Gaffiecfe17322018-11-07 13:41:29 +0100420}
421
Eric Laurentb52c1522014-05-20 11:27:36 -0700422// removeNotificationClient() is called when the client process dies.
luochaojiang908c7d72018-06-21 14:58:04 +0800423void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
Eric Laurentb52c1522014-05-20 11:27:36 -0700424{
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000425 bool hasSameUid = false;
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800426 {
427 Mutex::Autolock _l(mNotificationClientsLock);
luochaojiang908c7d72018-06-21 14:58:04 +0800428 int64_t token = ((int64_t)uid<<32) | pid;
429 mNotificationClients.removeItem(token);
luochaojiang908c7d72018-06-21 14:58:04 +0800430 for (size_t i = 0; i < mNotificationClients.size(); i++) {
431 if (mNotificationClients.valueAt(i)->uid() == uid) {
432 hasSameUid = true;
433 break;
434 }
435 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000436 }
437 {
438 Mutex::Autolock _l(mLock);
luochaojiang908c7d72018-06-21 14:58:04 +0800439 if (mAudioPolicyManager && !hasSameUid) {
Eric Laurent10b71232018-04-13 18:14:44 -0700440 // called from binder death notification: no need to clear caller identity
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700441 mAudioPolicyManager->releaseResourcesForUid(uid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700442 }
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800443 }
Eric Laurentb52c1522014-05-20 11:27:36 -0700444}
445
446void AudioPolicyService::onAudioPortListUpdate()
447{
448 mOutputCommandThread->updateAudioPortListCommand();
449}
450
451void AudioPolicyService::doOnAudioPortListUpdate()
452{
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800453 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700454 for (size_t i = 0; i < mNotificationClients.size(); i++) {
455 mNotificationClients.valueAt(i)->onAudioPortListUpdate();
456 }
457}
458
459void AudioPolicyService::onAudioPatchListUpdate()
460{
461 mOutputCommandThread->updateAudioPatchListCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700462}
463
Eric Laurentb52c1522014-05-20 11:27:36 -0700464void AudioPolicyService::doOnAudioPatchListUpdate()
465{
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800466 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700467 for (size_t i = 0; i < mNotificationClients.size(); i++) {
468 mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
469 }
470}
471
François Gaffiecfe17322018-11-07 13:41:29 +0100472void AudioPolicyService::onAudioVolumeGroupChanged(volume_group_t group, int flags)
473{
474 mOutputCommandThread->changeAudioVolumeGroupCommand(group, flags);
475}
476
477void AudioPolicyService::doOnAudioVolumeGroupChanged(volume_group_t group, int flags)
478{
479 Mutex::Autolock _l(mNotificationClientsLock);
480 for (size_t i = 0; i < mNotificationClients.size(); i++) {
481 mNotificationClients.valueAt(i)->onAudioVolumeGroupChanged(group, flags);
482 }
483}
484
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700485void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700486{
487 ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
488 regId.string(), state);
489 mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
490}
491
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700492void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700493{
494 Mutex::Autolock _l(mNotificationClientsLock);
495 for (size_t i = 0; i < mNotificationClients.size(); i++) {
496 mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
497 }
498}
499
Eric Laurenta9f86652018-11-28 17:23:11 -0800500void AudioPolicyService::onRecordingConfigurationUpdate(
501 int event,
502 const record_client_info_t *clientInfo,
503 const audio_config_base_t *clientConfig,
504 std::vector<effect_descriptor_t> clientEffects,
505 const audio_config_base_t *deviceConfig,
506 std::vector<effect_descriptor_t> effects,
507 audio_patch_handle_t patchHandle,
508 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800509{
Jean-Michel Triviac4e4292016-12-22 11:39:31 -0800510 mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -0800511 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800512}
513
Eric Laurenta9f86652018-11-28 17:23:11 -0800514void AudioPolicyService::doOnRecordingConfigurationUpdate(
515 int event,
516 const record_client_info_t *clientInfo,
517 const audio_config_base_t *clientConfig,
518 std::vector<effect_descriptor_t> clientEffects,
519 const audio_config_base_t *deviceConfig,
520 std::vector<effect_descriptor_t> effects,
521 audio_patch_handle_t patchHandle,
522 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800523{
524 Mutex::Autolock _l(mNotificationClientsLock);
525 for (size_t i = 0; i < mNotificationClients.size(); i++) {
Jean-Michel Triviac4e4292016-12-22 11:39:31 -0800526 mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -0800527 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800528 }
529}
530
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700531void AudioPolicyService::onRoutingUpdated()
532{
533 mOutputCommandThread->routingChangedCommand();
534}
535
536void AudioPolicyService::doOnRoutingUpdated()
537{
538 Mutex::Autolock _l(mNotificationClientsLock);
539 for (size_t i = 0; i < mNotificationClients.size(); i++) {
540 mNotificationClients.valueAt(i)->onRoutingUpdated();
541 }
542}
543
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +0000544void AudioPolicyService::onVolumeRangeInitRequest()
545{
546 mOutputCommandThread->volRangeInitReqCommand();
547}
548
549void AudioPolicyService::doOnVolumeRangeInitRequest()
550{
551 Mutex::Autolock _l(mNotificationClientsLock);
552 for (size_t i = 0; i < mNotificationClients.size(); i++) {
553 mNotificationClients.valueAt(i)->onVolumeRangeInitRequest();
554 }
555}
556
Eric Laurent81dd0f52021-07-05 11:54:40 +0200557void AudioPolicyService::onCheckSpatializer()
558{
559 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200560 onCheckSpatializer_l();
561}
562
563void AudioPolicyService::onCheckSpatializer_l()
564{
565 if (mSpatializer != nullptr) {
566 mOutputCommandThread->checkSpatializerCommand();
567 }
Eric Laurent81dd0f52021-07-05 11:54:40 +0200568}
569
570void AudioPolicyService::doOnCheckSpatializer()
571{
Eric Laurentd6bee3a2022-08-31 16:07:50 +0200572 ALOGV("%s mSpatializer %p level %d",
573 __func__, mSpatializer.get(), (int)mSpatializer->getLevel());
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200574
Eric Laurent39095982021-08-24 18:29:27 +0200575 if (mSpatializer != nullptr) {
Eric Laurent52b0bd52021-09-27 15:25:40 +0200576 // Note: mSpatializer != nullptr => mAudioPolicyManager != nullptr
Eric Laurent39095982021-08-24 18:29:27 +0200577 if (mSpatializer->getLevel() != media::SpatializationLevel::NONE) {
578 audio_io_handle_t currentOutput = mSpatializer->getOutput();
579 audio_io_handle_t newOutput;
580 const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
581 audio_config_base_t config = mSpatializer->getAudioInConfig();
Eric Laurent21270b62022-07-04 15:11:29 +0200582
583 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200584 status_t status =
585 mAudioPolicyManager->getSpatializerOutput(&config, &attr, &newOutput);
Eric Laurentb4f42a92022-01-17 17:37:31 +0100586 ALOGV("%s currentOutput %d newOutput %d channel_mask %#x",
587 __func__, currentOutput, newOutput, config.channel_mask);
Eric Laurent39095982021-08-24 18:29:27 +0200588 if (status == NO_ERROR && currentOutput == newOutput) {
589 return;
590 }
Eric Laurent15903592022-02-24 20:44:36 +0100591 size_t numActiveTracks = countActiveClientsOnOutput_l(newOutput);
Eric Laurent39095982021-08-24 18:29:27 +0200592 mLock.unlock();
593 // It is OK to call detachOutput() is none is already attached.
594 mSpatializer->detachOutput();
Eric Laurent21270b62022-07-04 15:11:29 +0200595 if (status == NO_ERROR && newOutput != AUDIO_IO_HANDLE_NONE) {
596 status = mSpatializer->attachOutput(newOutput, numActiveTracks);
Eric Laurent39095982021-08-24 18:29:27 +0200597 }
Eric Laurent39095982021-08-24 18:29:27 +0200598 mLock.lock();
599 if (status != NO_ERROR) {
600 mAudioPolicyManager->releaseSpatializerOutput(newOutput);
601 }
602 } else if (mSpatializer->getLevel() == media::SpatializationLevel::NONE
603 && mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
Eric Laurent39095982021-08-24 18:29:27 +0200604 audio_io_handle_t output = mSpatializer->detachOutput();
Eric Laurent21270b62022-07-04 15:11:29 +0200605
Eric Laurent39095982021-08-24 18:29:27 +0200606 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurent21270b62022-07-04 15:11:29 +0200607 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200608 mAudioPolicyManager->releaseSpatializerOutput(output);
Eric Laurent81dd0f52021-07-05 11:54:40 +0200609 }
610 }
611 }
612}
613
Eric Laurent11094172022-04-05 18:27:42 +0200614size_t AudioPolicyService::countActiveClientsOnOutput_l(
615 audio_io_handle_t output, bool spatializedOnly) {
Eric Laurent15903592022-02-24 20:44:36 +0100616 size_t count = 0;
617 for (size_t i = 0; i < mAudioPlaybackClients.size(); i++) {
618 auto client = mAudioPlaybackClients.valueAt(i);
Eric Laurent11094172022-04-05 18:27:42 +0200619 if (client->io == output && client->active
620 && (!spatializedOnly || client->isSpatialized)) {
Eric Laurent15903592022-02-24 20:44:36 +0100621 count++;
622 }
623 }
624 return count;
625}
626
627void AudioPolicyService::onUpdateActiveSpatializerTracks_l() {
628 if (mSpatializer == nullptr) {
629 return;
630 }
631 mOutputCommandThread->updateActiveSpatializerTracksCommand();
632}
633
634void AudioPolicyService::doOnUpdateActiveSpatializerTracks()
635{
Eric Laurent21270b62022-07-04 15:11:29 +0200636 if (mSpatializer == nullptr) {
637 return;
638 }
639 audio_io_handle_t output = mSpatializer->getOutput();
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200640 size_t activeClients;
641 {
642 Mutex::Autolock _l(mLock);
Eric Laurent21270b62022-07-04 15:11:29 +0200643 activeClients = countActiveClientsOnOutput_l(output);
Eric Laurent15903592022-02-24 20:44:36 +0100644 }
Eric Laurent21270b62022-07-04 15:11:29 +0200645 mSpatializer->updateActiveTracks(activeClients);
Eric Laurent15903592022-02-24 20:44:36 +0100646}
647
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800648status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
649 audio_patch_handle_t *handle,
650 int delayMs)
651{
652 return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
653}
654
655status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
656 int delayMs)
657{
658 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
659}
660
Eric Laurente1715a42014-05-20 11:30:42 -0700661status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
662 int delayMs)
663{
664 return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
665}
666
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800667AudioPolicyService::NotificationClient::NotificationClient(
668 const sp<AudioPolicyService>& service,
669 const sp<media::IAudioPolicyServiceClient>& client,
670 uid_t uid,
671 pid_t pid)
luochaojiang908c7d72018-06-21 14:58:04 +0800672 : mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
François Gaffiecfe17322018-11-07 13:41:29 +0100673 mAudioPortCallbacksEnabled(false), mAudioVolumeGroupCallbacksEnabled(false)
Eric Laurentb52c1522014-05-20 11:27:36 -0700674{
675}
676
677AudioPolicyService::NotificationClient::~NotificationClient()
678{
679}
680
681void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
682{
683 sp<NotificationClient> keep(this);
684 sp<AudioPolicyService> service = mService.promote();
685 if (service != 0) {
luochaojiang908c7d72018-06-21 14:58:04 +0800686 service->removeNotificationClient(mUid, mPid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700687 }
688}
689
690void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
691{
Eric Laurente8726fe2015-06-26 09:39:24 -0700692 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700693 mAudioPolicyServiceClient->onAudioPortListUpdate();
694 }
695}
696
697void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
698{
Eric Laurente8726fe2015-06-26 09:39:24 -0700699 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700700 mAudioPolicyServiceClient->onAudioPatchListUpdate();
701 }
702}
Eric Laurent57dae992011-07-24 13:36:09 -0700703
Pattydd807582021-11-04 21:01:03 +0800704void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
François Gaffiecfe17322018-11-07 13:41:29 +0100705 int flags)
706{
707 if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
708 mAudioPolicyServiceClient->onAudioVolumeGroupChanged(group, flags);
709 }
710}
711
712
Jean-Michel Trivide801052015-04-14 19:10:14 -0700713void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700714 const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700715{
Andy Hung4ef19fa2018-05-15 19:35:29 -0700716 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800717 mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(
718 legacy2aidl_String8_string(regId).value(), state);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800719 }
720}
721
722void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
Eric Laurenta9f86652018-11-28 17:23:11 -0800723 int event,
724 const record_client_info_t *clientInfo,
725 const audio_config_base_t *clientConfig,
726 std::vector<effect_descriptor_t> clientEffects,
727 const audio_config_base_t *deviceConfig,
728 std::vector<effect_descriptor_t> effects,
729 audio_patch_handle_t patchHandle,
730 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800731{
Andy Hung4ef19fa2018-05-15 19:35:29 -0700732 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800733 status_t status = [&]() -> status_t {
734 int32_t eventAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(event));
735 media::RecordClientInfo clientInfoAidl = VALUE_OR_RETURN_STATUS(
736 legacy2aidl_record_client_info_t_RecordClientInfo(*clientInfo));
Mikhail Naganovdbf03642021-08-25 18:15:32 -0700737 AudioConfigBase clientConfigAidl = VALUE_OR_RETURN_STATUS(
Mikhail Naganovde3fa182021-07-30 15:06:42 -0700738 legacy2aidl_audio_config_base_t_AudioConfigBase(
739 *clientConfig, true /*isInput*/));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800740 std::vector<media::EffectDescriptor> clientEffectsAidl = VALUE_OR_RETURN_STATUS(
741 convertContainer<std::vector<media::EffectDescriptor>>(
742 clientEffects,
743 legacy2aidl_effect_descriptor_t_EffectDescriptor));
Mikhail Naganovdbf03642021-08-25 18:15:32 -0700744 AudioConfigBase deviceConfigAidl = VALUE_OR_RETURN_STATUS(
Mikhail Naganovde3fa182021-07-30 15:06:42 -0700745 legacy2aidl_audio_config_base_t_AudioConfigBase(
746 *deviceConfig, true /*isInput*/));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800747 std::vector<media::EffectDescriptor> effectsAidl = VALUE_OR_RETURN_STATUS(
748 convertContainer<std::vector<media::EffectDescriptor>>(
749 effects,
750 legacy2aidl_effect_descriptor_t_EffectDescriptor));
751 int32_t patchHandleAidl = VALUE_OR_RETURN_STATUS(
752 legacy2aidl_audio_patch_handle_t_int32_t(patchHandle));
Mikhail Naganovddceecc2021-09-03 13:58:56 -0700753 media::audio::common::AudioSource sourceAidl = VALUE_OR_RETURN_STATUS(
754 legacy2aidl_audio_source_t_AudioSource(source));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800755 return aidl_utils::statusTFromBinderStatus(
756 mAudioPolicyServiceClient->onRecordingConfigurationUpdate(eventAidl,
757 clientInfoAidl,
758 clientConfigAidl,
759 clientEffectsAidl,
760 deviceConfigAidl,
761 effectsAidl,
762 patchHandleAidl,
763 sourceAidl));
764 }();
765 ALOGW_IF(status != OK, "onRecordingConfigurationUpdate() failed: %d", status);
Jean-Michel Trivide801052015-04-14 19:10:14 -0700766 }
767}
768
Eric Laurente8726fe2015-06-26 09:39:24 -0700769void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
770{
771 mAudioPortCallbacksEnabled = enabled;
772}
773
François Gaffiecfe17322018-11-07 13:41:29 +0100774void AudioPolicyService::NotificationClient::setAudioVolumeGroupCallbacksEnabled(bool enabled)
775{
776 mAudioVolumeGroupCallbacksEnabled = enabled;
777}
Eric Laurente8726fe2015-06-26 09:39:24 -0700778
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700779void AudioPolicyService::NotificationClient::onRoutingUpdated()
780{
781 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
782 mAudioPolicyServiceClient->onRoutingUpdated();
783 }
784}
785
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +0000786void AudioPolicyService::NotificationClient::onVolumeRangeInitRequest()
787{
788 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
789 mAudioPolicyServiceClient->onVolumeRangeInitRequest();
790 }
791}
792
Mathias Agopian65ab4712010-07-14 17:59:35 -0700793void AudioPolicyService::binderDied(const wp<IBinder>& who) {
Glenn Kasten411e4472012-11-02 10:00:06 -0700794 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
Eric Laurentde070132010-07-13 04:45:46 -0700795 IPCThreadState::self()->getCallingPid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700796}
797
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000798static bool dumpTryLock(Mutex& mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Mathias Agopian65ab4712010-07-14 17:59:35 -0700799{
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000800 return mutex.timedLock(kDumpLockTimeoutNs) == NO_ERROR;
801}
802
803static void dumpReleaseLock(Mutex& mutex, bool locked) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
804{
805 if (locked) mutex.unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700806}
807
808status_t AudioPolicyService::dumpInternals(int fd)
809{
810 const size_t SIZE = 256;
811 char buffer[SIZE];
812 String8 result;
813
Mikhail Naganovb3bcb4f2022-02-23 23:46:56 +0000814 snprintf(buffer, SIZE, "Supported System Usages:\n ");
Hayden Gomes524159d2019-12-23 14:41:47 -0800815 result.append(buffer);
Mikhail Naganovb3bcb4f2022-02-23 23:46:56 +0000816 std::stringstream msg;
817 size_t i = 0;
818 for (auto usage : mSupportedSystemUsages) {
819 if (i++ != 0) msg << ", ";
820 if (const char* strUsage = audio_usage_to_string(usage); strUsage) {
821 msg << strUsage;
822 } else {
823 msg << usage << " (unknown)";
824 }
Hayden Gomes524159d2019-12-23 14:41:47 -0800825 }
Mikhail Naganovb3bcb4f2022-02-23 23:46:56 +0000826 if (i == 0) {
827 msg << "None";
828 }
829 msg << std::endl;
830 result.append(msg.str().c_str());
Hayden Gomes524159d2019-12-23 14:41:47 -0800831
Mathias Agopian65ab4712010-07-14 17:59:35 -0700832 write(fd, result.string(), result.size());
Oscar Azucena829d90d2022-01-28 17:17:56 -0800833
834 mUidPolicy->dumpInternals(fd);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700835 return NO_ERROR;
836}
837
Eric Laurente8c8b432018-10-17 10:08:02 -0700838void AudioPolicyService::updateUidStates()
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800839{
Eric Laurente8c8b432018-10-17 10:08:02 -0700840 Mutex::Autolock _l(mLock);
841 updateUidStates_l();
842}
843
844void AudioPolicyService::updateUidStates_l()
845{
Eric Laurent4eb58f12018-12-07 16:41:02 -0800846// Go over all active clients and allow capture (does not force silence) in the
847// following cases:
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800848// The client is in the active assistant list
849// AND is TOP
850// AND an accessibility service is TOP
851// AND source is either VOICE_RECOGNITION OR HOTWORD
852// OR there is no active privacy sensitive capture or call
853// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
854// AND source is VOICE_RECOGNITION OR HOTWORD
855// The client is an assistant AND active assistant is not being used
Evan Severson1f700cd2021-02-10 13:10:37 -0800856// AND an accessibility service is on TOP or a RTT call is active
Eric Laurent589171c2019-07-25 18:04:29 -0700857// AND the source is VOICE_RECOGNITION or HOTWORD
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800858// OR there is no active privacy sensitive capture or call
Evan Severson1f700cd2021-02-10 13:10:37 -0800859// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800860// AND is TOP most recent assistant and uses VOICE_RECOGNITION or HOTWORD
861// OR there is no top recent assistant and source is HOTWORD
Evan Severson1f700cd2021-02-10 13:10:37 -0800862// OR The client is an accessibility service
863// AND Is on TOP
864// AND the source is VOICE_RECOGNITION or HOTWORD
865// OR The assistant is not on TOP
Eric Laurent589171c2019-07-25 18:04:29 -0700866// AND there is no active privacy sensitive capture or call
867// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Evan Severson1f700cd2021-02-10 13:10:37 -0800868// AND is on TOP
869// AND the source is VOICE_RECOGNITION or HOTWORD
870// OR the client source is virtual (remote submix, call audio TX or RX...)
871// OR the client source is HOTWORD
872// AND is on TOP
873// OR all active clients are using HOTWORD source
874// AND no call is active
875// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
876// OR the client is the current InputMethodService
877// AND a RTT call is active AND the source is VOICE_RECOGNITION
878// OR Any client
879// AND The assistant is not on TOP
880// AND is on TOP or latest started
881// AND there is no active privacy sensitive capture or call
882// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent4eb58f12018-12-07 16:41:02 -0800883
Eric Laurent4e947da2019-10-17 15:24:06 -0700884
Eric Laurent4eb58f12018-12-07 16:41:02 -0800885 sp<AudioRecordClient> topActive;
886 sp<AudioRecordClient> latestActive;
Eric Laurentc21d5692020-02-25 10:24:36 -0800887 sp<AudioRecordClient> topSensitiveActive;
Eric Laurentb809a752020-06-29 09:53:13 -0700888 sp<AudioRecordClient> latestSensitiveActiveOrComm;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800889 sp<AudioRecordClient> latestActiveAssistant;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700890
Eric Laurenta46bedb2018-12-07 18:01:26 -0800891 nsecs_t topStartNs = 0;
892 nsecs_t latestStartNs = 0;
Eric Laurentc21d5692020-02-25 10:24:36 -0800893 nsecs_t topSensitiveStartNs = 0;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800894 nsecs_t latestSensitiveStartNs = 0;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800895 nsecs_t latestAssistantStartNs = 0;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800896 bool isA11yOnTop = mUidPolicy->isA11yOnTop();
897 bool isAssistantOnTop = false;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800898 bool useActiveAssistantList = false;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800899 bool isSensitiveActive = false;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700900 bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
Eric Laurentc21d5692020-02-25 10:24:36 -0800901 bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION;
902 bool rttCallActive = (isInCall || isInCommunication)
Eric Laurent6ede98f2019-06-11 14:50:30 -0700903 && mUidPolicy->isRttEnabled();
Eric Laurent4e947da2019-10-17 15:24:06 -0700904 bool onlyHotwordActive = true;
Eric Laurentb809a752020-06-29 09:53:13 -0700905 bool isPhoneStateOwnerActive = false;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800906
Michael Groovercfd28302018-12-11 19:16:46 -0800907 // if Sensor Privacy is enabled then all recordings should be silenced.
908 if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
909 silenceAllRecordings_l();
910 return;
911 }
912
Eric Laurente8c8b432018-10-17 10:08:02 -0700913 for (size_t i =0; i < mAudioRecordClients.size(); i++) {
914 sp<AudioRecordClient> current = mAudioRecordClients[i];
Svet Ganov33761132021-05-13 22:51:08 +0000915 uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
916 current->attributionSource.uid));
Evan Severson1f700cd2021-02-10 13:10:37 -0800917 if (!current->active) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700918 continue;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800919 }
Eric Laurent1ff16a72019-03-14 18:35:04 -0700920
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700921 app_state_t appState = apmStatFromAmState(mUidPolicy->getUidState(currentUid));
Eric Laurent1ff16a72019-03-14 18:35:04 -0700922 // clients which app is in IDLE state are not eligible for top active or
923 // latest active
924 if (appState == APP_STATE_IDLE) {
925 continue;
926 }
927
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700928 bool isAccessibility = mUidPolicy->isA11yUid(currentUid);
Eric Laurent14a88632020-07-16 12:28:30 -0700929 // Clients capturing for Accessibility services or virtual sources are not considered
Eric Laurentc21d5692020-02-25 10:24:36 -0800930 // for top or latest active to avoid masking regular clients started before
Eric Laurent14a88632020-07-16 12:28:30 -0700931 if (!isAccessibility && !isVirtualSource(current->attributes.source)) {
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700932 bool isAssistant = mUidPolicy->isAssistantUid(currentUid);
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800933 bool isActiveAssistant = mUidPolicy->isActiveAssistantUid(currentUid);
Eric Laurentc21d5692020-02-25 10:24:36 -0800934 bool isPrivacySensitive =
935 (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0;
Eric Laurentb809a752020-06-29 09:53:13 -0700936
Eric Laurentc21d5692020-02-25 10:24:36 -0800937 if (appState == APP_STATE_TOP) {
938 if (isPrivacySensitive) {
939 if (current->startTimeNs > topSensitiveStartNs) {
940 topSensitiveActive = current;
941 topSensitiveStartNs = current->startTimeNs;
942 }
943 } else {
944 if (current->startTimeNs > topStartNs) {
945 topActive = current;
946 topStartNs = current->startTimeNs;
947 }
948 }
949 if (isAssistant) {
950 isAssistantOnTop = true;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800951 if (isActiveAssistant) {
952 useActiveAssistantList = true;
953 } else if (!useActiveAssistantList) {
954 if (current->startTimeNs > latestAssistantStartNs) {
955 latestActiveAssistant = current;
956 latestAssistantStartNs = current->startTimeNs;
957 }
958 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800959 }
Eric Laurenta46bedb2018-12-07 18:01:26 -0800960 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800961 // Clients capturing for HOTWORD are not considered
962 // for latest active to avoid masking regular clients started before
963 if (!(current->attributes.source == AUDIO_SOURCE_HOTWORD
964 || ((isA11yOnTop || rttCallActive) && isAssistant))) {
965 if (isPrivacySensitive) {
Eric Laurentb809a752020-06-29 09:53:13 -0700966 // if audio mode is IN_COMMUNICATION, make sure the audio mode owner
967 // is marked latest sensitive active even if another app qualifies.
968 if (current->startTimeNs > latestSensitiveStartNs
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700969 || (isInCommunication && currentUid == mPhoneStateOwnerUid)) {
Eric Laurentb809a752020-06-29 09:53:13 -0700970 if (!isInCommunication || latestSensitiveActiveOrComm == nullptr
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700971 || VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +0000972 latestSensitiveActiveOrComm->attributionSource.uid))
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700973 != mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -0700974 latestSensitiveActiveOrComm = current;
975 latestSensitiveStartNs = current->startTimeNs;
976 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800977 }
978 isSensitiveActive = true;
979 } else {
980 if (current->startTimeNs > latestStartNs) {
981 latestActive = current;
982 latestStartNs = current->startTimeNs;
983 }
984 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800985 }
986 }
Eric Laurent4e947da2019-10-17 15:24:06 -0700987 if (current->attributes.source != AUDIO_SOURCE_HOTWORD) {
988 onlyHotwordActive = false;
989 }
Eric Laurentb0eff0f2021-11-09 16:05:49 +0100990 if (currentUid == mPhoneStateOwnerUid &&
991 !isVirtualSource(current->attributes.source)) {
Eric Laurentb809a752020-06-29 09:53:13 -0700992 isPhoneStateOwnerActive = true;
993 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800994 }
995
Eric Laurent1ff16a72019-03-14 18:35:04 -0700996 // if no active client with UI on Top, consider latest active as top
997 if (topActive == nullptr) {
998 topActive = latestActive;
Eric Laurentc21d5692020-02-25 10:24:36 -0800999 topStartNs = latestStartNs;
1000 }
1001 if (topSensitiveActive == nullptr) {
Eric Laurentb809a752020-06-29 09:53:13 -07001002 topSensitiveActive = latestSensitiveActiveOrComm;
Eric Laurentc21d5692020-02-25 10:24:36 -08001003 topSensitiveStartNs = latestSensitiveStartNs;
Eric Laurentb809a752020-06-29 09:53:13 -07001004 } else if (latestSensitiveActiveOrComm != nullptr) {
1005 // if audio mode is IN_COMMUNICATION, favor audio mode owner over an app with
1006 // foreground UI in case both are capturing with privacy sensitive flag.
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001007 uid_t latestActiveUid = VALUE_OR_FATAL(
Svet Ganov33761132021-05-13 22:51:08 +00001008 aidl2legacy_int32_t_uid_t(latestSensitiveActiveOrComm->attributionSource.uid));
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001009 if (isInCommunication && latestActiveUid == mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -07001010 topSensitiveActive = latestSensitiveActiveOrComm;
1011 topSensitiveStartNs = latestSensitiveStartNs;
1012 }
Eric Laurentc21d5692020-02-25 10:24:36 -08001013 }
1014
1015 // If both privacy sensitive and regular capture are active:
1016 // if the regular capture is privileged
1017 // allow concurrency
1018 // else
1019 // favor the privacy sensitive case
1020 if (topActive != nullptr && topSensitiveActive != nullptr
Ricardo Correa57a37692020-03-23 17:27:25 -07001021 && !topActive->canCaptureOutput) {
Eric Laurentc21d5692020-02-25 10:24:36 -08001022 topActive = nullptr;
Eric Laurent4eb58f12018-12-07 16:41:02 -08001023 }
1024
1025 for (size_t i =0; i < mAudioRecordClients.size(); i++) {
1026 sp<AudioRecordClient> current = mAudioRecordClients[i];
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001027 uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +00001028 current->attributionSource.uid));
Eric Laurent1ff16a72019-03-14 18:35:04 -07001029 if (!current->active) {
1030 continue;
1031 }
1032
Eric Laurent4eb58f12018-12-07 16:41:02 -08001033 audio_source_t source = current->attributes.source;
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001034 bool isTopOrLatestActive = topActive == nullptr ? false :
Svet Ganov33761132021-05-13 22:51:08 +00001035 current->attributionSource.uid == topActive->attributionSource.uid;
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001036 bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false :
Svet Ganov33761132021-05-13 22:51:08 +00001037 current->attributionSource.uid == topSensitiveActive->attributionSource.uid;
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001038 bool isTopOrLatestAssistant = latestActiveAssistant == nullptr ? false :
1039 current->attributionSource.uid == latestActiveAssistant->attributionSource.uid;
Eric Laurentc21d5692020-02-25 10:24:36 -08001040
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001041 auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) REQUIRES(mLock) {
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001042 uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +00001043 recordClient->attributionSource.uid));
Ricardo Correa57a37692020-03-23 17:27:25 -07001044 bool canCaptureCall = recordClient->canCaptureOutput;
Eric Laurentb809a752020-06-29 09:53:13 -07001045 bool canCaptureCommunication = recordClient->canCaptureOutput
1046 || !isPhoneStateOwnerActive
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001047 || recordUid == mPhoneStateOwnerUid;
Eric Laurentb809a752020-06-29 09:53:13 -07001048 return !(isInCall && !canCaptureCall)
1049 && !(isInCommunication && !canCaptureCommunication);
Eric Laurentc21d5692020-02-25 10:24:36 -08001050 };
Eric Laurent1ff16a72019-03-14 18:35:04 -07001051
1052 // By default allow capture if:
1053 // The assistant is not on TOP
Eric Laurenta171e352019-05-07 13:04:45 -07001054 // AND is on TOP or latest started
Eric Laurent1ff16a72019-03-14 18:35:04 -07001055 // AND there is no active privacy sensitive capture or call
1056 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent4ab18412022-11-07 16:25:32 +01001057 bool allowSensitiveCapture =
1058 !isSensitiveActive || isTopOrLatestSensitive || current->canCaptureOutput;
Eric Laurent1ff16a72019-03-14 18:35:04 -07001059 bool allowCapture = !isAssistantOnTop
Eric Laurentc21d5692020-02-25 10:24:36 -08001060 && (isTopOrLatestActive || isTopOrLatestSensitive)
Eric Laurent4ab18412022-11-07 16:25:32 +01001061 && allowSensitiveCapture
Eric Laurentc21d5692020-02-25 10:24:36 -08001062 && canCaptureIfInCallOrCommunication(current);
Eric Laurent2dc962b2019-03-01 08:25:25 -08001063
Eric Laurented726cc2021-07-01 14:26:41 +02001064 if (!current->hasOp()) {
1065 // Never allow capture if app op is denied
1066 allowCapture = false;
1067 } else if (isVirtualSource(source)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001068 // Allow capture for virtual (remote submix, call audio TX or RX...) sources
1069 allowCapture = true;
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001070 } else if (!useActiveAssistantList && mUidPolicy->isAssistantUid(currentUid)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001071 // For assistant allow capture if:
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001072 // Active assistant list is not being used
1073 // AND accessibility service is on TOP or a RTT call is active
Eric Laurent1ff16a72019-03-14 18:35:04 -07001074 // AND the source is VOICE_RECOGNITION or HOTWORD
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001075 // OR there is no active privacy sensitive capture or call
1076 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1077 // AND is latest TOP assistant AND
1078 // uses VOICE_RECOGNITION OR uses HOTWORD
1079 // OR there is no TOP assistant and uses HOTWORD
Eric Laurent6ede98f2019-06-11 14:50:30 -07001080 if (isA11yOnTop || rttCallActive) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001081 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001082 allowCapture = true;
Eric Laurent4eb58f12018-12-07 16:41:02 -08001083 }
Eric Laurent4ab18412022-11-07 16:25:32 +01001084 } else if (allowSensitiveCapture
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001085 && canCaptureIfInCallOrCommunication(current)) {
1086 if (isTopOrLatestAssistant
1087 && (source == AUDIO_SOURCE_VOICE_RECOGNITION
1088 || source == AUDIO_SOURCE_HOTWORD)) {
1089 allowCapture = true;
1090 } else if (!isAssistantOnTop && (source == AUDIO_SOURCE_HOTWORD)) {
1091 allowCapture = true;
1092 }
1093 }
1094 } else if (useActiveAssistantList && mUidPolicy->isActiveAssistantUid(currentUid)) {
1095 // For assistant on active list and on top allow capture if:
1096 // An accessibility service is on TOP
1097 // AND the source is VOICE_RECOGNITION or HOTWORD
1098 // OR there is no active privacy sensitive capture or call
1099 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1100 // AND uses VOICE_RECOGNITION OR uses HOTWORD
1101 if (isA11yOnTop) {
1102 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1103 allowCapture = true;
1104 }
Eric Laurent4ab18412022-11-07 16:25:32 +01001105 } else if (allowSensitiveCapture
Eric Laurentc21d5692020-02-25 10:24:36 -08001106 && canCaptureIfInCallOrCommunication(current)) {
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001107 if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) || (source == AUDIO_SOURCE_HOTWORD))
1108 {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001109 allowCapture = true;
Eric Laurent4eb58f12018-12-07 16:41:02 -08001110 }
1111 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001112 } else if (mUidPolicy->isA11yUid(currentUid)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001113 // For accessibility service allow capture if:
Eric Laurent47670c92019-08-28 16:59:05 -07001114 // The assistant is not on TOP
1115 // AND there is no active privacy sensitive capture or call
Eric Laurent589171c2019-07-25 18:04:29 -07001116 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent47670c92019-08-28 16:59:05 -07001117 // OR
1118 // Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
1119 if (!isAssistantOnTop
Eric Laurent4ab18412022-11-07 16:25:32 +01001120 && allowSensitiveCapture
Eric Laurentc21d5692020-02-25 10:24:36 -08001121 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent47670c92019-08-28 16:59:05 -07001122 allowCapture = true;
1123 }
Eric Laurent589171c2019-07-25 18:04:29 -07001124 if (isA11yOnTop) {
1125 if (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD) {
1126 allowCapture = true;
1127 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001128 }
Eric Laurent4e947da2019-10-17 15:24:06 -07001129 } else if (source == AUDIO_SOURCE_HOTWORD) {
1130 // For HOTWORD source allow capture when not on TOP if:
1131 // All active clients are using HOTWORD source
1132 // AND no call is active
1133 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurentc21d5692020-02-25 10:24:36 -08001134 if (onlyHotwordActive
1135 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent4e947da2019-10-17 15:24:06 -07001136 allowCapture = true;
1137 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001138 } else if (mUidPolicy->isCurrentImeUid(currentUid)) {
Kohsuke Yatoha623a132020-03-24 20:10:26 -07001139 // For current InputMethodService allow capture if:
1140 // A RTT call is active AND the source is VOICE_RECOGNITION
1141 if (rttCallActive && source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1142 allowCapture = true;
1143 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001144 }
Eric Laurent8c7ef892021-06-10 13:32:16 +02001145 setAppState_l(current,
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001146 allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(currentUid)) :
Eric Laurent1ff16a72019-03-14 18:35:04 -07001147 APP_STATE_IDLE);
Eric Laurente8c8b432018-10-17 10:08:02 -07001148 }
1149}
1150
Michael Groovercfd28302018-12-11 19:16:46 -08001151void AudioPolicyService::silenceAllRecordings_l() {
1152 for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
1153 sp<AudioRecordClient> current = mAudioRecordClients[i];
Eric Laurent1ff16a72019-03-14 18:35:04 -07001154 if (!isVirtualSource(current->attributes.source)) {
Eric Laurent8c7ef892021-06-10 13:32:16 +02001155 setAppState_l(current, APP_STATE_IDLE);
Eric Laurent1ff16a72019-03-14 18:35:04 -07001156 }
Michael Groovercfd28302018-12-11 19:16:46 -08001157 }
1158}
1159
Eric Laurente8c8b432018-10-17 10:08:02 -07001160/* static */
1161app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001162
1163 if (amState == ActivityManager::PROCESS_STATE_UNKNOWN) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001164 return APP_STATE_IDLE;
Eric Laurent1ff16a72019-03-14 18:35:04 -07001165 } else if (amState <= ActivityManager::PROCESS_STATE_TOP) {
1166 // include persistent services
1167 return APP_STATE_TOP;
Eric Laurente8c8b432018-10-17 10:08:02 -07001168 }
1169 return APP_STATE_FOREGROUND;
1170}
1171
Eric Laurent4eb58f12018-12-07 16:41:02 -08001172/* static */
Eric Laurent2dc962b2019-03-01 08:25:25 -08001173bool AudioPolicyService::isVirtualSource(audio_source_t source)
Eric Laurent4eb58f12018-12-07 16:41:02 -08001174{
1175 switch (source) {
1176 case AUDIO_SOURCE_VOICE_UPLINK:
1177 case AUDIO_SOURCE_VOICE_DOWNLINK:
1178 case AUDIO_SOURCE_VOICE_CALL:
Eric Laurent2dc962b2019-03-01 08:25:25 -08001179 case AUDIO_SOURCE_REMOTE_SUBMIX:
1180 case AUDIO_SOURCE_FM_TUNER:
Eric Laurent68eb2122020-04-30 17:40:57 -07001181 case AUDIO_SOURCE_ECHO_REFERENCE:
Eric Laurent4eb58f12018-12-07 16:41:02 -08001182 return true;
1183 default:
1184 break;
1185 }
1186 return false;
1187}
1188
Eric Laurented726cc2021-07-01 14:26:41 +02001189/* static */
1190bool AudioPolicyService::isAppOpSource(audio_source_t source)
1191{
1192 switch (source) {
1193 case AUDIO_SOURCE_FM_TUNER:
1194 case AUDIO_SOURCE_ECHO_REFERENCE:
Eric Laurent637bd202021-09-22 11:17:11 +02001195 case AUDIO_SOURCE_REMOTE_SUBMIX:
Eric Laurented726cc2021-07-01 14:26:41 +02001196 return false;
1197 default:
1198 break;
1199 }
1200 return true;
1201}
1202
Eric Laurent8c7ef892021-06-10 13:32:16 +02001203void AudioPolicyService::setAppState_l(sp<AudioRecordClient> client, app_state_t state)
Eric Laurente8c8b432018-10-17 10:08:02 -07001204{
1205 AutoCallerClear acc;
1206
1207 if (mAudioPolicyManager) {
Eric Laurent8c7ef892021-06-10 13:32:16 +02001208 mAudioPolicyManager->setAppState(client->portId, state);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001209 }
1210 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1211 if (af) {
Eric Laurentf32108e2018-10-04 17:22:04 -07001212 bool silenced = state == APP_STATE_IDLE;
Eric Laurent8c7ef892021-06-10 13:32:16 +02001213 if (client->silenced != silenced) {
1214 if (client->active) {
1215 if (silenced) {
1216 finishRecording(client->attributionSource, client->attributes.source);
1217 } else {
1218 std::stringstream msg;
1219 msg << "Audio recording un-silenced on session " << client->session;
1220 if (!startRecording(client->attributionSource, String16(msg.str().c_str()),
1221 client->attributes.source)) {
1222 silenced = true;
1223 }
1224 }
1225 }
1226 af->setRecordSilenced(client->portId, silenced);
1227 client->silenced = silenced;
1228 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001229 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001230}
1231
Glenn Kasten0f11b512014-01-31 16:18:54 -08001232status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001233{
Glenn Kasten44deb052012-02-05 18:09:08 -08001234 if (!dumpAllowed()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001235 dumpPermissionDenial(fd);
1236 } else {
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001237 const bool locked = dumpTryLock(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001238 if (!locked) {
1239 String8 result(kDeadlockedString);
1240 write(fd, result.string(), result.size());
1241 }
1242
1243 dumpInternals(fd);
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001244
1245 String8 actPtr = String8::format("AudioCommandThread: %p\n", mAudioCommandThread.get());
1246 write(fd, actPtr.string(), actPtr.size());
Glenn Kasten9d1f02d2012-02-08 17:47:58 -08001247 if (mAudioCommandThread != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001248 mAudioCommandThread->dump(fd);
1249 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001250
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001251 String8 octPtr = String8::format("OutputCommandThread: %p\n", mOutputCommandThread.get());
1252 write(fd, octPtr.string(), octPtr.size());
1253 if (mOutputCommandThread != 0) {
1254 mOutputCommandThread->dump(fd);
1255 }
1256
Eric Laurentdce54a12014-03-10 12:19:46 -07001257 if (mAudioPolicyManager) {
1258 mAudioPolicyManager->dump(fd);
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001259 } else {
1260 String8 apmPtr = String8::format("AudioPolicyManager: %p\n", mAudioPolicyManager);
1261 write(fd, apmPtr.string(), apmPtr.size());
Eric Laurentdce54a12014-03-10 12:19:46 -07001262 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001263
Kevin Rocard8be94972019-02-22 13:26:25 -08001264 mPackageManager.dump(fd);
1265
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001266 dumpReleaseLock(mLock, locked);
Andy Hungc747c532022-03-07 21:41:14 -08001267
Shunkai Yao59b27bc2022-07-22 18:42:27 +00001268 if (mSpatializer != nullptr) {
1269 std::string dumpString = mSpatializer->toString(1 /* level */);
1270 write(fd, dumpString.c_str(), dumpString.size());
1271 } else {
1272 String8 spatializerPtr = String8::format("Spatializer no supportted on this device\n");
1273 write(fd, spatializerPtr.c_str(), spatializerPtr.size());
1274 }
1275
Andy Hungc747c532022-03-07 21:41:14 -08001276 {
1277 std::string timeCheckStats = getIAudioPolicyServiceStatistics().dump();
1278 dprintf(fd, "\nIAudioPolicyService binder call profile\n");
1279 write(fd, timeCheckStats.c_str(), timeCheckStats.size());
1280 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001281 }
1282 return NO_ERROR;
1283}
1284
1285status_t AudioPolicyService::dumpPermissionDenial(int fd)
1286{
1287 const size_t SIZE = 256;
1288 char buffer[SIZE];
1289 String8 result;
1290 snprintf(buffer, SIZE, "Permission Denial: "
1291 "can't dump AudioPolicyService from pid=%d, uid=%d\n",
1292 IPCThreadState::self()->getCallingPid(),
1293 IPCThreadState::self()->getCallingUid());
1294 result.append(buffer);
1295 write(fd, result.string(), result.size());
1296 return NO_ERROR;
1297}
1298
1299status_t AudioPolicyService::onTransact(
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001300 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001301 // make sure transactions reserved to AudioFlinger do not come from other processes
1302 switch (code) {
1303 case TRANSACTION_startOutput:
1304 case TRANSACTION_stopOutput:
1305 case TRANSACTION_releaseOutput:
1306 case TRANSACTION_getInputForAttr:
1307 case TRANSACTION_startInput:
1308 case TRANSACTION_stopInput:
1309 case TRANSACTION_releaseInput:
1310 case TRANSACTION_getOutputForEffect:
1311 case TRANSACTION_registerEffect:
1312 case TRANSACTION_unregisterEffect:
1313 case TRANSACTION_setEffectEnabled:
1314 case TRANSACTION_getStrategyForStream:
1315 case TRANSACTION_getOutputForAttr:
1316 case TRANSACTION_moveEffectsToIo:
1317 ALOGW("%s: transaction %d received from PID %d",
1318 __func__, code, IPCThreadState::self()->getCallingPid());
1319 return INVALID_OPERATION;
1320 default:
1321 break;
1322 }
1323
1324 // make sure the following transactions come from system components
1325 switch (code) {
1326 case TRANSACTION_setDeviceConnectionState:
1327 case TRANSACTION_handleDeviceConfigChange:
1328 case TRANSACTION_setPhoneState:
1329//FIXME: Allow setForceUse calls from system apps until a better use case routing API is available
1330// case TRANSACTION_setForceUse:
1331 case TRANSACTION_initStreamVolume:
1332 case TRANSACTION_setStreamVolumeIndex:
1333 case TRANSACTION_setVolumeIndexForAttributes:
1334 case TRANSACTION_getStreamVolumeIndex:
1335 case TRANSACTION_getVolumeIndexForAttributes:
1336 case TRANSACTION_getMinVolumeIndexForAttributes:
1337 case TRANSACTION_getMaxVolumeIndexForAttributes:
1338 case TRANSACTION_isStreamActive:
1339 case TRANSACTION_isStreamActiveRemotely:
1340 case TRANSACTION_isSourceActive:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001341 case TRANSACTION_registerPolicyMixes:
1342 case TRANSACTION_setMasterMono:
1343 case TRANSACTION_getSurroundFormats:
Kriti Dang6537def2021-03-02 13:46:59 +01001344 case TRANSACTION_getReportedSurroundFormats:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001345 case TRANSACTION_setSurroundFormatEnabled:
Oscar Azucena829d90d2022-01-28 17:17:56 -08001346 case TRANSACTION_setAssistantServicesUids:
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001347 case TRANSACTION_setActiveAssistantServicesUids:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001348 case TRANSACTION_setA11yServicesUids:
1349 case TRANSACTION_setUidDeviceAffinities:
1350 case TRANSACTION_removeUidDeviceAffinities:
1351 case TRANSACTION_setUserIdDeviceAffinities:
1352 case TRANSACTION_removeUserIdDeviceAffinities:
Pattydd807582021-11-04 21:01:03 +08001353 case TRANSACTION_getHwOffloadFormatsSupportedForBluetoothMedia:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001354 case TRANSACTION_listAudioVolumeGroups:
1355 case TRANSACTION_getVolumeGroupFromAudioAttributes:
1356 case TRANSACTION_acquireSoundTriggerSession:
1357 case TRANSACTION_releaseSoundTriggerSession:
Atneya Nair698f5ef2022-12-15 16:15:09 -08001358 case TRANSACTION_isHotwordStreamSupported:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001359 case TRANSACTION_setRttEnabled:
1360 case TRANSACTION_isCallScreenModeSupported:
1361 case TRANSACTION_setDevicesRoleForStrategy:
1362 case TRANSACTION_setSupportedSystemUsages:
1363 case TRANSACTION_removeDevicesRoleForStrategy:
Paul Wang5d7cdb52022-11-22 09:45:06 +00001364 case TRANSACTION_clearDevicesRoleForStrategy:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001365 case TRANSACTION_getDevicesForRoleAndStrategy:
1366 case TRANSACTION_getDevicesForAttributes:
1367 case TRANSACTION_setAllowedCapturePolicy:
1368 case TRANSACTION_onNewAudioModulesAvailable:
1369 case TRANSACTION_setCurrentImeUid:
1370 case TRANSACTION_registerSoundTriggerCaptureStateListener:
1371 case TRANSACTION_setDevicesRoleForCapturePreset:
1372 case TRANSACTION_addDevicesRoleForCapturePreset:
1373 case TRANSACTION_removeDevicesRoleForCapturePreset:
1374 case TRANSACTION_clearDevicesRoleForCapturePreset:
Eric Laurent81dd0f52021-07-05 11:54:40 +02001375 case TRANSACTION_getDevicesForRoleAndCapturePreset:
jiabina84c3d32022-12-02 18:59:55 +00001376 case TRANSACTION_getSpatializer:
1377 case TRANSACTION_setPreferredMixerAttributes:
1378 case TRANSACTION_clearPreferredMixerAttributes: {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001379 if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
1380 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
1381 __func__, code, IPCThreadState::self()->getCallingPid(),
1382 IPCThreadState::self()->getCallingUid());
1383 return INVALID_OPERATION;
1384 }
1385 } break;
1386 default:
1387 break;
1388 }
1389
Andy Hungc747c532022-03-07 21:41:14 -08001390 const std::string methodName = getIAudioPolicyServiceStatistics().getMethodForCode(code);
1391 mediautils::TimeCheck check(
1392 std::string("IAudioPolicyService::").append(methodName),
1393 [code, methodName](bool timeout, float elapsedMs) { // don't move methodName.
1394 if (timeout) {
1395 mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_POLICY)
1396 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_TIMEOUT)
1397 .set(AMEDIAMETRICS_PROP_METHODCODE, int64_t(code))
1398 .set(AMEDIAMETRICS_PROP_METHODNAME, methodName.c_str())
1399 .record();
1400 } else {
1401 getIAudioPolicyServiceStatistics().event(code, elapsedMs);
1402 }
Andy Hung741b3dd2022-06-13 19:49:43 -07001403 }, mediautils::TimeCheck::kDefaultTimeoutDuration,
1404 mediautils::TimeCheck::kDefaultSecondChanceDuration,
1405 true /* crashOnTimeout */);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001406
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001407 switch (code) {
1408 case SHELL_COMMAND_TRANSACTION: {
1409 int in = data.readFileDescriptor();
1410 int out = data.readFileDescriptor();
1411 int err = data.readFileDescriptor();
1412 int argc = data.readInt32();
1413 Vector<String16> args;
1414 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1415 args.add(data.readString16());
1416 }
1417 sp<IBinder> unusedCallback;
1418 sp<IResultReceiver> resultReceiver;
1419 status_t status;
1420 if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1421 return status;
1422 }
1423 if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1424 return status;
1425 }
1426 status = shellCommand(in, out, err, args);
1427 if (resultReceiver != nullptr) {
1428 resultReceiver->send(status);
1429 }
1430 return NO_ERROR;
1431 }
1432 }
1433
Mathias Agopian65ab4712010-07-14 17:59:35 -07001434 return BnAudioPolicyService::onTransact(code, data, reply, flags);
1435}
1436
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001437// ------------------- Shell command implementation -------------------
1438
1439// NOTE: This is a remote API - make sure all args are validated
1440status_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
1441 if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
1442 return PERMISSION_DENIED;
1443 }
1444 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
1445 return BAD_VALUE;
1446 }
jovanakbe066e12019-09-02 11:54:39 -07001447 if (args.size() >= 3 && args[0] == String16("set-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001448 return handleSetUidState(args, err);
jovanakbe066e12019-09-02 11:54:39 -07001449 } else if (args.size() >= 2 && args[0] == String16("reset-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001450 return handleResetUidState(args, err);
jovanakbe066e12019-09-02 11:54:39 -07001451 } else if (args.size() >= 2 && args[0] == String16("get-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001452 return handleGetUidState(args, out, err);
Eric Laurent269acb42021-04-23 16:53:22 +02001453 } else if (args.size() >= 1 && args[0] == String16("purge_permission-cache")) {
1454 purgePermissionCache();
1455 return NO_ERROR;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001456 } else if (args.size() == 1 && args[0] == String16("help")) {
1457 printHelp(out);
1458 return NO_ERROR;
1459 }
1460 printHelp(err);
1461 return BAD_VALUE;
1462}
1463
jovanakbe066e12019-09-02 11:54:39 -07001464static status_t getUidForPackage(String16 packageName, int userId, /*inout*/uid_t& uid, int err) {
1465 if (userId < 0) {
1466 ALOGE("Invalid user: %d", userId);
1467 dprintf(err, "Invalid user: %d\n", userId);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001468 return BAD_VALUE;
1469 }
jovanakbe066e12019-09-02 11:54:39 -07001470
1471 PermissionController pc;
1472 uid = pc.getPackageUid(packageName, 0);
1473 if (uid <= 0) {
1474 ALOGE("Unknown package: '%s'", String8(packageName).string());
1475 dprintf(err, "Unknown package: '%s'\n", String8(packageName).string());
1476 return BAD_VALUE;
1477 }
1478
1479 uid = multiuser_get_uid(userId, uid);
1480 return NO_ERROR;
1481}
1482
1483status_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) {
1484 // Valid arg.size() is 3 or 5, args.size() is 5 with --user option.
1485 if (!(args.size() == 3 || args.size() == 5)) {
1486 printHelp(err);
1487 return BAD_VALUE;
1488 }
1489
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001490 bool active = false;
1491 if (args[2] == String16("active")) {
1492 active = true;
1493 } else if ((args[2] != String16("idle"))) {
1494 ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
1495 return BAD_VALUE;
1496 }
jovanakbe066e12019-09-02 11:54:39 -07001497
1498 int userId = 0;
1499 if (args.size() >= 5 && args[3] == String16("--user")) {
1500 userId = atoi(String8(args[4]));
1501 }
1502
1503 uid_t uid;
1504 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1505 return BAD_VALUE;
1506 }
1507
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001508 sp<UidPolicy> uidPolicy;
1509 {
1510 Mutex::Autolock _l(mLock);
1511 uidPolicy = mUidPolicy;
1512 }
1513 if (uidPolicy) {
1514 uidPolicy->addOverrideUid(uid, active);
1515 return NO_ERROR;
1516 }
1517 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001518}
1519
1520status_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) {
jovanakbe066e12019-09-02 11:54:39 -07001521 // Valid arg.size() is 2 or 4, args.size() is 4 with --user option.
1522 if (!(args.size() == 2 || args.size() == 4)) {
1523 printHelp(err);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001524 return BAD_VALUE;
1525 }
jovanakbe066e12019-09-02 11:54:39 -07001526
1527 int userId = 0;
1528 if (args.size() >= 4 && args[2] == String16("--user")) {
1529 userId = atoi(String8(args[3]));
1530 }
1531
1532 uid_t uid;
1533 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1534 return BAD_VALUE;
1535 }
1536
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001537 sp<UidPolicy> uidPolicy;
1538 {
1539 Mutex::Autolock _l(mLock);
1540 uidPolicy = mUidPolicy;
1541 }
1542 if (uidPolicy) {
1543 uidPolicy->removeOverrideUid(uid);
1544 return NO_ERROR;
1545 }
1546 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001547}
1548
1549status_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) {
jovanakbe066e12019-09-02 11:54:39 -07001550 // Valid arg.size() is 2 or 4, args.size() is 4 with --user option.
1551 if (!(args.size() == 2 || args.size() == 4)) {
1552 printHelp(err);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001553 return BAD_VALUE;
1554 }
jovanakbe066e12019-09-02 11:54:39 -07001555
1556 int userId = 0;
1557 if (args.size() >= 4 && args[2] == String16("--user")) {
1558 userId = atoi(String8(args[3]));
1559 }
1560
1561 uid_t uid;
1562 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1563 return BAD_VALUE;
1564 }
1565
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001566 sp<UidPolicy> uidPolicy;
1567 {
1568 Mutex::Autolock _l(mLock);
1569 uidPolicy = mUidPolicy;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001570 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001571 if (uidPolicy) {
1572 return dprintf(out, uidPolicy->isUidActive(uid) ? "active\n" : "idle\n");
1573 }
1574 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001575}
1576
1577status_t AudioPolicyService::printHelp(int out) {
1578 return dprintf(out, "Audio policy service commands:\n"
jovanakbe066e12019-09-02 11:54:39 -07001579 " get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
1580 " set-uid-state <PACKAGE> <active|idle> [--user USER_ID] overrides the uid state\n"
1581 " reset-uid-state <PACKAGE> [--user USER_ID] clears the uid state override\n"
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001582 " help print this message\n");
1583}
1584
Eric Laurent0d13fea2022-11-04 17:12:08 +01001585status_t AudioPolicyService::registerOutput(audio_io_handle_t output,
1586 const audio_config_base_t& config,
1587 const audio_output_flags_t flags) {
1588 return mUsecaseValidator->registerStream(output, config, flags);
1589}
1590
1591status_t AudioPolicyService::unregisterOutput(audio_io_handle_t output) {
1592 return mUsecaseValidator->unregisterStream(output);
1593}
1594
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001595// ----------- AudioPolicyService::UidPolicy implementation ----------
1596
1597void AudioPolicyService::UidPolicy::registerSelf() {
Steven Moreland2f348142019-07-02 15:59:07 -07001598 status_t res = mAm.linkToDeath(this);
1599 mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001600 | ActivityManager::UID_OBSERVER_IDLE
Eric Laurente8c8b432018-10-17 10:08:02 -07001601 | ActivityManager::UID_OBSERVER_ACTIVE
1602 | ActivityManager::UID_OBSERVER_PROCSTATE,
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001603 ActivityManager::PROCESS_STATE_UNKNOWN,
1604 String16("audioserver"));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001605 if (!res) {
1606 Mutex::Autolock _l(mLock);
1607 mObserverRegistered = true;
1608 } else {
1609 ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
Eric Laurent4eb58f12018-12-07 16:41:02 -08001610
Steven Moreland2f348142019-07-02 15:59:07 -07001611 mAm.unregisterUidObserver(this);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001612 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001613}
1614
1615void AudioPolicyService::UidPolicy::unregisterSelf() {
Steven Moreland2f348142019-07-02 15:59:07 -07001616 mAm.unlinkToDeath(this);
1617 mAm.unregisterUidObserver(this);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001618 Mutex::Autolock _l(mLock);
1619 mObserverRegistered = false;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001620}
1621
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001622void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
1623 Mutex::Autolock _l(mLock);
1624 mCachedUids.clear();
1625 mObserverRegistered = false;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001626}
1627
Eric Laurente8c8b432018-10-17 10:08:02 -07001628void AudioPolicyService::UidPolicy::checkRegistered() {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001629 bool needToReregister = false;
1630 {
1631 Mutex::Autolock _l(mLock);
1632 needToReregister = !mObserverRegistered;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001633 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001634 if (needToReregister) {
1635 // Looks like ActivityManager has died previously, attempt to re-register.
1636 registerSelf();
1637 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001638}
1639
1640bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
1641 if (isServiceUid(uid)) return true;
1642 checkRegistered();
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001643 {
1644 Mutex::Autolock _l(mLock);
1645 auto overrideIter = mOverrideUids.find(uid);
1646 if (overrideIter != mOverrideUids.end()) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001647 return overrideIter->second.first;
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001648 }
1649 // In an absense of the ActivityManager, assume everything to be active.
1650 if (!mObserverRegistered) return true;
1651 auto cacheIter = mCachedUids.find(uid);
Mikhail Naganoveba668a2018-04-05 08:13:15 -07001652 if (cacheIter != mCachedUids.end()) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001653 return cacheIter->second.first;
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001654 }
1655 }
1656 ActivityManager am;
Hui Yu12c7ec72020-05-04 17:40:52 +00001657 bool active = am.isUidActive(uid, String16("audioserver"));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001658 {
1659 Mutex::Autolock _l(mLock);
Eric Laurente8c8b432018-10-17 10:08:02 -07001660 mCachedUids.insert(std::pair<uid_t,
1661 std::pair<bool, int>>(uid, std::pair<bool, int>(active,
1662 ActivityManager::PROCESS_STATE_UNKNOWN)));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001663 }
1664 return active;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001665}
1666
Eric Laurente8c8b432018-10-17 10:08:02 -07001667int AudioPolicyService::UidPolicy::getUidState(uid_t uid) {
1668 if (isServiceUid(uid)) {
1669 return ActivityManager::PROCESS_STATE_TOP;
1670 }
1671 checkRegistered();
1672 {
1673 Mutex::Autolock _l(mLock);
1674 auto overrideIter = mOverrideUids.find(uid);
1675 if (overrideIter != mOverrideUids.end()) {
1676 if (overrideIter->second.first) {
1677 if (overrideIter->second.second != ActivityManager::PROCESS_STATE_UNKNOWN) {
1678 return overrideIter->second.second;
1679 } else {
1680 auto cacheIter = mCachedUids.find(uid);
1681 if (cacheIter != mCachedUids.end()) {
1682 return cacheIter->second.second;
1683 }
1684 }
1685 }
1686 return ActivityManager::PROCESS_STATE_UNKNOWN;
1687 }
1688 // In an absense of the ActivityManager, assume everything to be active.
1689 if (!mObserverRegistered) {
1690 return ActivityManager::PROCESS_STATE_TOP;
1691 }
1692 auto cacheIter = mCachedUids.find(uid);
1693 if (cacheIter != mCachedUids.end()) {
1694 if (cacheIter->second.first) {
1695 return cacheIter->second.second;
1696 } else {
1697 return ActivityManager::PROCESS_STATE_UNKNOWN;
1698 }
1699 }
1700 }
1701 ActivityManager am;
Hui Yu12c7ec72020-05-04 17:40:52 +00001702 bool active = am.isUidActive(uid, String16("audioserver"));
Eric Laurente8c8b432018-10-17 10:08:02 -07001703 int state = ActivityManager::PROCESS_STATE_UNKNOWN;
1704 if (active) {
1705 state = am.getUidProcessState(uid, String16("audioserver"));
1706 }
1707 {
1708 Mutex::Autolock _l(mLock);
1709 mCachedUids.insert(std::pair<uid_t,
1710 std::pair<bool, int>>(uid, std::pair<bool, int>(active, state)));
1711 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001712
Eric Laurente8c8b432018-10-17 10:08:02 -07001713 return state;
1714}
1715
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001716void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001717 updateUid(&mCachedUids, uid, true, ActivityManager::PROCESS_STATE_UNKNOWN, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001718}
1719
1720void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001721 updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, false);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001722}
1723
1724void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001725 updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001726}
1727
Eric Laurente8c8b432018-10-17 10:08:02 -07001728void AudioPolicyService::UidPolicy::onUidStateChanged(uid_t uid,
1729 int32_t procState,
Hui Yu13ad0eb2019-09-09 10:27:07 -07001730 int64_t procStateSeq __unused,
1731 int32_t capability __unused) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001732 if (procState != ActivityManager::PROCESS_STATE_UNKNOWN) {
1733 updateUid(&mCachedUids, uid, true, procState, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001734 }
1735}
1736
Austin Borgerdddb7552023-03-30 17:53:01 -07001737void AudioPolicyService::UidPolicy::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {
Austin Borger65577682022-02-17 00:25:43 +00001738}
1739
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001740void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001741 updateUid(&mOverrideUids, uid, active, ActivityManager::PROCESS_STATE_UNKNOWN, insert);
1742}
1743
1744void AudioPolicyService::UidPolicy::notifyService() {
1745 sp<AudioPolicyService> service = mService.promote();
1746 if (service != nullptr) {
1747 service->updateUidStates();
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001748 }
1749}
1750
Eric Laurente8c8b432018-10-17 10:08:02 -07001751void AudioPolicyService::UidPolicy::updateUid(std::unordered_map<uid_t,
1752 std::pair<bool, int>> *uids,
1753 uid_t uid,
1754 bool active,
1755 int state,
1756 bool insert) {
1757 if (isServiceUid(uid)) {
1758 return;
1759 }
1760 bool wasActive = isUidActive(uid);
1761 int previousState = getUidState(uid);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001762 {
1763 Mutex::Autolock _l(mLock);
Eric Laurente8c8b432018-10-17 10:08:02 -07001764 updateUidLocked(uids, uid, active, state, insert);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001765 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001766 if (wasActive != isUidActive(uid) || state != previousState) {
1767 notifyService();
1768 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001769}
1770
Eric Laurente8c8b432018-10-17 10:08:02 -07001771void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t,
1772 std::pair<bool, int>> *uids,
1773 uid_t uid,
1774 bool active,
1775 int state,
1776 bool insert) {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001777 auto it = uids->find(uid);
1778 if (it != uids->end()) {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001779 if (insert) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001780 if (state == ActivityManager::PROCESS_STATE_UNKNOWN) {
1781 it->second.first = active;
1782 }
1783 if (it->second.first) {
1784 it->second.second = state;
1785 } else {
1786 it->second.second = ActivityManager::PROCESS_STATE_UNKNOWN;
1787 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001788 } else {
1789 uids->erase(it);
1790 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001791 } else if (insert && (state == ActivityManager::PROCESS_STATE_UNKNOWN)) {
1792 uids->insert(std::pair<uid_t, std::pair<bool, int>>(uid,
1793 std::pair<bool, int>(active, state)));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001794 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001795}
Mathias Agopian65ab4712010-07-14 17:59:35 -07001796
Eric Laurent4eb58f12018-12-07 16:41:02 -08001797bool AudioPolicyService::UidPolicy::isA11yOnTop() {
lihong80e1f56e2022-08-25 11:15:33 +08001798 Mutex::Autolock _l(mLock);
Eric Laurent4eb58f12018-12-07 16:41:02 -08001799 for (const auto &uid : mCachedUids) {
Eric Laurent47670c92019-08-28 16:59:05 -07001800 if (!isA11yUid(uid.first)) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001801 continue;
1802 }
Amith Yamasanibcbb3002019-01-23 13:53:33 -08001803 if (uid.second.second >= ActivityManager::PROCESS_STATE_TOP
1804 && uid.second.second <= ActivityManager::PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001805 return true;
1806 }
1807 }
1808 return false;
1809}
1810
Eric Laurentb78763e2018-10-17 10:08:02 -07001811bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
1812{
1813 std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid);
1814 return it != mA11yUids.end();
1815}
1816
Oscar Azucena829d90d2022-01-28 17:17:56 -08001817void AudioPolicyService::UidPolicy::setAssistantUids(const std::vector<uid_t>& uids) {
1818 mAssistantUids.clear();
1819 mAssistantUids = uids;
1820}
1821
1822bool AudioPolicyService::UidPolicy::isAssistantUid(uid_t uid)
1823{
1824 std::vector<uid_t>::iterator it = find(mAssistantUids.begin(), mAssistantUids.end(), uid);
1825 return it != mAssistantUids.end();
1826}
1827
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001828void AudioPolicyService::UidPolicy::setActiveAssistantUids(const std::vector<uid_t>& activeUids) {
1829 mActiveAssistantUids = activeUids;
1830}
1831
1832bool AudioPolicyService::UidPolicy::isActiveAssistantUid(uid_t uid)
1833{
1834 std::vector<uid_t>::iterator it = find(mActiveAssistantUids.begin(),
1835 mActiveAssistantUids.end(), uid);
1836 return it != mActiveAssistantUids.end();
1837}
1838
Oscar Azucena829d90d2022-01-28 17:17:56 -08001839void AudioPolicyService::UidPolicy::dumpInternals(int fd) {
1840 const size_t SIZE = 256;
1841 char buffer[SIZE];
1842 String8 result;
1843 auto appendUidsToResult = [&](const char* title, const std::vector<uid_t> &uids) {
1844 snprintf(buffer, SIZE, "\t%s: \n", title);
1845 result.append(buffer);
1846 int counter = 0;
1847 if (uids.empty()) {
1848 snprintf(buffer, SIZE, "\t\tNo UIDs present.\n");
1849 result.append(buffer);
1850 return;
1851 }
1852 for (const auto &uid : uids) {
1853 snprintf(buffer, SIZE, "\t\tUID[%d]=%d\n", counter++, uid);
1854 result.append(buffer);
1855 }
1856 };
1857
1858 snprintf(buffer, SIZE, "UID Policy:\n");
1859 result.append(buffer);
1860 snprintf(buffer, SIZE, "\tmObserverRegistered=%s\n",(mObserverRegistered ? "True":"False"));
1861 result.append(buffer);
1862
1863 appendUidsToResult("Assistants UIDs", mAssistantUids);
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001864 appendUidsToResult("Active Assistants UIDs", mActiveAssistantUids);
Oscar Azucena829d90d2022-01-28 17:17:56 -08001865
1866 appendUidsToResult("Accessibility UIDs", mA11yUids);
1867
1868 snprintf(buffer, SIZE, "\tInput Method Service UID=%d\n", mCurrentImeUid);
1869 result.append(buffer);
1870
1871 snprintf(buffer, SIZE, "\tIs RTT Enabled: %s\n", (mRttEnabled ? "True":"False"));
1872 result.append(buffer);
1873
1874 write(fd, result.string(), result.size());
1875}
1876
Michael Groovercfd28302018-12-11 19:16:46 -08001877// ----------- AudioPolicyService::SensorPrivacyService implementation ----------
1878void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
1879 SensorPrivacyManager spm;
1880 mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
1881 spm.addSensorPrivacyListener(this);
1882}
1883
1884void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
1885 SensorPrivacyManager spm;
1886 spm.removeSensorPrivacyListener(this);
1887}
1888
1889bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
1890 return mSensorPrivacyEnabled;
1891}
1892
Evan Seversond8dc6832022-01-27 10:47:03 -08001893binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(
1894 int toggleType __unused, int sensor __unused, bool enabled) {
Michael Groovercfd28302018-12-11 19:16:46 -08001895 mSensorPrivacyEnabled = enabled;
1896 sp<AudioPolicyService> service = mService.promote();
1897 if (service != nullptr) {
1898 service->updateUidStates();
1899 }
1900 return binder::Status::ok();
1901}
1902
Eric Laurented726cc2021-07-01 14:26:41 +02001903// ----------- AudioPolicyService::OpRecordAudioMonitor implementation ----------
1904
1905// static
1906sp<AudioPolicyService::OpRecordAudioMonitor>
1907AudioPolicyService::OpRecordAudioMonitor::createIfNeeded(
1908 const AttributionSourceState& attributionSource, const audio_attributes_t& attr,
1909 wp<AudioCommandThread> commandThread)
1910{
Eric Laurent987ce102021-07-05 12:11:51 +02001911 if (isAudioServerOrRootUid(attributionSource.uid)) {
1912 ALOGV("not silencing record for audio or root source %s",
Eric Laurented726cc2021-07-01 14:26:41 +02001913 attributionSource.toString().c_str());
1914 return nullptr;
1915 }
1916
1917 if (!AudioPolicyService::isAppOpSource(attr.source)) {
1918 ALOGD("not monitoring app op for uid %d and source %d",
1919 attributionSource.uid, attr.source);
1920 return nullptr;
1921 }
1922
1923 if (!attributionSource.packageName.has_value()
1924 || attributionSource.packageName.value().size() == 0) {
1925 return nullptr;
1926 }
1927 return new OpRecordAudioMonitor(attributionSource, getOpForSource(attr.source), commandThread);
1928}
1929
1930AudioPolicyService::OpRecordAudioMonitor::OpRecordAudioMonitor(
1931 const AttributionSourceState& attributionSource, int32_t appOp,
1932 wp<AudioCommandThread> commandThread) :
1933 mHasOp(true), mAttributionSource(attributionSource), mAppOp(appOp),
1934 mCommandThread(commandThread)
1935{
1936}
1937
1938AudioPolicyService::OpRecordAudioMonitor::~OpRecordAudioMonitor()
1939{
1940 if (mOpCallback != 0) {
1941 mAppOpsManager.stopWatchingMode(mOpCallback);
1942 }
1943 mOpCallback.clear();
1944}
1945
1946void AudioPolicyService::OpRecordAudioMonitor::onFirstRef()
1947{
1948 checkOp();
1949 mOpCallback = new RecordAudioOpCallback(this);
1950 ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
Atneya Nairdc4f3752023-08-09 16:21:48 -07001951 int flags = doesPackageTargetAtLeastU(
1952 mAttributionSource.packageName.value_or("")) ?
1953 AppOpsManager::WATCH_FOREGROUND_CHANGES : 0;
Eric Laurented726cc2021-07-01 14:26:41 +02001954 // TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
1955 // since it controls the mic permission for legacy apps.
1956 mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
1957 mAttributionSource.packageName.value_or(""))),
Atneya Nairdc4f3752023-08-09 16:21:48 -07001958 flags,
Eric Laurented726cc2021-07-01 14:26:41 +02001959 mOpCallback);
1960}
1961
1962bool AudioPolicyService::OpRecordAudioMonitor::hasOp() const {
1963 return mHasOp.load();
1964}
1965
1966// Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
1967// is updated in AppOp callback and in onFirstRef()
1968// Note this method is never called (and never to be) for audio server / root track
1969// due to the UID in createIfNeeded(). As a result for those record track, it's:
1970// - not called from constructor,
1971// - not called from RecordAudioOpCallback because the callback is not installed in this case
1972void AudioPolicyService::OpRecordAudioMonitor::checkOp(bool updateUidStates)
1973{
1974 // TODO: We need to always check AppOpsManager::OP_RECORD_AUDIO too
1975 // since it controls the mic permission for legacy apps.
1976 const int32_t mode = mAppOpsManager.checkOp(mAppOp,
1977 mAttributionSource.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
1978 mAttributionSource.packageName.value_or(""))));
1979 const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
1980 // verbose logging only log when appOp changed
1981 ALOGI_IF(hasIt != mHasOp.load(),
1982 "App op %d missing, %ssilencing record %s",
1983 mAppOp, hasIt ? "un" : "", mAttributionSource.toString().c_str());
1984 mHasOp.store(hasIt);
1985
1986 if (updateUidStates) {
1987 sp<AudioCommandThread> commandThread = mCommandThread.promote();
1988 if (commandThread != nullptr) {
1989 commandThread->updateUidStatesCommand();
1990 }
1991 }
1992}
1993
1994AudioPolicyService::OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
1995 const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
1996{ }
1997
1998void AudioPolicyService::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
1999 const String16& packageName __unused) {
2000 sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
2001 if (monitor != NULL) {
2002 if (op != monitor->getOp()) {
2003 return;
2004 }
2005 monitor->checkOp(true);
2006 }
2007}
2008
2009
Mathias Agopian65ab4712010-07-14 17:59:35 -07002010// ----------- AudioPolicyService::AudioCommandThread implementation ----------
2011
Eric Laurentbfb1b832013-01-07 09:53:42 -08002012AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
2013 const wp<AudioPolicyService>& service)
2014 : Thread(false), mName(name), mService(service)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002015{
Mathias Agopian65ab4712010-07-14 17:59:35 -07002016}
2017
2018
2019AudioPolicyService::AudioCommandThread::~AudioCommandThread()
2020{
Eric Laurentbfb1b832013-01-07 09:53:42 -08002021 if (!mAudioCommands.isEmpty()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002022 release_wake_lock(mName.string());
2023 }
2024 mAudioCommands.clear();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002025}
2026
2027void AudioPolicyService::AudioCommandThread::onFirstRef()
2028{
Eric Laurentbfb1b832013-01-07 09:53:42 -08002029 run(mName.string(), ANDROID_PRIORITY_AUDIO);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002030}
2031
2032bool AudioPolicyService::AudioCommandThread::threadLoop()
2033{
Eric Laurentd7eda8d2016-02-02 17:18:39 -08002034 nsecs_t waitTime = -1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002035
2036 mLock.lock();
2037 while (!exitPending())
2038 {
Eric Laurent59a89232014-06-08 14:14:17 -07002039 sp<AudioPolicyService> svc;
Ytai Ben-Tsvi6958b022022-04-26 15:45:53 -07002040 int numTimesBecameEmpty = 0;
Eric Laurent59a89232014-06-08 14:14:17 -07002041 while (!mAudioCommands.isEmpty() && !exitPending()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002042 nsecs_t curTime = systemTime();
2043 // commands are sorted by increasing time stamp: execute them from index 0 and up
2044 if (mAudioCommands[0]->mTime <= curTime) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002045 sp<AudioCommand> command = mAudioCommands[0];
Mathias Agopian65ab4712010-07-14 17:59:35 -07002046 mAudioCommands.removeAt(0);
Ytai Ben-Tsvi6958b022022-04-26 15:45:53 -07002047 if (mAudioCommands.isEmpty()) {
2048 ++numTimesBecameEmpty;
2049 }
Eric Laurent0ede8922014-05-09 18:04:42 -07002050 mLastCommand = command;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002051
2052 switch (command->mCommand) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002053 case SET_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002054 VolumeData *data = (VolumeData *)command->mParam.get();
Steve Block3856b092011-10-20 11:56:00 +01002055 ALOGV("AudioCommandThread() processing set volume stream %d, \
Eric Laurentde070132010-07-13 04:45:46 -07002056 volume %f, output %d", data->mStream, data->mVolume, data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07002057 mLock.unlock();
Eric Laurentde070132010-07-13 04:45:46 -07002058 command->mStatus = AudioSystem::setStreamVolume(data->mStream,
2059 data->mVolume,
2060 data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07002061 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002062 }break;
2063 case SET_PARAMETERS: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002064 ParametersData *data = (ParametersData *)command->mParam.get();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002065 ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
2066 data->mKeyValuePairs.string(), data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07002067 mLock.unlock();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002068 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
Andy Hungfe726a62018-09-27 15:17:25 -07002069 mLock.lock();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002070 }break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002071 case SET_VOICE_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002072 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
Steve Block3856b092011-10-20 11:56:00 +01002073 ALOGV("AudioCommandThread() processing set voice volume volume %f",
Eric Laurentde070132010-07-13 04:45:46 -07002074 data->mVolume);
Andy Hungfe726a62018-09-27 15:17:25 -07002075 mLock.unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002076 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
Andy Hungfe726a62018-09-27 15:17:25 -07002077 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002078 }break;
Eric Laurentbfb1b832013-01-07 09:53:42 -08002079 case STOP_OUTPUT: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002080 StopOutputData *data = (StopOutputData *)command->mParam.get();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002081 ALOGV("AudioCommandThread() processing stop output portId %d",
2082 data->mPortId);
Eric Laurent59a89232014-06-08 14:14:17 -07002083 svc = mService.promote();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002084 if (svc == 0) {
2085 break;
2086 }
2087 mLock.unlock();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002088 svc->doStopOutput(data->mPortId);
Eric Laurentbfb1b832013-01-07 09:53:42 -08002089 mLock.lock();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002090 }break;
2091 case RELEASE_OUTPUT: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002092 ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002093 ALOGV("AudioCommandThread() processing release output portId %d",
2094 data->mPortId);
Eric Laurent59a89232014-06-08 14:14:17 -07002095 svc = mService.promote();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002096 if (svc == 0) {
2097 break;
2098 }
2099 mLock.unlock();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002100 svc->doReleaseOutput(data->mPortId);
Eric Laurentbfb1b832013-01-07 09:53:42 -08002101 mLock.lock();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002102 }break;
Eric Laurent951f4552014-05-20 10:48:17 -07002103 case CREATE_AUDIO_PATCH: {
2104 CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
2105 ALOGV("AudioCommandThread() processing create audio patch");
2106 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
2107 if (af == 0) {
2108 command->mStatus = PERMISSION_DENIED;
2109 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07002110 mLock.unlock();
Eric Laurent951f4552014-05-20 10:48:17 -07002111 command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
Andy Hungfe726a62018-09-27 15:17:25 -07002112 mLock.lock();
Eric Laurent951f4552014-05-20 10:48:17 -07002113 }
2114 } break;
2115 case RELEASE_AUDIO_PATCH: {
2116 ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
2117 ALOGV("AudioCommandThread() processing release audio patch");
2118 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
2119 if (af == 0) {
2120 command->mStatus = PERMISSION_DENIED;
2121 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07002122 mLock.unlock();
Eric Laurent951f4552014-05-20 10:48:17 -07002123 command->mStatus = af->releaseAudioPatch(data->mHandle);
Andy Hungfe726a62018-09-27 15:17:25 -07002124 mLock.lock();
Eric Laurent951f4552014-05-20 10:48:17 -07002125 }
2126 } break;
Eric Laurentb52c1522014-05-20 11:27:36 -07002127 case UPDATE_AUDIOPORT_LIST: {
2128 ALOGV("AudioCommandThread() processing update audio port list");
Eric Laurent59a89232014-06-08 14:14:17 -07002129 svc = mService.promote();
Eric Laurentb52c1522014-05-20 11:27:36 -07002130 if (svc == 0) {
2131 break;
2132 }
2133 mLock.unlock();
2134 svc->doOnAudioPortListUpdate();
2135 mLock.lock();
2136 }break;
2137 case UPDATE_AUDIOPATCH_LIST: {
2138 ALOGV("AudioCommandThread() processing update audio patch list");
Eric Laurent59a89232014-06-08 14:14:17 -07002139 svc = mService.promote();
Eric Laurentb52c1522014-05-20 11:27:36 -07002140 if (svc == 0) {
2141 break;
2142 }
2143 mLock.unlock();
2144 svc->doOnAudioPatchListUpdate();
2145 mLock.lock();
2146 }break;
François Gaffiecfe17322018-11-07 13:41:29 +01002147 case CHANGED_AUDIOVOLUMEGROUP: {
2148 AudioVolumeGroupData *data =
2149 static_cast<AudioVolumeGroupData *>(command->mParam.get());
2150 ALOGV("AudioCommandThread() processing update audio volume group");
2151 svc = mService.promote();
2152 if (svc == 0) {
2153 break;
2154 }
2155 mLock.unlock();
2156 svc->doOnAudioVolumeGroupChanged(data->mGroup, data->mFlags);
2157 mLock.lock();
2158 }break;
Eric Laurente1715a42014-05-20 11:30:42 -07002159 case SET_AUDIOPORT_CONFIG: {
2160 SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
2161 ALOGV("AudioCommandThread() processing set port config");
2162 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
2163 if (af == 0) {
2164 command->mStatus = PERMISSION_DENIED;
2165 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07002166 mLock.unlock();
Eric Laurente1715a42014-05-20 11:30:42 -07002167 command->mStatus = af->setAudioPortConfig(&data->mConfig);
Andy Hungfe726a62018-09-27 15:17:25 -07002168 mLock.lock();
Eric Laurente1715a42014-05-20 11:30:42 -07002169 }
2170 } break;
Jean-Michel Trivide801052015-04-14 19:10:14 -07002171 case DYN_POLICY_MIX_STATE_UPDATE: {
2172 DynPolicyMixStateUpdateData *data =
2173 (DynPolicyMixStateUpdateData *)command->mParam.get();
Jean-Michel Trivide801052015-04-14 19:10:14 -07002174 ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
2175 data->mRegId.string(), data->mState);
2176 svc = mService.promote();
2177 if (svc == 0) {
2178 break;
2179 }
2180 mLock.unlock();
2181 svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
2182 mLock.lock();
2183 } break;
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002184 case RECORDING_CONFIGURATION_UPDATE: {
2185 RecordingConfigurationUpdateData *data =
2186 (RecordingConfigurationUpdateData *)command->mParam.get();
2187 ALOGV("AudioCommandThread() processing recording configuration update");
2188 svc = mService.promote();
2189 if (svc == 0) {
2190 break;
2191 }
2192 mLock.unlock();
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002193 svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -08002194 &data->mClientConfig, data->mClientEffects,
2195 &data->mDeviceConfig, data->mEffects,
2196 data->mPatchHandle, data->mSource);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002197 mLock.lock();
2198 } break;
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002199 case SET_EFFECT_SUSPENDED: {
2200 SetEffectSuspendedData *data = (SetEffectSuspendedData *)command->mParam.get();
2201 ALOGV("AudioCommandThread() processing set effect suspended");
2202 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
2203 if (af != 0) {
2204 mLock.unlock();
2205 af->setEffectSuspended(data->mEffectId, data->mSessionId, data->mSuspended);
2206 mLock.lock();
2207 }
2208 } break;
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002209 case AUDIO_MODULES_UPDATE: {
2210 ALOGV("AudioCommandThread() processing audio modules update");
2211 svc = mService.promote();
2212 if (svc == 0) {
2213 break;
2214 }
2215 mLock.unlock();
2216 svc->doOnNewAudioModulesAvailable();
2217 mLock.lock();
2218 } break;
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002219 case ROUTING_UPDATED: {
2220 ALOGV("AudioCommandThread() processing routing update");
2221 svc = mService.promote();
2222 if (svc == 0) {
2223 break;
2224 }
2225 mLock.unlock();
2226 svc->doOnRoutingUpdated();
2227 mLock.lock();
2228 } break;
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002229
Eric Laurented726cc2021-07-01 14:26:41 +02002230 case UPDATE_UID_STATES: {
2231 ALOGV("AudioCommandThread() processing updateUID states");
2232 svc = mService.promote();
2233 if (svc == 0) {
2234 break;
2235 }
2236 mLock.unlock();
2237 svc->updateUidStates();
2238 mLock.lock();
2239 } break;
2240
Eric Laurent15903592022-02-24 20:44:36 +01002241 case CHECK_SPATIALIZER_OUTPUT: {
2242 ALOGV("AudioCommandThread() processing check spatializer");
Eric Laurent81dd0f52021-07-05 11:54:40 +02002243 svc = mService.promote();
2244 if (svc == 0) {
2245 break;
2246 }
2247 mLock.unlock();
2248 svc->doOnCheckSpatializer();
2249 mLock.lock();
2250 } break;
2251
Eric Laurent15903592022-02-24 20:44:36 +01002252 case UPDATE_ACTIVE_SPATIALIZER_TRACKS: {
2253 ALOGV("AudioCommandThread() processing update spatializer tracks");
2254 svc = mService.promote();
2255 if (svc == 0) {
2256 break;
2257 }
2258 mLock.unlock();
2259 svc->doOnUpdateActiveSpatializerTracks();
2260 mLock.lock();
2261 } break;
2262
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +00002263 case VOL_RANGE_INIT_REQUEST: {
2264 ALOGV("AudioCommandThread() processing volume range init request");
2265 svc = mService.promote();
2266 if (svc == 0) {
2267 break;
2268 }
2269 mLock.unlock();
2270 svc->doOnVolumeRangeInitRequest();
2271 mLock.lock();
2272 } break;
2273
Mathias Agopian65ab4712010-07-14 17:59:35 -07002274 default:
Steve Block5ff1dd52012-01-05 23:22:43 +00002275 ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002276 }
Eric Laurent0ede8922014-05-09 18:04:42 -07002277 {
2278 Mutex::Autolock _l(command->mLock);
2279 if (command->mWaitStatus) {
2280 command->mWaitStatus = false;
2281 command->mCond.signal();
2282 }
2283 }
Eric Laurentd7eda8d2016-02-02 17:18:39 -08002284 waitTime = -1;
Zach Janga754b4f2015-10-27 01:29:34 +00002285 // release mLock before releasing strong reference on the service as
2286 // AudioPolicyService destructor calls AudioCommandThread::exit() which
2287 // acquires mLock.
2288 mLock.unlock();
2289 svc.clear();
2290 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002291 } else {
2292 waitTime = mAudioCommands[0]->mTime - curTime;
2293 break;
2294 }
2295 }
Zach Janga754b4f2015-10-27 01:29:34 +00002296
Ytai Ben-Tsvi6958b022022-04-26 15:45:53 -07002297 // release delayed commands wake lock as many times as we made the queue is
2298 // empty during popping.
2299 while (numTimesBecameEmpty--) {
Ricardo Garcia05f2fdc2014-07-24 15:48:24 -07002300 release_wake_lock(mName.string());
Zach Janga754b4f2015-10-27 01:29:34 +00002301 }
2302
2303 // At this stage we have either an empty command queue or the first command in the queue
2304 // has a finite delay. So unless we are exiting it is safe to wait.
2305 if (!exitPending()) {
Eric Laurent59a89232014-06-08 14:14:17 -07002306 ALOGV("AudioCommandThread() going to sleep");
Eric Laurentd7eda8d2016-02-02 17:18:39 -08002307 if (waitTime == -1) {
2308 mWaitWorkCV.wait(mLock);
2309 } else {
2310 mWaitWorkCV.waitRelative(mLock, waitTime);
2311 }
Eric Laurent59a89232014-06-08 14:14:17 -07002312 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002313 }
Ricardo Garcia05f2fdc2014-07-24 15:48:24 -07002314 // release delayed commands wake lock before quitting
2315 if (!mAudioCommands.isEmpty()) {
2316 release_wake_lock(mName.string());
2317 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002318 mLock.unlock();
2319 return false;
2320}
2321
2322status_t AudioPolicyService::AudioCommandThread::dump(int fd)
2323{
2324 const size_t SIZE = 256;
2325 char buffer[SIZE];
2326 String8 result;
2327
Mikhail Naganov12b716c2020-04-30 22:37:43 +00002328 const bool locked = dumpTryLock(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002329 if (!locked) {
2330 String8 result2(kCmdDeadlockedString);
2331 write(fd, result2.string(), result2.size());
2332 }
2333
2334 snprintf(buffer, SIZE, "- Commands:\n");
2335 result = String8(buffer);
2336 result.append(" Command Time Wait pParam\n");
Glenn Kasten8d6a2442012-02-08 14:04:28 -08002337 for (size_t i = 0; i < mAudioCommands.size(); i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002338 mAudioCommands[i]->dump(buffer, SIZE);
2339 result.append(buffer);
2340 }
2341 result.append(" Last Command\n");
Eric Laurent0ede8922014-05-09 18:04:42 -07002342 if (mLastCommand != 0) {
2343 mLastCommand->dump(buffer, SIZE);
2344 result.append(buffer);
2345 } else {
2346 result.append(" none\n");
2347 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002348
2349 write(fd, result.string(), result.size());
2350
Mikhail Naganov12b716c2020-04-30 22:37:43 +00002351 dumpReleaseLock(mLock, locked);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002352
2353 return NO_ERROR;
2354}
2355
Glenn Kastenfff6d712012-01-12 16:38:12 -08002356status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
Eric Laurentde070132010-07-13 04:45:46 -07002357 float volume,
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002358 audio_io_handle_t output,
Eric Laurentde070132010-07-13 04:45:46 -07002359 int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002360{
Eric Laurent0ede8922014-05-09 18:04:42 -07002361 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002362 command->mCommand = SET_VOLUME;
Eric Laurent0ede8922014-05-09 18:04:42 -07002363 sp<VolumeData> data = new VolumeData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002364 data->mStream = stream;
2365 data->mVolume = volume;
2366 data->mIO = output;
2367 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07002368 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01002369 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
Eric Laurentde070132010-07-13 04:45:46 -07002370 stream, volume, output);
Eric Laurent0ede8922014-05-09 18:04:42 -07002371 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002372}
2373
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002374status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
Dima Zavinfce7a472011-04-19 22:30:36 -07002375 const char *keyValuePairs,
Eric Laurentde070132010-07-13 04:45:46 -07002376 int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002377{
Eric Laurent0ede8922014-05-09 18:04:42 -07002378 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002379 command->mCommand = SET_PARAMETERS;
Eric Laurent0ede8922014-05-09 18:04:42 -07002380 sp<ParametersData> data = new ParametersData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002381 data->mIO = ioHandle;
Dima Zavinfce7a472011-04-19 22:30:36 -07002382 data->mKeyValuePairs = String8(keyValuePairs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002383 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07002384 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01002385 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
Dima Zavinfce7a472011-04-19 22:30:36 -07002386 keyValuePairs, ioHandle, delayMs);
Eric Laurent0ede8922014-05-09 18:04:42 -07002387 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002388}
2389
2390status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
2391{
Eric Laurent0ede8922014-05-09 18:04:42 -07002392 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002393 command->mCommand = SET_VOICE_VOLUME;
Eric Laurent0ede8922014-05-09 18:04:42 -07002394 sp<VoiceVolumeData> data = new VoiceVolumeData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002395 data->mVolume = volume;
2396 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07002397 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01002398 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
Eric Laurent0ede8922014-05-09 18:04:42 -07002399 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002400}
2401
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002402void AudioPolicyService::AudioCommandThread::setEffectSuspendedCommand(int effectId,
2403 audio_session_t sessionId,
2404 bool suspended)
2405{
2406 sp<AudioCommand> command = new AudioCommand();
2407 command->mCommand = SET_EFFECT_SUSPENDED;
2408 sp<SetEffectSuspendedData> data = new SetEffectSuspendedData();
2409 data->mEffectId = effectId;
2410 data->mSessionId = sessionId;
2411 data->mSuspended = suspended;
2412 command->mParam = data;
2413 ALOGV("AudioCommandThread() adding set suspended effectId %d sessionId %d suspended %d",
2414 effectId, sessionId, suspended);
2415 sendCommand(command);
2416}
2417
2418
Eric Laurentd7fe0862018-07-14 16:48:01 -07002419void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_port_handle_t portId)
Eric Laurentbfb1b832013-01-07 09:53:42 -08002420{
Eric Laurent0ede8922014-05-09 18:04:42 -07002421 sp<AudioCommand> command = new AudioCommand();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002422 command->mCommand = STOP_OUTPUT;
Eric Laurent0ede8922014-05-09 18:04:42 -07002423 sp<StopOutputData> data = new StopOutputData();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002424 data->mPortId = portId;
Jesper Tragardh48412dc2014-03-24 14:12:43 +01002425 command->mParam = data;
Eric Laurentd7fe0862018-07-14 16:48:01 -07002426 ALOGV("AudioCommandThread() adding stop output portId %d", portId);
Eric Laurent0ede8922014-05-09 18:04:42 -07002427 sendCommand(command);
Eric Laurentbfb1b832013-01-07 09:53:42 -08002428}
2429
Eric Laurentd7fe0862018-07-14 16:48:01 -07002430void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_port_handle_t portId)
Eric Laurentbfb1b832013-01-07 09:53:42 -08002431{
Eric Laurent0ede8922014-05-09 18:04:42 -07002432 sp<AudioCommand> command = new AudioCommand();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002433 command->mCommand = RELEASE_OUTPUT;
Eric Laurent0ede8922014-05-09 18:04:42 -07002434 sp<ReleaseOutputData> data = new ReleaseOutputData();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002435 data->mPortId = portId;
Jesper Tragardh48412dc2014-03-24 14:12:43 +01002436 command->mParam = data;
Eric Laurentd7fe0862018-07-14 16:48:01 -07002437 ALOGV("AudioCommandThread() adding release output portId %d", portId);
Eric Laurent0ede8922014-05-09 18:04:42 -07002438 sendCommand(command);
2439}
2440
Eric Laurent951f4552014-05-20 10:48:17 -07002441status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
2442 const struct audio_patch *patch,
2443 audio_patch_handle_t *handle,
2444 int delayMs)
2445{
2446 status_t status = NO_ERROR;
2447
2448 sp<AudioCommand> command = new AudioCommand();
2449 command->mCommand = CREATE_AUDIO_PATCH;
2450 CreateAudioPatchData *data = new CreateAudioPatchData();
2451 data->mPatch = *patch;
2452 data->mHandle = *handle;
2453 command->mParam = data;
2454 command->mWaitStatus = true;
2455 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
2456 status = sendCommand(command, delayMs);
2457 if (status == NO_ERROR) {
2458 *handle = data->mHandle;
2459 }
2460 return status;
2461}
2462
2463status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
2464 int delayMs)
2465{
2466 sp<AudioCommand> command = new AudioCommand();
2467 command->mCommand = RELEASE_AUDIO_PATCH;
2468 ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
2469 data->mHandle = handle;
2470 command->mParam = data;
2471 command->mWaitStatus = true;
2472 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
2473 return sendCommand(command, delayMs);
2474}
2475
Eric Laurentb52c1522014-05-20 11:27:36 -07002476void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
2477{
2478 sp<AudioCommand> command = new AudioCommand();
2479 command->mCommand = UPDATE_AUDIOPORT_LIST;
2480 ALOGV("AudioCommandThread() adding update audio port list");
2481 sendCommand(command);
2482}
2483
Eric Laurented726cc2021-07-01 14:26:41 +02002484void AudioPolicyService::AudioCommandThread::updateUidStatesCommand()
2485{
2486 sp<AudioCommand> command = new AudioCommand();
2487 command->mCommand = UPDATE_UID_STATES;
2488 ALOGV("AudioCommandThread() adding update UID states");
2489 sendCommand(command);
2490}
2491
Eric Laurentb52c1522014-05-20 11:27:36 -07002492void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
2493{
2494 sp<AudioCommand>command = new AudioCommand();
2495 command->mCommand = UPDATE_AUDIOPATCH_LIST;
2496 ALOGV("AudioCommandThread() adding update audio patch list");
2497 sendCommand(command);
2498}
2499
François Gaffiecfe17322018-11-07 13:41:29 +01002500void AudioPolicyService::AudioCommandThread::changeAudioVolumeGroupCommand(volume_group_t group,
2501 int flags)
2502{
2503 sp<AudioCommand>command = new AudioCommand();
2504 command->mCommand = CHANGED_AUDIOVOLUMEGROUP;
2505 AudioVolumeGroupData *data= new AudioVolumeGroupData();
2506 data->mGroup = group;
2507 data->mFlags = flags;
2508 command->mParam = data;
2509 ALOGV("AudioCommandThread() adding audio volume group changed");
2510 sendCommand(command);
2511}
2512
Eric Laurente1715a42014-05-20 11:30:42 -07002513status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
2514 const struct audio_port_config *config, int delayMs)
2515{
2516 sp<AudioCommand> command = new AudioCommand();
2517 command->mCommand = SET_AUDIOPORT_CONFIG;
2518 SetAudioPortConfigData *data = new SetAudioPortConfigData();
2519 data->mConfig = *config;
2520 command->mParam = data;
2521 command->mWaitStatus = true;
2522 ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
2523 return sendCommand(command, delayMs);
2524}
2525
Jean-Michel Trivide801052015-04-14 19:10:14 -07002526void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07002527 const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -07002528{
2529 sp<AudioCommand> command = new AudioCommand();
2530 command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
2531 DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
2532 data->mRegId = regId;
2533 data->mState = state;
2534 command->mParam = data;
2535 ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
2536 regId.string(), state);
2537 sendCommand(command);
2538}
2539
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002540void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
Eric Laurenta9f86652018-11-28 17:23:11 -08002541 int event,
2542 const record_client_info_t *clientInfo,
2543 const audio_config_base_t *clientConfig,
2544 std::vector<effect_descriptor_t> clientEffects,
2545 const audio_config_base_t *deviceConfig,
2546 std::vector<effect_descriptor_t> effects,
2547 audio_patch_handle_t patchHandle,
2548 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002549{
2550 sp<AudioCommand>command = new AudioCommand();
2551 command->mCommand = RECORDING_CONFIGURATION_UPDATE;
2552 RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
2553 data->mEvent = event;
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002554 data->mClientInfo = *clientInfo;
Jean-Michel Trivi7281aa92016-02-17 15:33:40 -08002555 data->mClientConfig = *clientConfig;
Eric Laurenta9f86652018-11-28 17:23:11 -08002556 data->mClientEffects = clientEffects;
Jean-Michel Trivi7281aa92016-02-17 15:33:40 -08002557 data->mDeviceConfig = *deviceConfig;
Eric Laurenta9f86652018-11-28 17:23:11 -08002558 data->mEffects = effects;
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08002559 data->mPatchHandle = patchHandle;
Eric Laurenta9f86652018-11-28 17:23:11 -08002560 data->mSource = source;
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002561 command->mParam = data;
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002562 ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
2563 event, clientInfo->source, clientInfo->uid);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002564 sendCommand(command);
2565}
2566
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002567void AudioPolicyService::AudioCommandThread::audioModulesUpdateCommand()
2568{
2569 sp<AudioCommand> command = new AudioCommand();
2570 command->mCommand = AUDIO_MODULES_UPDATE;
2571 sendCommand(command);
2572}
2573
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002574void AudioPolicyService::AudioCommandThread::routingChangedCommand()
2575{
2576 sp<AudioCommand>command = new AudioCommand();
2577 command->mCommand = ROUTING_UPDATED;
2578 ALOGV("AudioCommandThread() adding routing update");
2579 sendCommand(command);
2580}
2581
Eric Laurent81dd0f52021-07-05 11:54:40 +02002582void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
2583{
2584 sp<AudioCommand>command = new AudioCommand();
Eric Laurent15903592022-02-24 20:44:36 +01002585 command->mCommand = CHECK_SPATIALIZER_OUTPUT;
Eric Laurent81dd0f52021-07-05 11:54:40 +02002586 ALOGV("AudioCommandThread() adding check spatializer");
2587 sendCommand(command);
2588}
2589
Eric Laurent15903592022-02-24 20:44:36 +01002590void AudioPolicyService::AudioCommandThread::updateActiveSpatializerTracksCommand()
2591{
2592 sp<AudioCommand>command = new AudioCommand();
2593 command->mCommand = UPDATE_ACTIVE_SPATIALIZER_TRACKS;
2594 ALOGV("AudioCommandThread() adding update active spatializer tracks");
2595 sendCommand(command);
2596}
2597
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +00002598void AudioPolicyService::AudioCommandThread::volRangeInitReqCommand()
2599{
2600 sp<AudioCommand>command = new AudioCommand();
2601 command->mCommand = VOL_RANGE_INIT_REQUEST;
2602 ALOGV("AudioCommandThread() adding volume range init request");
2603 sendCommand(command);
2604}
2605
Eric Laurent0ede8922014-05-09 18:04:42 -07002606status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
2607{
2608 {
2609 Mutex::Autolock _l(mLock);
2610 insertCommand_l(command, delayMs);
2611 mWaitWorkCV.signal();
2612 }
2613 Mutex::Autolock _l(command->mLock);
2614 while (command->mWaitStatus) {
2615 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
2616 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
2617 command->mStatus = TIMED_OUT;
2618 command->mWaitStatus = false;
2619 }
2620 }
2621 return command->mStatus;
Eric Laurentbfb1b832013-01-07 09:53:42 -08002622}
2623
Mathias Agopian65ab4712010-07-14 17:59:35 -07002624// insertCommand_l() must be called with mLock held
Eric Laurent0ede8922014-05-09 18:04:42 -07002625void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002626{
Glenn Kasten8d6a2442012-02-08 14:04:28 -08002627 ssize_t i; // not size_t because i will count down to -1
Eric Laurent0ede8922014-05-09 18:04:42 -07002628 Vector < sp<AudioCommand> > removedCommands;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002629 command->mTime = systemTime() + milliseconds(delayMs);
2630
2631 // acquire wake lock to make sure delayed commands are processed
Eric Laurentbfb1b832013-01-07 09:53:42 -08002632 if (mAudioCommands.isEmpty()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002633 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
2634 }
2635
2636 // check same pending commands with later time stamps and eliminate them
Ivan Lozano5ff158f2017-10-30 09:06:24 -07002637 for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002638 sp<AudioCommand> command2 = mAudioCommands[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07002639 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
2640 if (command2->mTime <= command->mTime) break;
Eric Laurente45b48a2014-09-04 16:40:57 -07002641
2642 // create audio patch or release audio patch commands are equivalent
2643 // with regard to filtering
2644 if ((command->mCommand == CREATE_AUDIO_PATCH) ||
2645 (command->mCommand == RELEASE_AUDIO_PATCH)) {
2646 if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
2647 (command2->mCommand != RELEASE_AUDIO_PATCH)) {
2648 continue;
2649 }
2650 } else if (command2->mCommand != command->mCommand) continue;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002651
2652 switch (command->mCommand) {
2653 case SET_PARAMETERS: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002654 ParametersData *data = (ParametersData *)command->mParam.get();
2655 ParametersData *data2 = (ParametersData *)command2->mParam.get();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002656 if (data->mIO != data2->mIO) break;
Steve Block3856b092011-10-20 11:56:00 +01002657 ALOGV("Comparing parameter command %s to new command %s",
Eric Laurentde070132010-07-13 04:45:46 -07002658 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002659 AudioParameter param = AudioParameter(data->mKeyValuePairs);
2660 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
2661 for (size_t j = 0; j < param.size(); j++) {
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002662 String8 key;
2663 String8 value;
2664 param.getAt(j, key, value);
2665 for (size_t k = 0; k < param2.size(); k++) {
2666 String8 key2;
2667 String8 value2;
2668 param2.getAt(k, key2, value2);
2669 if (key2 == key) {
2670 param2.remove(key2);
2671 ALOGV("Filtering out parameter %s", key2.string());
2672 break;
2673 }
2674 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002675 }
2676 // if all keys have been filtered out, remove the command.
2677 // otherwise, update the key value pairs
2678 if (param2.size() == 0) {
2679 removedCommands.add(command2);
2680 } else {
2681 data2->mKeyValuePairs = param2.toString();
2682 }
Eric Laurent21e54562013-09-23 12:08:05 -07002683 command->mTime = command2->mTime;
2684 // force delayMs to non 0 so that code below does not request to wait for
2685 // command status as the command is now delayed
2686 delayMs = 1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002687 } break;
2688
2689 case SET_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002690 VolumeData *data = (VolumeData *)command->mParam.get();
2691 VolumeData *data2 = (VolumeData *)command2->mParam.get();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002692 if (data->mIO != data2->mIO) break;
2693 if (data->mStream != data2->mStream) break;
Steve Block3856b092011-10-20 11:56:00 +01002694 ALOGV("Filtering out volume command on output %d for stream %d",
Eric Laurentde070132010-07-13 04:45:46 -07002695 data->mIO, data->mStream);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002696 removedCommands.add(command2);
Eric Laurent21e54562013-09-23 12:08:05 -07002697 command->mTime = command2->mTime;
2698 // force delayMs to non 0 so that code below does not request to wait for
2699 // command status as the command is now delayed
2700 delayMs = 1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002701 } break;
Eric Laurente45b48a2014-09-04 16:40:57 -07002702
Eric Laurentbaf35fe2016-07-27 15:36:53 -07002703 case SET_VOICE_VOLUME: {
2704 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
2705 VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
2706 ALOGV("Filtering out voice volume command value %f replaced by %f",
2707 data2->mVolume, data->mVolume);
2708 removedCommands.add(command2);
2709 command->mTime = command2->mTime;
2710 // force delayMs to non 0 so that code below does not request to wait for
2711 // command status as the command is now delayed
2712 delayMs = 1;
2713 } break;
2714
Eric Laurente45b48a2014-09-04 16:40:57 -07002715 case CREATE_AUDIO_PATCH:
2716 case RELEASE_AUDIO_PATCH: {
2717 audio_patch_handle_t handle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002718 struct audio_patch patch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002719 if (command->mCommand == CREATE_AUDIO_PATCH) {
2720 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002721 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002722 } else {
2723 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
Mikhail Naganov7be71d22018-05-23 16:51:46 -07002724 memset(&patch, 0, sizeof(patch));
Eric Laurente45b48a2014-09-04 16:40:57 -07002725 }
2726 audio_patch_handle_t handle2;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002727 struct audio_patch patch2;
Eric Laurente45b48a2014-09-04 16:40:57 -07002728 if (command2->mCommand == CREATE_AUDIO_PATCH) {
2729 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002730 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002731 } else {
2732 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
Glenn Kastenf60b6b62015-07-06 10:53:26 -07002733 memset(&patch2, 0, sizeof(patch2));
Eric Laurente45b48a2014-09-04 16:40:57 -07002734 }
2735 if (handle != handle2) break;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002736 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
2737 same output. */
2738 if( (command->mCommand == CREATE_AUDIO_PATCH) &&
2739 (command2->mCommand == CREATE_AUDIO_PATCH) ) {
2740 bool isOutputDiff = false;
2741 if (patch.num_sources == patch2.num_sources) {
2742 for (unsigned count = 0; count < patch.num_sources; count++) {
2743 if (patch.sources[count].id != patch2.sources[count].id) {
2744 isOutputDiff = true;
2745 break;
2746 }
2747 }
2748 if (isOutputDiff)
2749 break;
2750 }
2751 }
Eric Laurente45b48a2014-09-04 16:40:57 -07002752 ALOGV("Filtering out %s audio patch command for handle %d",
2753 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
2754 removedCommands.add(command2);
2755 command->mTime = command2->mTime;
2756 // force delayMs to non 0 so that code below does not request to wait for
2757 // command status as the command is now delayed
2758 delayMs = 1;
2759 } break;
2760
Jean-Michel Trivide801052015-04-14 19:10:14 -07002761 case DYN_POLICY_MIX_STATE_UPDATE: {
2762
2763 } break;
2764
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002765 case RECORDING_CONFIGURATION_UPDATE: {
2766
2767 } break;
2768
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002769 case ROUTING_UPDATED: {
2770
2771 } break;
2772
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +00002773 case VOL_RANGE_INIT_REQUEST: {
2774 // command may come from different requests, do not filter
2775 } break;
2776
Mathias Agopian65ab4712010-07-14 17:59:35 -07002777 default:
2778 break;
2779 }
2780 }
2781
2782 // remove filtered commands
2783 for (size_t j = 0; j < removedCommands.size(); j++) {
2784 // removed commands always have time stamps greater than current command
2785 for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002786 if (mAudioCommands[k].get() == removedCommands[j].get()) {
Steve Block3856b092011-10-20 11:56:00 +01002787 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002788 mAudioCommands.removeAt(k);
2789 break;
2790 }
2791 }
2792 }
2793 removedCommands.clear();
2794
Eric Laurentaa79bef2015-01-15 14:33:51 -08002795 // Disable wait for status if delay is not 0.
2796 // Except for create audio patch command because the returned patch handle
2797 // is needed by audio policy manager
2798 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
Eric Laurentcec4abb2012-07-03 12:23:02 -07002799 command->mWaitStatus = false;
2800 }
Eric Laurentcec4abb2012-07-03 12:23:02 -07002801
Mathias Agopian65ab4712010-07-14 17:59:35 -07002802 // insert command at the right place according to its time stamp
Eric Laurent1e693b52014-07-09 15:03:28 -07002803 ALOGV("inserting command: %d at index %zd, num commands %zu",
2804 command->mCommand, i+1, mAudioCommands.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002805 mAudioCommands.insertAt(command, i + 1);
2806}
2807
2808void AudioPolicyService::AudioCommandThread::exit()
2809{
Steve Block3856b092011-10-20 11:56:00 +01002810 ALOGV("AudioCommandThread::exit");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002811 {
2812 AutoMutex _l(mLock);
2813 requestExit();
2814 mWaitWorkCV.signal();
2815 }
Zach Janga754b4f2015-10-27 01:29:34 +00002816 // Note that we can call it from the thread loop if all other references have been released
2817 // but it will safely return WOULD_BLOCK in this case
Mathias Agopian65ab4712010-07-14 17:59:35 -07002818 requestExitAndWait();
2819}
2820
2821void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
2822{
2823 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n",
2824 mCommand,
2825 (int)ns2s(mTime),
2826 (int)ns2ms(mTime)%1000,
2827 mWaitStatus,
Eric Laurent0ede8922014-05-09 18:04:42 -07002828 mParam.get());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002829}
2830
Dima Zavinfce7a472011-04-19 22:30:36 -07002831/******* helpers for the service_ops callbacks defined below *********/
2832void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
2833 const char *keyValuePairs,
2834 int delayMs)
2835{
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002836 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
Dima Zavinfce7a472011-04-19 22:30:36 -07002837 delayMs);
2838}
2839
2840int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
2841 float volume,
2842 audio_io_handle_t output,
2843 int delayMs)
2844{
Glenn Kastenfff6d712012-01-12 16:38:12 -08002845 return (int)mAudioCommandThread->volumeCommand(stream, volume,
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002846 output, delayMs);
Dima Zavinfce7a472011-04-19 22:30:36 -07002847}
2848
Dima Zavinfce7a472011-04-19 22:30:36 -07002849int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
2850{
2851 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
2852}
2853
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002854void AudioPolicyService::setEffectSuspended(int effectId,
2855 audio_session_t sessionId,
2856 bool suspended)
2857{
2858 mAudioCommandThread->setEffectSuspendedCommand(effectId, sessionId, suspended);
2859}
2860
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08002861Status AudioPolicyService::onNewAudioModulesAvailable()
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002862{
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002863 mOutputCommandThread->audioModulesUpdateCommand();
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08002864 return Status::ok();
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002865}
2866
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002867
Dima Zavinfce7a472011-04-19 22:30:36 -07002868extern "C" {
Eric Laurent2d388ec2014-03-07 13:25:54 -08002869audio_module_handle_t aps_load_hw_module(void *service __unused,
2870 const char *name);
2871audio_io_handle_t aps_open_output(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002872 audio_devices_t *pDevices,
2873 uint32_t *pSamplingRate,
2874 audio_format_t *pFormat,
2875 audio_channel_mask_t *pChannelMask,
2876 uint32_t *pLatencyMs,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002877 audio_output_flags_t flags);
Eric Laurenta4c5a552012-03-29 10:12:40 -07002878
Eric Laurent2d388ec2014-03-07 13:25:54 -08002879audio_io_handle_t aps_open_output_on_module(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002880 audio_module_handle_t module,
2881 audio_devices_t *pDevices,
2882 uint32_t *pSamplingRate,
2883 audio_format_t *pFormat,
2884 audio_channel_mask_t *pChannelMask,
2885 uint32_t *pLatencyMs,
Richard Fitzgeraldad3af332013-03-25 16:54:37 +00002886 audio_output_flags_t flags,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002887 const audio_offload_info_t *offloadInfo);
2888audio_io_handle_t aps_open_dup_output(void *service __unused,
Dima Zavinfce7a472011-04-19 22:30:36 -07002889 audio_io_handle_t output1,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002890 audio_io_handle_t output2);
2891int aps_close_output(void *service __unused, audio_io_handle_t output);
2892int aps_suspend_output(void *service __unused, audio_io_handle_t output);
2893int aps_restore_output(void *service __unused, audio_io_handle_t output);
2894audio_io_handle_t aps_open_input(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002895 audio_devices_t *pDevices,
2896 uint32_t *pSamplingRate,
2897 audio_format_t *pFormat,
2898 audio_channel_mask_t *pChannelMask,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002899 audio_in_acoustics_t acoustics __unused);
2900audio_io_handle_t aps_open_input_on_module(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002901 audio_module_handle_t module,
2902 audio_devices_t *pDevices,
2903 uint32_t *pSamplingRate,
2904 audio_format_t *pFormat,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002905 audio_channel_mask_t *pChannelMask);
2906int aps_close_input(void *service __unused, audio_io_handle_t input);
2907int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
Glenn Kastend848eb42016-03-08 13:42:11 -08002908int aps_move_effects(void *service __unused, audio_session_t session,
Dima Zavinfce7a472011-04-19 22:30:36 -07002909 audio_io_handle_t src_output,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002910 audio_io_handle_t dst_output);
2911char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
2912 const char *keys);
2913void aps_set_parameters(void *service, audio_io_handle_t io_handle,
2914 const char *kv_pairs, int delay_ms);
2915int aps_set_stream_volume(void *service, audio_stream_type_t stream,
Dima Zavinfce7a472011-04-19 22:30:36 -07002916 float volume, audio_io_handle_t output,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002917 int delay_ms);
Eric Laurent2d388ec2014-03-07 13:25:54 -08002918int aps_set_voice_volume(void *service, float volume, int delay_ms);
2919};
Dima Zavinfce7a472011-04-19 22:30:36 -07002920
Mikhail Naganov1b2a7942017-12-08 10:18:09 -08002921} // namespace android