blob: aa2b6f51daa4502dc6d612e7ba01f0ba80ee47e1 [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
28#include <audio_utils/clock.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070029#include <binder/IServiceManager.h>
30#include <utils/Log.h>
31#include <cutils/properties.h>
32#include <binder/IPCThreadState.h>
Svet Ganovf4ddfef2018-01-16 07:37:58 -080033#include <binder/PermissionController.h>
34#include <binder/IResultReceiver.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070035#include <utils/String16.h>
36#include <utils/threads.h>
Atneya Nair5b1ed642023-06-23 14:43:37 -070037#include "AudioRecordClient.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070038#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) \
Jan Sebechlebsky0af8e872023-08-11 14:45:08 +0200123BINDER_METHOD_ENTRY(updatePolicyMixes) \
Andy Hungc747c532022-03-07 21:41:14 -0800124BINDER_METHOD_ENTRY(setUidDeviceAffinities) \
125BINDER_METHOD_ENTRY(removeUidDeviceAffinities) \
126BINDER_METHOD_ENTRY(setUserIdDeviceAffinities) \
127BINDER_METHOD_ENTRY(removeUserIdDeviceAffinities) \
128BINDER_METHOD_ENTRY(startAudioSource) \
129BINDER_METHOD_ENTRY(stopAudioSource) \
130BINDER_METHOD_ENTRY(setMasterMono) \
131BINDER_METHOD_ENTRY(getMasterMono) \
132BINDER_METHOD_ENTRY(getStreamVolumeDB) \
133BINDER_METHOD_ENTRY(getSurroundFormats) \
134BINDER_METHOD_ENTRY(getReportedSurroundFormats) \
135BINDER_METHOD_ENTRY(getHwOffloadFormatsSupportedForBluetoothMedia) \
136BINDER_METHOD_ENTRY(setSurroundFormatEnabled) \
137BINDER_METHOD_ENTRY(setAssistantServicesUids) \
138BINDER_METHOD_ENTRY(setActiveAssistantServicesUids) \
139BINDER_METHOD_ENTRY(setA11yServicesUids) \
140BINDER_METHOD_ENTRY(setCurrentImeUid) \
141BINDER_METHOD_ENTRY(isHapticPlaybackSupported) \
142BINDER_METHOD_ENTRY(isUltrasoundSupported) \
Atneya Nair698f5ef2022-12-15 16:15:09 -0800143BINDER_METHOD_ENTRY(isHotwordStreamSupported) \
Andy Hungc747c532022-03-07 21:41:14 -0800144BINDER_METHOD_ENTRY(listAudioProductStrategies) \
145BINDER_METHOD_ENTRY(getProductStrategyFromAudioAttributes) \
146BINDER_METHOD_ENTRY(listAudioVolumeGroups) \
147BINDER_METHOD_ENTRY(getVolumeGroupFromAudioAttributes) \
148BINDER_METHOD_ENTRY(setRttEnabled) \
149BINDER_METHOD_ENTRY(isCallScreenModeSupported) \
150BINDER_METHOD_ENTRY(setDevicesRoleForStrategy) \
151BINDER_METHOD_ENTRY(removeDevicesRoleForStrategy) \
Paul Wang5d7cdb52022-11-22 09:45:06 +0000152BINDER_METHOD_ENTRY(clearDevicesRoleForStrategy) \
Andy Hungc747c532022-03-07 21:41:14 -0800153BINDER_METHOD_ENTRY(getDevicesForRoleAndStrategy) \
154BINDER_METHOD_ENTRY(setDevicesRoleForCapturePreset) \
155BINDER_METHOD_ENTRY(addDevicesRoleForCapturePreset) \
156BINDER_METHOD_ENTRY(removeDevicesRoleForCapturePreset) \
157BINDER_METHOD_ENTRY(clearDevicesRoleForCapturePreset) \
158BINDER_METHOD_ENTRY(getDevicesForRoleAndCapturePreset) \
159BINDER_METHOD_ENTRY(registerSoundTriggerCaptureStateListener) \
160BINDER_METHOD_ENTRY(getSpatializer) \
161BINDER_METHOD_ENTRY(canBeSpatialized) \
162BINDER_METHOD_ENTRY(getDirectPlaybackSupport) \
jiabina84c3d32022-12-02 18:59:55 +0000163BINDER_METHOD_ENTRY(getDirectProfilesForAttributes) \
164BINDER_METHOD_ENTRY(getSupportedMixerAttributes) \
165BINDER_METHOD_ENTRY(setPreferredMixerAttributes) \
166BINDER_METHOD_ENTRY(getPreferredMixerAttributes) \
167BINDER_METHOD_ENTRY(clearPreferredMixerAttributes) \
Andy Hungc747c532022-03-07 21:41:14 -0800168
169// singleton for Binder Method Statistics for IAudioPolicyService
170static auto& getIAudioPolicyServiceStatistics() {
171 using Code = int;
172
173#pragma push_macro("BINDER_METHOD_ENTRY")
174#undef BINDER_METHOD_ENTRY
175#define BINDER_METHOD_ENTRY(ENTRY) \
176 {(Code)media::BnAudioPolicyService::TRANSACTION_##ENTRY, #ENTRY},
177
178 static mediautils::MethodStatistics<Code> methodStatistics{
179 IAUDIOPOLICYSERVICE_BINDER_METHOD_MACRO_LIST
180 METHOD_STATISTICS_BINDER_CODE_NAMES(Code)
181 };
182#pragma pop_macro("BINDER_METHOD_ENTRY")
183
184 return methodStatistics;
185}
186
Mathias Agopian65ab4712010-07-14 17:59:35 -0700187// ----------------------------------------------------------------------------
188
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530189static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
190{
Mikhail Naganov9e459d72023-05-05 17:36:39 -0700191 AudioPolicyManager *apm = nullptr;
192 media::AudioPolicyConfig apmConfig;
193 if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
194 auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
195 LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix() !=
196 AudioPolicyConfig::kDefaultEngineLibraryNameSuffix,
197 "Only default engine is currently supported with the AIDL HAL");
198 apm = new AudioPolicyManager(config,
199 loadApmEngineLibraryAndCreateEngine(
200 config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
201 clientInterface);
202 } else {
203 auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This can't fail.
204 apm = new AudioPolicyManager(config,
205 loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
206 clientInterface);
207 }
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530208 status_t status = apm->initialize();
209 if (status != NO_ERROR) {
210 delete apm;
211 apm = nullptr;
212 }
213 return apm;
214}
215
216static void destroyAudioPolicyManager(AudioPolicyInterface *interface)
217{
218 delete interface;
219}
220// ----------------------------------------------------------------------------
221
Mathias Agopian65ab4712010-07-14 17:59:35 -0700222AudioPolicyService::AudioPolicyService()
Ytai Ben-Tsvi85093d52020-03-26 09:41:15 -0700223 : BnAudioPolicyService(),
Ytai Ben-Tsvi85093d52020-03-26 09:41:15 -0700224 mAudioPolicyManager(NULL),
225 mAudioPolicyClient(NULL),
226 mPhoneState(AUDIO_MODE_INVALID),
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530227 mCaptureStateNotifier(false),
228 mCreateAudioPolicyManager(createAudioPolicyManager),
Eric Laurent0d13fea2022-11-04 17:12:08 +0100229 mDestroyAudioPolicyManager(destroyAudioPolicyManager),
230 mUsecaseValidator(media::createUsecaseValidator()) {
Andy Hung225aef62022-12-06 16:33:20 -0800231 setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530232}
233
234void AudioPolicyService::loadAudioPolicyManager()
235{
236 mLibraryHandle = dlopen(kAudioPolicyManagerCustomPath, RTLD_NOW);
237 if (mLibraryHandle != nullptr) {
238 ALOGI("%s loading %s", __func__, kAudioPolicyManagerCustomPath);
239 mCreateAudioPolicyManager = reinterpret_cast<CreateAudioPolicyManagerInstance>
240 (dlsym(mLibraryHandle, "createAudioPolicyManager"));
241 const char *lastError = dlerror();
242 ALOGW_IF(mCreateAudioPolicyManager == nullptr, "%s createAudioPolicyManager is null %s",
243 __func__, lastError != nullptr ? lastError : "no error");
244
245 mDestroyAudioPolicyManager = reinterpret_cast<DestroyAudioPolicyManagerInstance>(
246 dlsym(mLibraryHandle, "destroyAudioPolicyManager"));
247 lastError = dlerror();
248 ALOGW_IF(mDestroyAudioPolicyManager == nullptr, "%s destroyAudioPolicyManager is null %s",
249 __func__, lastError != nullptr ? lastError : "no error");
250 if (mCreateAudioPolicyManager == nullptr || mDestroyAudioPolicyManager == nullptr){
251 unloadAudioPolicyManager();
252 LOG_ALWAYS_FATAL("could not find audiopolicymanager interface methods");
253 }
254 }
Eric Laurentf5ada6e2014-10-09 17:49:00 -0700255}
256
257void AudioPolicyService::onFirstRef()
258{
Andy Hungd47aca22022-03-15 11:50:51 -0700259 // Log an AudioPolicy "constructor" mediametrics event on first ref.
260 // This records the time it takes to load the audio modules and devices.
261 mediametrics::Defer defer([beginNs = systemTime()] {
262 mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_POLICY)
263 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR)
264 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
265 .record(); });
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700266 {
267 Mutex::Autolock _l(mLock);
Eric Laurent93575202011-01-18 18:39:02 -0800268
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700269 // start audio commands thread
270 mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
271 // start output activity command thread
272 mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
Eric Laurentdce54a12014-03-10 12:19:46 -0700273
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700274 mAudioPolicyClient = new AudioPolicyClient(this);
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530275
276 loadAudioPolicyManager();
277 mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700278 }
Eric Laurentd66d7a12021-07-13 13:35:32 +0200279
bryant_liuba2b4392014-06-11 16:49:30 +0800280 // load audio processing modules
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000281 const sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
282 sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects(effectsFactoryHal);
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000283 sp<UidPolicy> uidPolicy = new UidPolicy(this);
284 sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700285 {
286 Mutex::Autolock _l(mLock);
287 mAudioPolicyEffects = audioPolicyEffects;
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000288 mUidPolicy = uidPolicy;
289 mSensorPrivacyPolicy = sensorPrivacyPolicy;
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700290 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000291 uidPolicy->registerSelf();
292 sensorPrivacyPolicy->registerSelf();
Eric Laurentd66d7a12021-07-13 13:35:32 +0200293
Eric Laurent81dd0f52021-07-05 11:54:40 +0200294 // Create spatializer if supported
Eric Laurent52b0bd52021-09-27 15:25:40 +0200295 if (mAudioPolicyManager != nullptr) {
296 Mutex::Autolock _l(mLock);
297 const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
298 AudioDeviceTypeAddrVector devices;
299 bool hasSpatializer = mAudioPolicyManager->canBeSpatialized(&attr, nullptr, devices);
300 if (hasSpatializer) {
Shunkai Yao8d6489a2023-04-18 23:14:25 +0000301 mSpatializer = Spatializer::create(this, effectsFactoryHal);
Eric Laurent52b0bd52021-09-27 15:25:40 +0200302 }
Andy Hung8aa43c02022-09-13 18:53:06 -0700303 if (mSpatializer == nullptr) {
304 // No spatializer created, signal the reason: NO_INIT a failure, OK means intended.
305 const status_t createStatus = hasSpatializer ? NO_INIT : OK;
306 Spatializer::sendEmptyCreateSpatializerMetricWithStatus(createStatus);
307 }
Eric Laurent81dd0f52021-07-05 11:54:40 +0200308 }
Eric Laurentd66d7a12021-07-13 13:35:32 +0200309 AudioSystem::audioPolicyReady();
François Gaffie163ce832023-06-28 11:36:35 +0200310 // AudioFlinger will handle effect creation and register these effects on audio_policy
311 // service. Hence, audio_policy service must be ready.
312 audioPolicyEffects->setDefaultDeviceEffects();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700313}
314
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530315void AudioPolicyService::unloadAudioPolicyManager()
316{
317 ALOGV("%s ", __func__);
318 if (mLibraryHandle != nullptr) {
319 dlclose(mLibraryHandle);
320 }
321 mLibraryHandle = nullptr;
322 mCreateAudioPolicyManager = nullptr;
323 mDestroyAudioPolicyManager = nullptr;
324}
325
Mathias Agopian65ab4712010-07-14 17:59:35 -0700326AudioPolicyService::~AudioPolicyService()
327{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700328 mAudioCommandThread->exit();
Eric Laurent657ff612014-05-07 11:58:24 -0700329 mOutputCommandThread->exit();
Eric Laurent7c7f10b2011-06-17 21:29:58 -0700330
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530331 mDestroyAudioPolicyManager(mAudioPolicyManager);
332 unloadAudioPolicyManager();
333
Eric Laurentdce54a12014-03-10 12:19:46 -0700334 delete mAudioPolicyClient;
Eric Laurentb52c1522014-05-20 11:27:36 -0700335
336 mNotificationClients.clear();
bryant_liuba2b4392014-06-11 16:49:30 +0800337 mAudioPolicyEffects.clear();
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800338
339 mUidPolicy->unregisterSelf();
Michael Groovercfd28302018-12-11 19:16:46 -0800340 mSensorPrivacyPolicy->unregisterSelf();
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000341
342 mUidPolicy.clear();
Michael Groovercfd28302018-12-11 19:16:46 -0800343 mSensorPrivacyPolicy.clear();
Eric Laurentb52c1522014-05-20 11:27:36 -0700344}
345
346// A notification client is always registered by AudioSystem when the client process
347// connects to AudioPolicyService.
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800348Status AudioPolicyService::registerClient(const sp<media::IAudioPolicyServiceClient>& client)
Eric Laurentb52c1522014-05-20 11:27:36 -0700349{
Eric Laurent12590252015-08-21 18:40:20 -0700350 if (client == 0) {
351 ALOGW("%s got NULL client", __FUNCTION__);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800352 return Status::ok();
Eric Laurent12590252015-08-21 18:40:20 -0700353 }
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800354 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700355
356 uid_t uid = IPCThreadState::self()->getCallingUid();
luochaojiang908c7d72018-06-21 14:58:04 +0800357 pid_t pid = IPCThreadState::self()->getCallingPid();
358 int64_t token = ((int64_t)uid<<32) | pid;
359
360 if (mNotificationClients.indexOfKey(token) < 0) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700361 sp<NotificationClient> notificationClient = new NotificationClient(this,
362 client,
luochaojiang908c7d72018-06-21 14:58:04 +0800363 uid,
364 pid);
365 ALOGV("registerClient() client %p, uid %d pid %d", client.get(), uid, pid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700366
luochaojiang908c7d72018-06-21 14:58:04 +0800367 mNotificationClients.add(token, notificationClient);
Eric Laurentb52c1522014-05-20 11:27:36 -0700368
Marco Nelissenf8880202014-11-14 07:58:25 -0800369 sp<IBinder> binder = IInterface::asBinder(client);
Eric Laurentb52c1522014-05-20 11:27:36 -0700370 binder->linkToDeath(notificationClient);
371 }
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800372 return Status::ok();
Eric Laurentb52c1522014-05-20 11:27:36 -0700373}
374
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800375Status AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
Eric Laurente8726fe2015-06-26 09:39:24 -0700376{
377 Mutex::Autolock _l(mNotificationClientsLock);
378
379 uid_t uid = IPCThreadState::self()->getCallingUid();
luochaojiang908c7d72018-06-21 14:58:04 +0800380 pid_t pid = IPCThreadState::self()->getCallingPid();
381 int64_t token = ((int64_t)uid<<32) | pid;
382
383 if (mNotificationClients.indexOfKey(token) < 0) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800384 return Status::ok();
Eric Laurente8726fe2015-06-26 09:39:24 -0700385 }
luochaojiang908c7d72018-06-21 14:58:04 +0800386 mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800387 return Status::ok();
Eric Laurente8726fe2015-06-26 09:39:24 -0700388}
389
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800390Status AudioPolicyService::setAudioVolumeGroupCallbacksEnabled(bool enabled)
François Gaffiecfe17322018-11-07 13:41:29 +0100391{
392 Mutex::Autolock _l(mNotificationClientsLock);
393
394 uid_t uid = IPCThreadState::self()->getCallingUid();
395 pid_t pid = IPCThreadState::self()->getCallingPid();
396 int64_t token = ((int64_t)uid<<32) | pid;
397
398 if (mNotificationClients.indexOfKey(token) < 0) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800399 return Status::ok();
François Gaffiecfe17322018-11-07 13:41:29 +0100400 }
401 mNotificationClients.valueFor(token)->setAudioVolumeGroupCallbacksEnabled(enabled);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800402 return Status::ok();
François Gaffiecfe17322018-11-07 13:41:29 +0100403}
404
Eric Laurentb52c1522014-05-20 11:27:36 -0700405// removeNotificationClient() is called when the client process dies.
luochaojiang908c7d72018-06-21 14:58:04 +0800406void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
Eric Laurentb52c1522014-05-20 11:27:36 -0700407{
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000408 bool hasSameUid = false;
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800409 {
410 Mutex::Autolock _l(mNotificationClientsLock);
luochaojiang908c7d72018-06-21 14:58:04 +0800411 int64_t token = ((int64_t)uid<<32) | pid;
412 mNotificationClients.removeItem(token);
luochaojiang908c7d72018-06-21 14:58:04 +0800413 for (size_t i = 0; i < mNotificationClients.size(); i++) {
414 if (mNotificationClients.valueAt(i)->uid() == uid) {
415 hasSameUid = true;
416 break;
417 }
418 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000419 }
420 {
421 Mutex::Autolock _l(mLock);
luochaojiang908c7d72018-06-21 14:58:04 +0800422 if (mAudioPolicyManager && !hasSameUid) {
Eric Laurent10b71232018-04-13 18:14:44 -0700423 // called from binder death notification: no need to clear caller identity
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700424 mAudioPolicyManager->releaseResourcesForUid(uid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700425 }
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800426 }
Eric Laurentb52c1522014-05-20 11:27:36 -0700427}
428
429void AudioPolicyService::onAudioPortListUpdate()
430{
431 mOutputCommandThread->updateAudioPortListCommand();
432}
433
434void AudioPolicyService::doOnAudioPortListUpdate()
435{
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800436 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700437 for (size_t i = 0; i < mNotificationClients.size(); i++) {
438 mNotificationClients.valueAt(i)->onAudioPortListUpdate();
439 }
440}
441
442void AudioPolicyService::onAudioPatchListUpdate()
443{
444 mOutputCommandThread->updateAudioPatchListCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700445}
446
Eric Laurentb52c1522014-05-20 11:27:36 -0700447void AudioPolicyService::doOnAudioPatchListUpdate()
448{
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800449 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700450 for (size_t i = 0; i < mNotificationClients.size(); i++) {
451 mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
452 }
453}
454
François Gaffiecfe17322018-11-07 13:41:29 +0100455void AudioPolicyService::onAudioVolumeGroupChanged(volume_group_t group, int flags)
456{
457 mOutputCommandThread->changeAudioVolumeGroupCommand(group, flags);
458}
459
460void AudioPolicyService::doOnAudioVolumeGroupChanged(volume_group_t group, int flags)
461{
462 Mutex::Autolock _l(mNotificationClientsLock);
463 for (size_t i = 0; i < mNotificationClients.size(); i++) {
464 mNotificationClients.valueAt(i)->onAudioVolumeGroupChanged(group, flags);
465 }
466}
467
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700468void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700469{
470 ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +0000471 regId.c_str(), state);
Jean-Michel Trivide801052015-04-14 19:10:14 -0700472 mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
473}
474
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700475void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700476{
477 Mutex::Autolock _l(mNotificationClientsLock);
478 for (size_t i = 0; i < mNotificationClients.size(); i++) {
479 mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
480 }
481}
482
Eric Laurenta9f86652018-11-28 17:23:11 -0800483void AudioPolicyService::onRecordingConfigurationUpdate(
484 int event,
485 const record_client_info_t *clientInfo,
486 const audio_config_base_t *clientConfig,
487 std::vector<effect_descriptor_t> clientEffects,
488 const audio_config_base_t *deviceConfig,
489 std::vector<effect_descriptor_t> effects,
490 audio_patch_handle_t patchHandle,
491 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800492{
Jean-Michel Triviac4e4292016-12-22 11:39:31 -0800493 mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -0800494 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800495}
496
Eric Laurenta9f86652018-11-28 17:23:11 -0800497void AudioPolicyService::doOnRecordingConfigurationUpdate(
498 int event,
499 const record_client_info_t *clientInfo,
500 const audio_config_base_t *clientConfig,
501 std::vector<effect_descriptor_t> clientEffects,
502 const audio_config_base_t *deviceConfig,
503 std::vector<effect_descriptor_t> effects,
504 audio_patch_handle_t patchHandle,
505 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800506{
507 Mutex::Autolock _l(mNotificationClientsLock);
508 for (size_t i = 0; i < mNotificationClients.size(); i++) {
Jean-Michel Triviac4e4292016-12-22 11:39:31 -0800509 mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -0800510 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800511 }
512}
513
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700514void AudioPolicyService::onRoutingUpdated()
515{
516 mOutputCommandThread->routingChangedCommand();
517}
518
519void AudioPolicyService::doOnRoutingUpdated()
520{
521 Mutex::Autolock _l(mNotificationClientsLock);
522 for (size_t i = 0; i < mNotificationClients.size(); i++) {
523 mNotificationClients.valueAt(i)->onRoutingUpdated();
524 }
525}
526
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +0000527void AudioPolicyService::onVolumeRangeInitRequest()
528{
529 mOutputCommandThread->volRangeInitReqCommand();
530}
531
532void AudioPolicyService::doOnVolumeRangeInitRequest()
533{
534 Mutex::Autolock _l(mNotificationClientsLock);
535 for (size_t i = 0; i < mNotificationClients.size(); i++) {
536 mNotificationClients.valueAt(i)->onVolumeRangeInitRequest();
537 }
538}
539
Eric Laurent81dd0f52021-07-05 11:54:40 +0200540void AudioPolicyService::onCheckSpatializer()
541{
542 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200543 onCheckSpatializer_l();
544}
545
546void AudioPolicyService::onCheckSpatializer_l()
547{
548 if (mSpatializer != nullptr) {
549 mOutputCommandThread->checkSpatializerCommand();
550 }
Eric Laurent81dd0f52021-07-05 11:54:40 +0200551}
552
553void AudioPolicyService::doOnCheckSpatializer()
554{
Eric Laurentd6bee3a2022-08-31 16:07:50 +0200555 ALOGV("%s mSpatializer %p level %d",
556 __func__, mSpatializer.get(), (int)mSpatializer->getLevel());
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200557
Eric Laurent39095982021-08-24 18:29:27 +0200558 if (mSpatializer != nullptr) {
Eric Laurent52b0bd52021-09-27 15:25:40 +0200559 // Note: mSpatializer != nullptr => mAudioPolicyManager != nullptr
Eric Laurent39095982021-08-24 18:29:27 +0200560 if (mSpatializer->getLevel() != media::SpatializationLevel::NONE) {
561 audio_io_handle_t currentOutput = mSpatializer->getOutput();
562 audio_io_handle_t newOutput;
563 const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
564 audio_config_base_t config = mSpatializer->getAudioInConfig();
Eric Laurent21270b62022-07-04 15:11:29 +0200565
566 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200567 status_t status =
568 mAudioPolicyManager->getSpatializerOutput(&config, &attr, &newOutput);
Eric Laurentb4f42a92022-01-17 17:37:31 +0100569 ALOGV("%s currentOutput %d newOutput %d channel_mask %#x",
570 __func__, currentOutput, newOutput, config.channel_mask);
Eric Laurent39095982021-08-24 18:29:27 +0200571 if (status == NO_ERROR && currentOutput == newOutput) {
572 return;
573 }
Eric Laurent15903592022-02-24 20:44:36 +0100574 size_t numActiveTracks = countActiveClientsOnOutput_l(newOutput);
Eric Laurent39095982021-08-24 18:29:27 +0200575 mLock.unlock();
576 // It is OK to call detachOutput() is none is already attached.
577 mSpatializer->detachOutput();
Eric Laurent21270b62022-07-04 15:11:29 +0200578 if (status == NO_ERROR && newOutput != AUDIO_IO_HANDLE_NONE) {
579 status = mSpatializer->attachOutput(newOutput, numActiveTracks);
Eric Laurent39095982021-08-24 18:29:27 +0200580 }
Eric Laurent39095982021-08-24 18:29:27 +0200581 mLock.lock();
582 if (status != NO_ERROR) {
583 mAudioPolicyManager->releaseSpatializerOutput(newOutput);
584 }
585 } else if (mSpatializer->getLevel() == media::SpatializationLevel::NONE
586 && mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
Eric Laurent39095982021-08-24 18:29:27 +0200587 audio_io_handle_t output = mSpatializer->detachOutput();
Eric Laurent21270b62022-07-04 15:11:29 +0200588
Eric Laurent39095982021-08-24 18:29:27 +0200589 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurent21270b62022-07-04 15:11:29 +0200590 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200591 mAudioPolicyManager->releaseSpatializerOutput(output);
Eric Laurent81dd0f52021-07-05 11:54:40 +0200592 }
593 }
594 }
595}
596
Eric Laurent11094172022-04-05 18:27:42 +0200597size_t AudioPolicyService::countActiveClientsOnOutput_l(
598 audio_io_handle_t output, bool spatializedOnly) {
Eric Laurent15903592022-02-24 20:44:36 +0100599 size_t count = 0;
600 for (size_t i = 0; i < mAudioPlaybackClients.size(); i++) {
601 auto client = mAudioPlaybackClients.valueAt(i);
Eric Laurent11094172022-04-05 18:27:42 +0200602 if (client->io == output && client->active
603 && (!spatializedOnly || client->isSpatialized)) {
Eric Laurent15903592022-02-24 20:44:36 +0100604 count++;
605 }
606 }
607 return count;
608}
609
610void AudioPolicyService::onUpdateActiveSpatializerTracks_l() {
611 if (mSpatializer == nullptr) {
612 return;
613 }
614 mOutputCommandThread->updateActiveSpatializerTracksCommand();
615}
616
617void AudioPolicyService::doOnUpdateActiveSpatializerTracks()
618{
Eric Laurent21270b62022-07-04 15:11:29 +0200619 if (mSpatializer == nullptr) {
620 return;
621 }
622 audio_io_handle_t output = mSpatializer->getOutput();
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200623 size_t activeClients;
624 {
625 Mutex::Autolock _l(mLock);
Eric Laurent21270b62022-07-04 15:11:29 +0200626 activeClients = countActiveClientsOnOutput_l(output);
Eric Laurent15903592022-02-24 20:44:36 +0100627 }
Eric Laurent21270b62022-07-04 15:11:29 +0200628 mSpatializer->updateActiveTracks(activeClients);
Eric Laurent15903592022-02-24 20:44:36 +0100629}
630
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800631status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
632 audio_patch_handle_t *handle,
633 int delayMs)
634{
635 return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
636}
637
638status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
639 int delayMs)
640{
641 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
642}
643
Eric Laurente1715a42014-05-20 11:30:42 -0700644status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
645 int delayMs)
646{
647 return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
648}
649
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800650AudioPolicyService::NotificationClient::NotificationClient(
651 const sp<AudioPolicyService>& service,
652 const sp<media::IAudioPolicyServiceClient>& client,
653 uid_t uid,
654 pid_t pid)
luochaojiang908c7d72018-06-21 14:58:04 +0800655 : mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
François Gaffiecfe17322018-11-07 13:41:29 +0100656 mAudioPortCallbacksEnabled(false), mAudioVolumeGroupCallbacksEnabled(false)
Eric Laurentb52c1522014-05-20 11:27:36 -0700657{
658}
659
660AudioPolicyService::NotificationClient::~NotificationClient()
661{
662}
663
664void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
665{
666 sp<NotificationClient> keep(this);
667 sp<AudioPolicyService> service = mService.promote();
668 if (service != 0) {
luochaojiang908c7d72018-06-21 14:58:04 +0800669 service->removeNotificationClient(mUid, mPid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700670 }
671}
672
673void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
674{
Eric Laurente8726fe2015-06-26 09:39:24 -0700675 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700676 mAudioPolicyServiceClient->onAudioPortListUpdate();
677 }
678}
679
680void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
681{
Eric Laurente8726fe2015-06-26 09:39:24 -0700682 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700683 mAudioPolicyServiceClient->onAudioPatchListUpdate();
684 }
685}
Eric Laurent57dae992011-07-24 13:36:09 -0700686
Pattydd807582021-11-04 21:01:03 +0800687void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
François Gaffiecfe17322018-11-07 13:41:29 +0100688 int flags)
689{
690 if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
691 mAudioPolicyServiceClient->onAudioVolumeGroupChanged(group, flags);
692 }
693}
694
695
Jean-Michel Trivide801052015-04-14 19:10:14 -0700696void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700697 const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700698{
Andy Hung4ef19fa2018-05-15 19:35:29 -0700699 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800700 mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(
701 legacy2aidl_String8_string(regId).value(), state);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800702 }
703}
704
705void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
Eric Laurenta9f86652018-11-28 17:23:11 -0800706 int event,
707 const record_client_info_t *clientInfo,
708 const audio_config_base_t *clientConfig,
709 std::vector<effect_descriptor_t> clientEffects,
710 const audio_config_base_t *deviceConfig,
711 std::vector<effect_descriptor_t> effects,
712 audio_patch_handle_t patchHandle,
713 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800714{
Andy Hung4ef19fa2018-05-15 19:35:29 -0700715 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800716 status_t status = [&]() -> status_t {
717 int32_t eventAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(event));
718 media::RecordClientInfo clientInfoAidl = VALUE_OR_RETURN_STATUS(
719 legacy2aidl_record_client_info_t_RecordClientInfo(*clientInfo));
Mikhail Naganovdbf03642021-08-25 18:15:32 -0700720 AudioConfigBase clientConfigAidl = VALUE_OR_RETURN_STATUS(
Mikhail Naganovde3fa182021-07-30 15:06:42 -0700721 legacy2aidl_audio_config_base_t_AudioConfigBase(
722 *clientConfig, true /*isInput*/));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800723 std::vector<media::EffectDescriptor> clientEffectsAidl = VALUE_OR_RETURN_STATUS(
724 convertContainer<std::vector<media::EffectDescriptor>>(
725 clientEffects,
726 legacy2aidl_effect_descriptor_t_EffectDescriptor));
Mikhail Naganovdbf03642021-08-25 18:15:32 -0700727 AudioConfigBase deviceConfigAidl = VALUE_OR_RETURN_STATUS(
Mikhail Naganovde3fa182021-07-30 15:06:42 -0700728 legacy2aidl_audio_config_base_t_AudioConfigBase(
729 *deviceConfig, true /*isInput*/));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800730 std::vector<media::EffectDescriptor> effectsAidl = VALUE_OR_RETURN_STATUS(
731 convertContainer<std::vector<media::EffectDescriptor>>(
732 effects,
733 legacy2aidl_effect_descriptor_t_EffectDescriptor));
734 int32_t patchHandleAidl = VALUE_OR_RETURN_STATUS(
735 legacy2aidl_audio_patch_handle_t_int32_t(patchHandle));
Mikhail Naganovddceecc2021-09-03 13:58:56 -0700736 media::audio::common::AudioSource sourceAidl = VALUE_OR_RETURN_STATUS(
737 legacy2aidl_audio_source_t_AudioSource(source));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800738 return aidl_utils::statusTFromBinderStatus(
739 mAudioPolicyServiceClient->onRecordingConfigurationUpdate(eventAidl,
740 clientInfoAidl,
741 clientConfigAidl,
742 clientEffectsAidl,
743 deviceConfigAidl,
744 effectsAidl,
745 patchHandleAidl,
746 sourceAidl));
747 }();
748 ALOGW_IF(status != OK, "onRecordingConfigurationUpdate() failed: %d", status);
Jean-Michel Trivide801052015-04-14 19:10:14 -0700749 }
750}
751
Eric Laurente8726fe2015-06-26 09:39:24 -0700752void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
753{
754 mAudioPortCallbacksEnabled = enabled;
755}
756
François Gaffiecfe17322018-11-07 13:41:29 +0100757void AudioPolicyService::NotificationClient::setAudioVolumeGroupCallbacksEnabled(bool enabled)
758{
759 mAudioVolumeGroupCallbacksEnabled = enabled;
760}
Eric Laurente8726fe2015-06-26 09:39:24 -0700761
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700762void AudioPolicyService::NotificationClient::onRoutingUpdated()
763{
764 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
765 mAudioPolicyServiceClient->onRoutingUpdated();
766 }
767}
768
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +0000769void AudioPolicyService::NotificationClient::onVolumeRangeInitRequest()
770{
771 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
772 mAudioPolicyServiceClient->onVolumeRangeInitRequest();
773 }
774}
775
Mathias Agopian65ab4712010-07-14 17:59:35 -0700776void AudioPolicyService::binderDied(const wp<IBinder>& who) {
Glenn Kasten411e4472012-11-02 10:00:06 -0700777 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
Eric Laurentde070132010-07-13 04:45:46 -0700778 IPCThreadState::self()->getCallingPid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700779}
780
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000781static bool dumpTryLock(Mutex& mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782{
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000783 return mutex.timedLock(kDumpLockTimeoutNs) == NO_ERROR;
784}
785
786static void dumpReleaseLock(Mutex& mutex, bool locked) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
787{
788 if (locked) mutex.unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700789}
790
791status_t AudioPolicyService::dumpInternals(int fd)
792{
793 const size_t SIZE = 256;
794 char buffer[SIZE];
795 String8 result;
796
Mikhail Naganovb3bcb4f2022-02-23 23:46:56 +0000797 snprintf(buffer, SIZE, "Supported System Usages:\n ");
Hayden Gomes524159d2019-12-23 14:41:47 -0800798 result.append(buffer);
Mikhail Naganovb3bcb4f2022-02-23 23:46:56 +0000799 std::stringstream msg;
800 size_t i = 0;
801 for (auto usage : mSupportedSystemUsages) {
802 if (i++ != 0) msg << ", ";
803 if (const char* strUsage = audio_usage_to_string(usage); strUsage) {
804 msg << strUsage;
805 } else {
806 msg << usage << " (unknown)";
807 }
Hayden Gomes524159d2019-12-23 14:41:47 -0800808 }
Mikhail Naganovb3bcb4f2022-02-23 23:46:56 +0000809 if (i == 0) {
810 msg << "None";
811 }
812 msg << std::endl;
813 result.append(msg.str().c_str());
Hayden Gomes524159d2019-12-23 14:41:47 -0800814
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +0000815 write(fd, result.c_str(), result.size());
Oscar Azucena829d90d2022-01-28 17:17:56 -0800816
817 mUidPolicy->dumpInternals(fd);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700818 return NO_ERROR;
819}
820
Eric Laurente8c8b432018-10-17 10:08:02 -0700821void AudioPolicyService::updateUidStates()
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800822{
Eric Laurente8c8b432018-10-17 10:08:02 -0700823 Mutex::Autolock _l(mLock);
824 updateUidStates_l();
825}
826
827void AudioPolicyService::updateUidStates_l()
828{
Eric Laurent4eb58f12018-12-07 16:41:02 -0800829// Go over all active clients and allow capture (does not force silence) in the
830// following cases:
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800831// The client is in the active assistant list
832// AND is TOP
833// AND an accessibility service is TOP
834// AND source is either VOICE_RECOGNITION OR HOTWORD
835// OR there is no active privacy sensitive capture or call
836// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
837// AND source is VOICE_RECOGNITION OR HOTWORD
838// The client is an assistant AND active assistant is not being used
Evan Severson1f700cd2021-02-10 13:10:37 -0800839// AND an accessibility service is on TOP or a RTT call is active
Eric Laurent589171c2019-07-25 18:04:29 -0700840// AND the source is VOICE_RECOGNITION or HOTWORD
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800841// OR there is no active privacy sensitive capture or call
Evan Severson1f700cd2021-02-10 13:10:37 -0800842// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800843// AND is TOP most recent assistant and uses VOICE_RECOGNITION or HOTWORD
844// OR there is no top recent assistant and source is HOTWORD
Evan Severson1f700cd2021-02-10 13:10:37 -0800845// OR The client is an accessibility service
846// AND Is on TOP
847// AND the source is VOICE_RECOGNITION or HOTWORD
848// OR The assistant is not on TOP
Eric Laurent589171c2019-07-25 18:04:29 -0700849// AND there is no active privacy sensitive capture or call
850// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Evan Severson1f700cd2021-02-10 13:10:37 -0800851// AND is on TOP
852// AND the source is VOICE_RECOGNITION or HOTWORD
853// OR the client source is virtual (remote submix, call audio TX or RX...)
854// OR the client source is HOTWORD
855// AND is on TOP
856// OR all active clients are using HOTWORD source
857// AND no call is active
858// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
859// OR the client is the current InputMethodService
860// AND a RTT call is active AND the source is VOICE_RECOGNITION
861// OR Any client
862// AND The assistant is not on TOP
863// AND is on TOP or latest started
864// AND there is no active privacy sensitive capture or call
865// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent4eb58f12018-12-07 16:41:02 -0800866
Eric Laurent4e947da2019-10-17 15:24:06 -0700867
Eric Laurent4eb58f12018-12-07 16:41:02 -0800868 sp<AudioRecordClient> topActive;
869 sp<AudioRecordClient> latestActive;
Eric Laurentc21d5692020-02-25 10:24:36 -0800870 sp<AudioRecordClient> topSensitiveActive;
Eric Laurentb809a752020-06-29 09:53:13 -0700871 sp<AudioRecordClient> latestSensitiveActiveOrComm;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800872 sp<AudioRecordClient> latestActiveAssistant;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700873
Eric Laurenta46bedb2018-12-07 18:01:26 -0800874 nsecs_t topStartNs = 0;
875 nsecs_t latestStartNs = 0;
Eric Laurentc21d5692020-02-25 10:24:36 -0800876 nsecs_t topSensitiveStartNs = 0;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800877 nsecs_t latestSensitiveStartNs = 0;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800878 nsecs_t latestAssistantStartNs = 0;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800879 bool isA11yOnTop = mUidPolicy->isA11yOnTop();
880 bool isAssistantOnTop = false;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800881 bool useActiveAssistantList = false;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800882 bool isSensitiveActive = false;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700883 bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
Eric Laurentc21d5692020-02-25 10:24:36 -0800884 bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION;
885 bool rttCallActive = (isInCall || isInCommunication)
Eric Laurent6ede98f2019-06-11 14:50:30 -0700886 && mUidPolicy->isRttEnabled();
Eric Laurent4e947da2019-10-17 15:24:06 -0700887 bool onlyHotwordActive = true;
Eric Laurentb809a752020-06-29 09:53:13 -0700888 bool isPhoneStateOwnerActive = false;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800889
Michael Groovercfd28302018-12-11 19:16:46 -0800890 // if Sensor Privacy is enabled then all recordings should be silenced.
891 if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
892 silenceAllRecordings_l();
893 return;
894 }
895
Eric Laurente8c8b432018-10-17 10:08:02 -0700896 for (size_t i =0; i < mAudioRecordClients.size(); i++) {
897 sp<AudioRecordClient> current = mAudioRecordClients[i];
Svet Ganov33761132021-05-13 22:51:08 +0000898 uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
899 current->attributionSource.uid));
Evan Severson1f700cd2021-02-10 13:10:37 -0800900 if (!current->active) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700901 continue;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800902 }
Eric Laurent1ff16a72019-03-14 18:35:04 -0700903
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700904 app_state_t appState = apmStatFromAmState(mUidPolicy->getUidState(currentUid));
Eric Laurent1ff16a72019-03-14 18:35:04 -0700905 // clients which app is in IDLE state are not eligible for top active or
906 // latest active
907 if (appState == APP_STATE_IDLE) {
908 continue;
909 }
910
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700911 bool isAccessibility = mUidPolicy->isA11yUid(currentUid);
Eric Laurent14a88632020-07-16 12:28:30 -0700912 // Clients capturing for Accessibility services or virtual sources are not considered
Eric Laurentc21d5692020-02-25 10:24:36 -0800913 // for top or latest active to avoid masking regular clients started before
Eric Laurent14a88632020-07-16 12:28:30 -0700914 if (!isAccessibility && !isVirtualSource(current->attributes.source)) {
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700915 bool isAssistant = mUidPolicy->isAssistantUid(currentUid);
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800916 bool isActiveAssistant = mUidPolicy->isActiveAssistantUid(currentUid);
Eric Laurentc21d5692020-02-25 10:24:36 -0800917 bool isPrivacySensitive =
918 (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0;
Eric Laurentb809a752020-06-29 09:53:13 -0700919
Eric Laurentc21d5692020-02-25 10:24:36 -0800920 if (appState == APP_STATE_TOP) {
921 if (isPrivacySensitive) {
922 if (current->startTimeNs > topSensitiveStartNs) {
923 topSensitiveActive = current;
924 topSensitiveStartNs = current->startTimeNs;
925 }
926 } else {
927 if (current->startTimeNs > topStartNs) {
928 topActive = current;
929 topStartNs = current->startTimeNs;
930 }
931 }
932 if (isAssistant) {
933 isAssistantOnTop = true;
Oscar Azucenac2cdda32022-01-31 19:10:39 -0800934 if (isActiveAssistant) {
935 useActiveAssistantList = true;
936 } else if (!useActiveAssistantList) {
937 if (current->startTimeNs > latestAssistantStartNs) {
938 latestActiveAssistant = current;
939 latestAssistantStartNs = current->startTimeNs;
940 }
941 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800942 }
Eric Laurenta46bedb2018-12-07 18:01:26 -0800943 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800944 // Clients capturing for HOTWORD are not considered
945 // for latest active to avoid masking regular clients started before
946 if (!(current->attributes.source == AUDIO_SOURCE_HOTWORD
947 || ((isA11yOnTop || rttCallActive) && isAssistant))) {
948 if (isPrivacySensitive) {
Eric Laurentb809a752020-06-29 09:53:13 -0700949 // if audio mode is IN_COMMUNICATION, make sure the audio mode owner
950 // is marked latest sensitive active even if another app qualifies.
951 if (current->startTimeNs > latestSensitiveStartNs
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700952 || (isInCommunication && currentUid == mPhoneStateOwnerUid)) {
Eric Laurentb809a752020-06-29 09:53:13 -0700953 if (!isInCommunication || latestSensitiveActiveOrComm == nullptr
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700954 || VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +0000955 latestSensitiveActiveOrComm->attributionSource.uid))
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700956 != mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -0700957 latestSensitiveActiveOrComm = current;
958 latestSensitiveStartNs = current->startTimeNs;
959 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800960 }
961 isSensitiveActive = true;
962 } else {
963 if (current->startTimeNs > latestStartNs) {
964 latestActive = current;
965 latestStartNs = current->startTimeNs;
966 }
967 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800968 }
969 }
Eric Laurent4e947da2019-10-17 15:24:06 -0700970 if (current->attributes.source != AUDIO_SOURCE_HOTWORD) {
971 onlyHotwordActive = false;
972 }
Eric Laurentb0eff0f2021-11-09 16:05:49 +0100973 if (currentUid == mPhoneStateOwnerUid &&
974 !isVirtualSource(current->attributes.source)) {
Eric Laurentb809a752020-06-29 09:53:13 -0700975 isPhoneStateOwnerActive = true;
976 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800977 }
978
Eric Laurent1ff16a72019-03-14 18:35:04 -0700979 // if no active client with UI on Top, consider latest active as top
980 if (topActive == nullptr) {
981 topActive = latestActive;
Eric Laurentc21d5692020-02-25 10:24:36 -0800982 topStartNs = latestStartNs;
983 }
984 if (topSensitiveActive == nullptr) {
Eric Laurentb809a752020-06-29 09:53:13 -0700985 topSensitiveActive = latestSensitiveActiveOrComm;
Eric Laurentc21d5692020-02-25 10:24:36 -0800986 topSensitiveStartNs = latestSensitiveStartNs;
Eric Laurentb809a752020-06-29 09:53:13 -0700987 } else if (latestSensitiveActiveOrComm != nullptr) {
988 // if audio mode is IN_COMMUNICATION, favor audio mode owner over an app with
989 // foreground UI in case both are capturing with privacy sensitive flag.
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700990 uid_t latestActiveUid = VALUE_OR_FATAL(
Svet Ganov33761132021-05-13 22:51:08 +0000991 aidl2legacy_int32_t_uid_t(latestSensitiveActiveOrComm->attributionSource.uid));
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700992 if (isInCommunication && latestActiveUid == mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -0700993 topSensitiveActive = latestSensitiveActiveOrComm;
994 topSensitiveStartNs = latestSensitiveStartNs;
995 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800996 }
997
998 // If both privacy sensitive and regular capture are active:
999 // if the regular capture is privileged
1000 // allow concurrency
1001 // else
1002 // favor the privacy sensitive case
1003 if (topActive != nullptr && topSensitiveActive != nullptr
Ricardo Correa57a37692020-03-23 17:27:25 -07001004 && !topActive->canCaptureOutput) {
Eric Laurentc21d5692020-02-25 10:24:36 -08001005 topActive = nullptr;
Eric Laurent4eb58f12018-12-07 16:41:02 -08001006 }
1007
1008 for (size_t i =0; i < mAudioRecordClients.size(); i++) {
1009 sp<AudioRecordClient> current = mAudioRecordClients[i];
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001010 uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +00001011 current->attributionSource.uid));
Eric Laurent1ff16a72019-03-14 18:35:04 -07001012 if (!current->active) {
1013 continue;
1014 }
1015
Eric Laurent4eb58f12018-12-07 16:41:02 -08001016 audio_source_t source = current->attributes.source;
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001017 bool isTopOrLatestActive = topActive == nullptr ? false :
Svet Ganov33761132021-05-13 22:51:08 +00001018 current->attributionSource.uid == topActive->attributionSource.uid;
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001019 bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false :
Svet Ganov33761132021-05-13 22:51:08 +00001020 current->attributionSource.uid == topSensitiveActive->attributionSource.uid;
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001021 bool isTopOrLatestAssistant = latestActiveAssistant == nullptr ? false :
1022 current->attributionSource.uid == latestActiveAssistant->attributionSource.uid;
Eric Laurentc21d5692020-02-25 10:24:36 -08001023
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001024 auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) REQUIRES(mLock) {
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001025 uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +00001026 recordClient->attributionSource.uid));
Ricardo Correa57a37692020-03-23 17:27:25 -07001027 bool canCaptureCall = recordClient->canCaptureOutput;
Eric Laurentb809a752020-06-29 09:53:13 -07001028 bool canCaptureCommunication = recordClient->canCaptureOutput
1029 || !isPhoneStateOwnerActive
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001030 || recordUid == mPhoneStateOwnerUid;
Eric Laurentb809a752020-06-29 09:53:13 -07001031 return !(isInCall && !canCaptureCall)
1032 && !(isInCommunication && !canCaptureCommunication);
Eric Laurentc21d5692020-02-25 10:24:36 -08001033 };
Eric Laurent1ff16a72019-03-14 18:35:04 -07001034
1035 // By default allow capture if:
1036 // The assistant is not on TOP
Eric Laurenta171e352019-05-07 13:04:45 -07001037 // AND is on TOP or latest started
Eric Laurent1ff16a72019-03-14 18:35:04 -07001038 // AND there is no active privacy sensitive capture or call
1039 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent4ab18412022-11-07 16:25:32 +01001040 bool allowSensitiveCapture =
1041 !isSensitiveActive || isTopOrLatestSensitive || current->canCaptureOutput;
Eric Laurent1ff16a72019-03-14 18:35:04 -07001042 bool allowCapture = !isAssistantOnTop
Eric Laurentc21d5692020-02-25 10:24:36 -08001043 && (isTopOrLatestActive || isTopOrLatestSensitive)
Eric Laurent4ab18412022-11-07 16:25:32 +01001044 && allowSensitiveCapture
Eric Laurentc21d5692020-02-25 10:24:36 -08001045 && canCaptureIfInCallOrCommunication(current);
Eric Laurent2dc962b2019-03-01 08:25:25 -08001046
Eric Laurented726cc2021-07-01 14:26:41 +02001047 if (!current->hasOp()) {
1048 // Never allow capture if app op is denied
1049 allowCapture = false;
1050 } else if (isVirtualSource(source)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001051 // Allow capture for virtual (remote submix, call audio TX or RX...) sources
1052 allowCapture = true;
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001053 } else if (!useActiveAssistantList && mUidPolicy->isAssistantUid(currentUid)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001054 // For assistant allow capture if:
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001055 // Active assistant list is not being used
1056 // AND accessibility service is on TOP or a RTT call is active
Eric Laurent1ff16a72019-03-14 18:35:04 -07001057 // AND the source is VOICE_RECOGNITION or HOTWORD
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001058 // OR there is no active privacy sensitive capture or call
1059 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1060 // AND is latest TOP assistant AND
1061 // uses VOICE_RECOGNITION OR uses HOTWORD
1062 // OR there is no TOP assistant and uses HOTWORD
Eric Laurent6ede98f2019-06-11 14:50:30 -07001063 if (isA11yOnTop || rttCallActive) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001064 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001065 allowCapture = true;
Eric Laurent4eb58f12018-12-07 16:41:02 -08001066 }
Eric Laurent4ab18412022-11-07 16:25:32 +01001067 } else if (allowSensitiveCapture
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001068 && canCaptureIfInCallOrCommunication(current)) {
1069 if (isTopOrLatestAssistant
1070 && (source == AUDIO_SOURCE_VOICE_RECOGNITION
1071 || source == AUDIO_SOURCE_HOTWORD)) {
1072 allowCapture = true;
1073 } else if (!isAssistantOnTop && (source == AUDIO_SOURCE_HOTWORD)) {
1074 allowCapture = true;
1075 }
1076 }
1077 } else if (useActiveAssistantList && mUidPolicy->isActiveAssistantUid(currentUid)) {
1078 // For assistant on active list and on top allow capture if:
1079 // An accessibility service is on TOP
1080 // AND the source is VOICE_RECOGNITION or HOTWORD
1081 // OR there is no active privacy sensitive capture or call
1082 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1083 // AND uses VOICE_RECOGNITION OR uses HOTWORD
1084 if (isA11yOnTop) {
1085 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1086 allowCapture = true;
1087 }
Eric Laurent4ab18412022-11-07 16:25:32 +01001088 } else if (allowSensitiveCapture
Eric Laurentc21d5692020-02-25 10:24:36 -08001089 && canCaptureIfInCallOrCommunication(current)) {
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001090 if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) || (source == AUDIO_SOURCE_HOTWORD))
1091 {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001092 allowCapture = true;
Eric Laurent4eb58f12018-12-07 16:41:02 -08001093 }
1094 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001095 } else if (mUidPolicy->isA11yUid(currentUid)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001096 // For accessibility service allow capture if:
Eric Laurent47670c92019-08-28 16:59:05 -07001097 // The assistant is not on TOP
1098 // AND there is no active privacy sensitive capture or call
Eric Laurent589171c2019-07-25 18:04:29 -07001099 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent47670c92019-08-28 16:59:05 -07001100 // OR
1101 // Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
1102 if (!isAssistantOnTop
Eric Laurent4ab18412022-11-07 16:25:32 +01001103 && allowSensitiveCapture
Eric Laurentc21d5692020-02-25 10:24:36 -08001104 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent47670c92019-08-28 16:59:05 -07001105 allowCapture = true;
1106 }
Eric Laurent589171c2019-07-25 18:04:29 -07001107 if (isA11yOnTop) {
1108 if (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD) {
1109 allowCapture = true;
1110 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001111 }
Eric Laurent4e947da2019-10-17 15:24:06 -07001112 } else if (source == AUDIO_SOURCE_HOTWORD) {
1113 // For HOTWORD source allow capture when not on TOP if:
1114 // All active clients are using HOTWORD source
1115 // AND no call is active
1116 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurentc21d5692020-02-25 10:24:36 -08001117 if (onlyHotwordActive
1118 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent4e947da2019-10-17 15:24:06 -07001119 allowCapture = true;
1120 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001121 } else if (mUidPolicy->isCurrentImeUid(currentUid)) {
Kohsuke Yatoha623a132020-03-24 20:10:26 -07001122 // For current InputMethodService allow capture if:
1123 // A RTT call is active AND the source is VOICE_RECOGNITION
1124 if (rttCallActive && source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1125 allowCapture = true;
1126 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001127 }
Eric Laurent8c7ef892021-06-10 13:32:16 +02001128 setAppState_l(current,
Philip P. Moltmannbda45752020-07-17 16:41:18 -07001129 allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(currentUid)) :
Eric Laurent1ff16a72019-03-14 18:35:04 -07001130 APP_STATE_IDLE);
Eric Laurente8c8b432018-10-17 10:08:02 -07001131 }
1132}
1133
Michael Groovercfd28302018-12-11 19:16:46 -08001134void AudioPolicyService::silenceAllRecordings_l() {
1135 for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
1136 sp<AudioRecordClient> current = mAudioRecordClients[i];
Eric Laurent1ff16a72019-03-14 18:35:04 -07001137 if (!isVirtualSource(current->attributes.source)) {
Eric Laurent8c7ef892021-06-10 13:32:16 +02001138 setAppState_l(current, APP_STATE_IDLE);
Eric Laurent1ff16a72019-03-14 18:35:04 -07001139 }
Michael Groovercfd28302018-12-11 19:16:46 -08001140 }
1141}
1142
Eric Laurente8c8b432018-10-17 10:08:02 -07001143/* static */
1144app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
Eric Laurent1ff16a72019-03-14 18:35:04 -07001145
1146 if (amState == ActivityManager::PROCESS_STATE_UNKNOWN) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001147 return APP_STATE_IDLE;
Eric Laurent1ff16a72019-03-14 18:35:04 -07001148 } else if (amState <= ActivityManager::PROCESS_STATE_TOP) {
1149 // include persistent services
1150 return APP_STATE_TOP;
Eric Laurente8c8b432018-10-17 10:08:02 -07001151 }
1152 return APP_STATE_FOREGROUND;
1153}
1154
Eric Laurent4eb58f12018-12-07 16:41:02 -08001155/* static */
Eric Laurent2dc962b2019-03-01 08:25:25 -08001156bool AudioPolicyService::isVirtualSource(audio_source_t source)
Eric Laurent4eb58f12018-12-07 16:41:02 -08001157{
1158 switch (source) {
1159 case AUDIO_SOURCE_VOICE_UPLINK:
1160 case AUDIO_SOURCE_VOICE_DOWNLINK:
1161 case AUDIO_SOURCE_VOICE_CALL:
Eric Laurent2dc962b2019-03-01 08:25:25 -08001162 case AUDIO_SOURCE_REMOTE_SUBMIX:
1163 case AUDIO_SOURCE_FM_TUNER:
Eric Laurent68eb2122020-04-30 17:40:57 -07001164 case AUDIO_SOURCE_ECHO_REFERENCE:
Eric Laurent4eb58f12018-12-07 16:41:02 -08001165 return true;
1166 default:
1167 break;
1168 }
1169 return false;
1170}
1171
Eric Laurent8c7ef892021-06-10 13:32:16 +02001172void AudioPolicyService::setAppState_l(sp<AudioRecordClient> client, app_state_t state)
Eric Laurente8c8b432018-10-17 10:08:02 -07001173{
1174 AutoCallerClear acc;
1175
1176 if (mAudioPolicyManager) {
Eric Laurent8c7ef892021-06-10 13:32:16 +02001177 mAudioPolicyManager->setAppState(client->portId, state);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001178 }
1179 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1180 if (af) {
Eric Laurentf32108e2018-10-04 17:22:04 -07001181 bool silenced = state == APP_STATE_IDLE;
Eric Laurent8c7ef892021-06-10 13:32:16 +02001182 if (client->silenced != silenced) {
1183 if (client->active) {
1184 if (silenced) {
1185 finishRecording(client->attributionSource, client->attributes.source);
1186 } else {
1187 std::stringstream msg;
1188 msg << "Audio recording un-silenced on session " << client->session;
1189 if (!startRecording(client->attributionSource, String16(msg.str().c_str()),
1190 client->attributes.source)) {
1191 silenced = true;
1192 }
1193 }
1194 }
1195 af->setRecordSilenced(client->portId, silenced);
1196 client->silenced = silenced;
1197 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001198 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001199}
1200
Glenn Kasten0f11b512014-01-31 16:18:54 -08001201status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001202{
Glenn Kasten44deb052012-02-05 18:09:08 -08001203 if (!dumpAllowed()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001204 dumpPermissionDenial(fd);
1205 } else {
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001206 const bool locked = dumpTryLock(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001207 if (!locked) {
1208 String8 result(kDeadlockedString);
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001209 write(fd, result.c_str(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001210 }
1211
1212 dumpInternals(fd);
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001213
1214 String8 actPtr = String8::format("AudioCommandThread: %p\n", mAudioCommandThread.get());
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001215 write(fd, actPtr.c_str(), actPtr.size());
Glenn Kasten9d1f02d2012-02-08 17:47:58 -08001216 if (mAudioCommandThread != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001217 mAudioCommandThread->dump(fd);
1218 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001219
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001220 String8 octPtr = String8::format("OutputCommandThread: %p\n", mOutputCommandThread.get());
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001221 write(fd, octPtr.c_str(), octPtr.size());
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001222 if (mOutputCommandThread != 0) {
1223 mOutputCommandThread->dump(fd);
1224 }
1225
Eric Laurentdce54a12014-03-10 12:19:46 -07001226 if (mAudioPolicyManager) {
1227 mAudioPolicyManager->dump(fd);
Mikhail Naganov1b22e542022-02-25 04:24:49 +00001228 } else {
1229 String8 apmPtr = String8::format("AudioPolicyManager: %p\n", mAudioPolicyManager);
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001230 write(fd, apmPtr.c_str(), apmPtr.size());
Eric Laurentdce54a12014-03-10 12:19:46 -07001231 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001232
Kevin Rocard8be94972019-02-22 13:26:25 -08001233 mPackageManager.dump(fd);
1234
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001235 dumpReleaseLock(mLock, locked);
Andy Hungc747c532022-03-07 21:41:14 -08001236
Shunkai Yao59b27bc2022-07-22 18:42:27 +00001237 if (mSpatializer != nullptr) {
1238 std::string dumpString = mSpatializer->toString(1 /* level */);
1239 write(fd, dumpString.c_str(), dumpString.size());
1240 } else {
1241 String8 spatializerPtr = String8::format("Spatializer no supportted on this device\n");
1242 write(fd, spatializerPtr.c_str(), spatializerPtr.size());
1243 }
1244
Andy Hungc747c532022-03-07 21:41:14 -08001245 {
1246 std::string timeCheckStats = getIAudioPolicyServiceStatistics().dump();
1247 dprintf(fd, "\nIAudioPolicyService binder call profile\n");
1248 write(fd, timeCheckStats.c_str(), timeCheckStats.size());
1249 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001250 }
1251 return NO_ERROR;
1252}
1253
1254status_t AudioPolicyService::dumpPermissionDenial(int fd)
1255{
1256 const size_t SIZE = 256;
1257 char buffer[SIZE];
1258 String8 result;
1259 snprintf(buffer, SIZE, "Permission Denial: "
1260 "can't dump AudioPolicyService from pid=%d, uid=%d\n",
1261 IPCThreadState::self()->getCallingPid(),
1262 IPCThreadState::self()->getCallingUid());
1263 result.append(buffer);
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001264 write(fd, result.c_str(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001265 return NO_ERROR;
1266}
1267
1268status_t AudioPolicyService::onTransact(
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001269 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001270 // make sure transactions reserved to AudioFlinger do not come from other processes
1271 switch (code) {
1272 case TRANSACTION_startOutput:
1273 case TRANSACTION_stopOutput:
1274 case TRANSACTION_releaseOutput:
1275 case TRANSACTION_getInputForAttr:
1276 case TRANSACTION_startInput:
1277 case TRANSACTION_stopInput:
1278 case TRANSACTION_releaseInput:
1279 case TRANSACTION_getOutputForEffect:
1280 case TRANSACTION_registerEffect:
1281 case TRANSACTION_unregisterEffect:
1282 case TRANSACTION_setEffectEnabled:
1283 case TRANSACTION_getStrategyForStream:
1284 case TRANSACTION_getOutputForAttr:
1285 case TRANSACTION_moveEffectsToIo:
1286 ALOGW("%s: transaction %d received from PID %d",
1287 __func__, code, IPCThreadState::self()->getCallingPid());
1288 return INVALID_OPERATION;
1289 default:
1290 break;
1291 }
1292
1293 // make sure the following transactions come from system components
1294 switch (code) {
1295 case TRANSACTION_setDeviceConnectionState:
1296 case TRANSACTION_handleDeviceConfigChange:
1297 case TRANSACTION_setPhoneState:
1298//FIXME: Allow setForceUse calls from system apps until a better use case routing API is available
1299// case TRANSACTION_setForceUse:
1300 case TRANSACTION_initStreamVolume:
1301 case TRANSACTION_setStreamVolumeIndex:
1302 case TRANSACTION_setVolumeIndexForAttributes:
1303 case TRANSACTION_getStreamVolumeIndex:
1304 case TRANSACTION_getVolumeIndexForAttributes:
1305 case TRANSACTION_getMinVolumeIndexForAttributes:
1306 case TRANSACTION_getMaxVolumeIndexForAttributes:
1307 case TRANSACTION_isStreamActive:
1308 case TRANSACTION_isStreamActiveRemotely:
1309 case TRANSACTION_isSourceActive:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001310 case TRANSACTION_registerPolicyMixes:
Jan Sebechlebsky0af8e872023-08-11 14:45:08 +02001311 case TRANSACTION_updatePolicyMixes:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001312 case TRANSACTION_setMasterMono:
1313 case TRANSACTION_getSurroundFormats:
Kriti Dang6537def2021-03-02 13:46:59 +01001314 case TRANSACTION_getReportedSurroundFormats:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001315 case TRANSACTION_setSurroundFormatEnabled:
Oscar Azucena829d90d2022-01-28 17:17:56 -08001316 case TRANSACTION_setAssistantServicesUids:
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001317 case TRANSACTION_setActiveAssistantServicesUids:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001318 case TRANSACTION_setA11yServicesUids:
1319 case TRANSACTION_setUidDeviceAffinities:
1320 case TRANSACTION_removeUidDeviceAffinities:
1321 case TRANSACTION_setUserIdDeviceAffinities:
1322 case TRANSACTION_removeUserIdDeviceAffinities:
Pattydd807582021-11-04 21:01:03 +08001323 case TRANSACTION_getHwOffloadFormatsSupportedForBluetoothMedia:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001324 case TRANSACTION_listAudioVolumeGroups:
1325 case TRANSACTION_getVolumeGroupFromAudioAttributes:
1326 case TRANSACTION_acquireSoundTriggerSession:
1327 case TRANSACTION_releaseSoundTriggerSession:
Atneya Nair698f5ef2022-12-15 16:15:09 -08001328 case TRANSACTION_isHotwordStreamSupported:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001329 case TRANSACTION_setRttEnabled:
1330 case TRANSACTION_isCallScreenModeSupported:
1331 case TRANSACTION_setDevicesRoleForStrategy:
1332 case TRANSACTION_setSupportedSystemUsages:
1333 case TRANSACTION_removeDevicesRoleForStrategy:
Paul Wang5d7cdb52022-11-22 09:45:06 +00001334 case TRANSACTION_clearDevicesRoleForStrategy:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001335 case TRANSACTION_getDevicesForRoleAndStrategy:
1336 case TRANSACTION_getDevicesForAttributes:
1337 case TRANSACTION_setAllowedCapturePolicy:
1338 case TRANSACTION_onNewAudioModulesAvailable:
1339 case TRANSACTION_setCurrentImeUid:
1340 case TRANSACTION_registerSoundTriggerCaptureStateListener:
1341 case TRANSACTION_setDevicesRoleForCapturePreset:
1342 case TRANSACTION_addDevicesRoleForCapturePreset:
1343 case TRANSACTION_removeDevicesRoleForCapturePreset:
1344 case TRANSACTION_clearDevicesRoleForCapturePreset:
Eric Laurent81dd0f52021-07-05 11:54:40 +02001345 case TRANSACTION_getDevicesForRoleAndCapturePreset:
jiabina84c3d32022-12-02 18:59:55 +00001346 case TRANSACTION_getSpatializer:
1347 case TRANSACTION_setPreferredMixerAttributes:
1348 case TRANSACTION_clearPreferredMixerAttributes: {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001349 if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
1350 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
1351 __func__, code, IPCThreadState::self()->getCallingPid(),
1352 IPCThreadState::self()->getCallingUid());
1353 return INVALID_OPERATION;
1354 }
1355 } break;
1356 default:
1357 break;
1358 }
1359
Andy Hungc747c532022-03-07 21:41:14 -08001360 const std::string methodName = getIAudioPolicyServiceStatistics().getMethodForCode(code);
1361 mediautils::TimeCheck check(
1362 std::string("IAudioPolicyService::").append(methodName),
1363 [code, methodName](bool timeout, float elapsedMs) { // don't move methodName.
1364 if (timeout) {
1365 mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_POLICY)
1366 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_TIMEOUT)
1367 .set(AMEDIAMETRICS_PROP_METHODCODE, int64_t(code))
1368 .set(AMEDIAMETRICS_PROP_METHODNAME, methodName.c_str())
1369 .record();
1370 } else {
1371 getIAudioPolicyServiceStatistics().event(code, elapsedMs);
1372 }
Andy Hung741b3dd2022-06-13 19:49:43 -07001373 }, mediautils::TimeCheck::kDefaultTimeoutDuration,
1374 mediautils::TimeCheck::kDefaultSecondChanceDuration,
1375 true /* crashOnTimeout */);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001376
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001377 switch (code) {
1378 case SHELL_COMMAND_TRANSACTION: {
1379 int in = data.readFileDescriptor();
1380 int out = data.readFileDescriptor();
1381 int err = data.readFileDescriptor();
1382 int argc = data.readInt32();
1383 Vector<String16> args;
1384 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1385 args.add(data.readString16());
1386 }
1387 sp<IBinder> unusedCallback;
1388 sp<IResultReceiver> resultReceiver;
1389 status_t status;
1390 if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1391 return status;
1392 }
1393 if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1394 return status;
1395 }
1396 status = shellCommand(in, out, err, args);
1397 if (resultReceiver != nullptr) {
1398 resultReceiver->send(status);
1399 }
1400 return NO_ERROR;
1401 }
1402 }
1403
Mathias Agopian65ab4712010-07-14 17:59:35 -07001404 return BnAudioPolicyService::onTransact(code, data, reply, flags);
1405}
1406
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001407// ------------------- Shell command implementation -------------------
1408
1409// NOTE: This is a remote API - make sure all args are validated
1410status_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
1411 if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
1412 return PERMISSION_DENIED;
1413 }
1414 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
1415 return BAD_VALUE;
1416 }
jovanakbe066e12019-09-02 11:54:39 -07001417 if (args.size() >= 3 && args[0] == String16("set-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001418 return handleSetUidState(args, err);
jovanakbe066e12019-09-02 11:54:39 -07001419 } else if (args.size() >= 2 && args[0] == String16("reset-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001420 return handleResetUidState(args, err);
jovanakbe066e12019-09-02 11:54:39 -07001421 } else if (args.size() >= 2 && args[0] == String16("get-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001422 return handleGetUidState(args, out, err);
Eric Laurent269acb42021-04-23 16:53:22 +02001423 } else if (args.size() >= 1 && args[0] == String16("purge_permission-cache")) {
1424 purgePermissionCache();
1425 return NO_ERROR;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001426 } else if (args.size() == 1 && args[0] == String16("help")) {
1427 printHelp(out);
1428 return NO_ERROR;
1429 }
1430 printHelp(err);
1431 return BAD_VALUE;
1432}
1433
jovanakbe066e12019-09-02 11:54:39 -07001434static status_t getUidForPackage(String16 packageName, int userId, /*inout*/uid_t& uid, int err) {
1435 if (userId < 0) {
1436 ALOGE("Invalid user: %d", userId);
1437 dprintf(err, "Invalid user: %d\n", userId);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001438 return BAD_VALUE;
1439 }
jovanakbe066e12019-09-02 11:54:39 -07001440
1441 PermissionController pc;
1442 uid = pc.getPackageUid(packageName, 0);
1443 if (uid <= 0) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001444 ALOGE("Unknown package: '%s'", String8(packageName).c_str());
1445 dprintf(err, "Unknown package: '%s'\n", String8(packageName).c_str());
jovanakbe066e12019-09-02 11:54:39 -07001446 return BAD_VALUE;
1447 }
1448
1449 uid = multiuser_get_uid(userId, uid);
1450 return NO_ERROR;
1451}
1452
1453status_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) {
1454 // Valid arg.size() is 3 or 5, args.size() is 5 with --user option.
1455 if (!(args.size() == 3 || args.size() == 5)) {
1456 printHelp(err);
1457 return BAD_VALUE;
1458 }
1459
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001460 bool active = false;
1461 if (args[2] == String16("active")) {
1462 active = true;
1463 } else if ((args[2] != String16("idle"))) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001464 ALOGE("Expected active or idle but got: '%s'", String8(args[2]).c_str());
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001465 return BAD_VALUE;
1466 }
jovanakbe066e12019-09-02 11:54:39 -07001467
1468 int userId = 0;
1469 if (args.size() >= 5 && args[3] == String16("--user")) {
1470 userId = atoi(String8(args[4]));
1471 }
1472
1473 uid_t uid;
1474 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1475 return BAD_VALUE;
1476 }
1477
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001478 sp<UidPolicy> uidPolicy;
1479 {
1480 Mutex::Autolock _l(mLock);
1481 uidPolicy = mUidPolicy;
1482 }
1483 if (uidPolicy) {
1484 uidPolicy->addOverrideUid(uid, active);
1485 return NO_ERROR;
1486 }
1487 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001488}
1489
1490status_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) {
jovanakbe066e12019-09-02 11:54:39 -07001491 // Valid arg.size() is 2 or 4, args.size() is 4 with --user option.
1492 if (!(args.size() == 2 || args.size() == 4)) {
1493 printHelp(err);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001494 return BAD_VALUE;
1495 }
jovanakbe066e12019-09-02 11:54:39 -07001496
1497 int userId = 0;
1498 if (args.size() >= 4 && args[2] == String16("--user")) {
1499 userId = atoi(String8(args[3]));
1500 }
1501
1502 uid_t uid;
1503 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1504 return BAD_VALUE;
1505 }
1506
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001507 sp<UidPolicy> uidPolicy;
1508 {
1509 Mutex::Autolock _l(mLock);
1510 uidPolicy = mUidPolicy;
1511 }
1512 if (uidPolicy) {
1513 uidPolicy->removeOverrideUid(uid);
1514 return NO_ERROR;
1515 }
1516 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001517}
1518
1519status_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) {
jovanakbe066e12019-09-02 11:54:39 -07001520 // Valid arg.size() is 2 or 4, args.size() is 4 with --user option.
1521 if (!(args.size() == 2 || args.size() == 4)) {
1522 printHelp(err);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001523 return BAD_VALUE;
1524 }
jovanakbe066e12019-09-02 11:54:39 -07001525
1526 int userId = 0;
1527 if (args.size() >= 4 && args[2] == String16("--user")) {
1528 userId = atoi(String8(args[3]));
1529 }
1530
1531 uid_t uid;
1532 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1533 return BAD_VALUE;
1534 }
1535
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001536 sp<UidPolicy> uidPolicy;
1537 {
1538 Mutex::Autolock _l(mLock);
1539 uidPolicy = mUidPolicy;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001540 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001541 if (uidPolicy) {
1542 return dprintf(out, uidPolicy->isUidActive(uid) ? "active\n" : "idle\n");
1543 }
1544 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001545}
1546
1547status_t AudioPolicyService::printHelp(int out) {
1548 return dprintf(out, "Audio policy service commands:\n"
jovanakbe066e12019-09-02 11:54:39 -07001549 " get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
1550 " set-uid-state <PACKAGE> <active|idle> [--user USER_ID] overrides the uid state\n"
1551 " reset-uid-state <PACKAGE> [--user USER_ID] clears the uid state override\n"
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001552 " help print this message\n");
1553}
1554
Eric Laurent0d13fea2022-11-04 17:12:08 +01001555status_t AudioPolicyService::registerOutput(audio_io_handle_t output,
1556 const audio_config_base_t& config,
1557 const audio_output_flags_t flags) {
1558 return mUsecaseValidator->registerStream(output, config, flags);
1559}
1560
1561status_t AudioPolicyService::unregisterOutput(audio_io_handle_t output) {
1562 return mUsecaseValidator->unregisterStream(output);
1563}
1564
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001565// ----------- AudioPolicyService::UidPolicy implementation ----------
1566
1567void AudioPolicyService::UidPolicy::registerSelf() {
Steven Moreland2f348142019-07-02 15:59:07 -07001568 status_t res = mAm.linkToDeath(this);
1569 mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001570 | ActivityManager::UID_OBSERVER_IDLE
Eric Laurente8c8b432018-10-17 10:08:02 -07001571 | ActivityManager::UID_OBSERVER_ACTIVE
1572 | ActivityManager::UID_OBSERVER_PROCSTATE,
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001573 ActivityManager::PROCESS_STATE_UNKNOWN,
1574 String16("audioserver"));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001575 if (!res) {
1576 Mutex::Autolock _l(mLock);
1577 mObserverRegistered = true;
1578 } else {
1579 ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
Eric Laurent4eb58f12018-12-07 16:41:02 -08001580
Steven Moreland2f348142019-07-02 15:59:07 -07001581 mAm.unregisterUidObserver(this);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001582 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001583}
1584
1585void AudioPolicyService::UidPolicy::unregisterSelf() {
Steven Moreland2f348142019-07-02 15:59:07 -07001586 mAm.unlinkToDeath(this);
1587 mAm.unregisterUidObserver(this);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001588 Mutex::Autolock _l(mLock);
1589 mObserverRegistered = false;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001590}
1591
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001592void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
1593 Mutex::Autolock _l(mLock);
1594 mCachedUids.clear();
1595 mObserverRegistered = false;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001596}
1597
Eric Laurente8c8b432018-10-17 10:08:02 -07001598void AudioPolicyService::UidPolicy::checkRegistered() {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001599 bool needToReregister = false;
1600 {
1601 Mutex::Autolock _l(mLock);
1602 needToReregister = !mObserverRegistered;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001603 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001604 if (needToReregister) {
1605 // Looks like ActivityManager has died previously, attempt to re-register.
1606 registerSelf();
1607 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001608}
1609
1610bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
1611 if (isServiceUid(uid)) return true;
1612 checkRegistered();
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001613 {
1614 Mutex::Autolock _l(mLock);
1615 auto overrideIter = mOverrideUids.find(uid);
1616 if (overrideIter != mOverrideUids.end()) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001617 return overrideIter->second.first;
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001618 }
1619 // In an absense of the ActivityManager, assume everything to be active.
1620 if (!mObserverRegistered) return true;
1621 auto cacheIter = mCachedUids.find(uid);
Mikhail Naganoveba668a2018-04-05 08:13:15 -07001622 if (cacheIter != mCachedUids.end()) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001623 return cacheIter->second.first;
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001624 }
1625 }
1626 ActivityManager am;
Hui Yu12c7ec72020-05-04 17:40:52 +00001627 bool active = am.isUidActive(uid, String16("audioserver"));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001628 {
1629 Mutex::Autolock _l(mLock);
Eric Laurente8c8b432018-10-17 10:08:02 -07001630 mCachedUids.insert(std::pair<uid_t,
1631 std::pair<bool, int>>(uid, std::pair<bool, int>(active,
1632 ActivityManager::PROCESS_STATE_UNKNOWN)));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001633 }
1634 return active;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001635}
1636
Eric Laurente8c8b432018-10-17 10:08:02 -07001637int AudioPolicyService::UidPolicy::getUidState(uid_t uid) {
1638 if (isServiceUid(uid)) {
1639 return ActivityManager::PROCESS_STATE_TOP;
1640 }
1641 checkRegistered();
1642 {
1643 Mutex::Autolock _l(mLock);
1644 auto overrideIter = mOverrideUids.find(uid);
1645 if (overrideIter != mOverrideUids.end()) {
1646 if (overrideIter->second.first) {
1647 if (overrideIter->second.second != ActivityManager::PROCESS_STATE_UNKNOWN) {
1648 return overrideIter->second.second;
1649 } else {
1650 auto cacheIter = mCachedUids.find(uid);
1651 if (cacheIter != mCachedUids.end()) {
1652 return cacheIter->second.second;
1653 }
1654 }
1655 }
1656 return ActivityManager::PROCESS_STATE_UNKNOWN;
1657 }
1658 // In an absense of the ActivityManager, assume everything to be active.
1659 if (!mObserverRegistered) {
1660 return ActivityManager::PROCESS_STATE_TOP;
1661 }
1662 auto cacheIter = mCachedUids.find(uid);
1663 if (cacheIter != mCachedUids.end()) {
1664 if (cacheIter->second.first) {
1665 return cacheIter->second.second;
1666 } else {
1667 return ActivityManager::PROCESS_STATE_UNKNOWN;
1668 }
1669 }
1670 }
1671 ActivityManager am;
Hui Yu12c7ec72020-05-04 17:40:52 +00001672 bool active = am.isUidActive(uid, String16("audioserver"));
Eric Laurente8c8b432018-10-17 10:08:02 -07001673 int state = ActivityManager::PROCESS_STATE_UNKNOWN;
1674 if (active) {
1675 state = am.getUidProcessState(uid, String16("audioserver"));
1676 }
1677 {
1678 Mutex::Autolock _l(mLock);
1679 mCachedUids.insert(std::pair<uid_t,
1680 std::pair<bool, int>>(uid, std::pair<bool, int>(active, state)));
1681 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001682
Eric Laurente8c8b432018-10-17 10:08:02 -07001683 return state;
1684}
1685
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001686void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001687 updateUid(&mCachedUids, uid, true, ActivityManager::PROCESS_STATE_UNKNOWN, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001688}
1689
1690void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001691 updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, false);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001692}
1693
1694void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001695 updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001696}
1697
Eric Laurente8c8b432018-10-17 10:08:02 -07001698void AudioPolicyService::UidPolicy::onUidStateChanged(uid_t uid,
1699 int32_t procState,
Hui Yu13ad0eb2019-09-09 10:27:07 -07001700 int64_t procStateSeq __unused,
1701 int32_t capability __unused) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001702 if (procState != ActivityManager::PROCESS_STATE_UNKNOWN) {
1703 updateUid(&mCachedUids, uid, true, procState, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001704 }
1705}
1706
Austin Borgerdddb7552023-03-30 17:53:01 -07001707void AudioPolicyService::UidPolicy::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {
Austin Borger65577682022-02-17 00:25:43 +00001708}
1709
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001710void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001711 updateUid(&mOverrideUids, uid, active, ActivityManager::PROCESS_STATE_UNKNOWN, insert);
1712}
1713
1714void AudioPolicyService::UidPolicy::notifyService() {
1715 sp<AudioPolicyService> service = mService.promote();
1716 if (service != nullptr) {
1717 service->updateUidStates();
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001718 }
1719}
1720
Eric Laurente8c8b432018-10-17 10:08:02 -07001721void AudioPolicyService::UidPolicy::updateUid(std::unordered_map<uid_t,
1722 std::pair<bool, int>> *uids,
1723 uid_t uid,
1724 bool active,
1725 int state,
1726 bool insert) {
1727 if (isServiceUid(uid)) {
1728 return;
1729 }
1730 bool wasActive = isUidActive(uid);
1731 int previousState = getUidState(uid);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001732 {
1733 Mutex::Autolock _l(mLock);
Eric Laurente8c8b432018-10-17 10:08:02 -07001734 updateUidLocked(uids, uid, active, state, insert);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001735 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001736 if (wasActive != isUidActive(uid) || state != previousState) {
1737 notifyService();
1738 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001739}
1740
Eric Laurente8c8b432018-10-17 10:08:02 -07001741void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t,
1742 std::pair<bool, int>> *uids,
1743 uid_t uid,
1744 bool active,
1745 int state,
1746 bool insert) {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001747 auto it = uids->find(uid);
1748 if (it != uids->end()) {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001749 if (insert) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001750 if (state == ActivityManager::PROCESS_STATE_UNKNOWN) {
1751 it->second.first = active;
1752 }
1753 if (it->second.first) {
1754 it->second.second = state;
1755 } else {
1756 it->second.second = ActivityManager::PROCESS_STATE_UNKNOWN;
1757 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001758 } else {
1759 uids->erase(it);
1760 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001761 } else if (insert && (state == ActivityManager::PROCESS_STATE_UNKNOWN)) {
1762 uids->insert(std::pair<uid_t, std::pair<bool, int>>(uid,
1763 std::pair<bool, int>(active, state)));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001764 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001765}
Mathias Agopian65ab4712010-07-14 17:59:35 -07001766
Eric Laurent4eb58f12018-12-07 16:41:02 -08001767bool AudioPolicyService::UidPolicy::isA11yOnTop() {
lihong80e1f56e2022-08-25 11:15:33 +08001768 Mutex::Autolock _l(mLock);
Eric Laurent4eb58f12018-12-07 16:41:02 -08001769 for (const auto &uid : mCachedUids) {
Eric Laurent47670c92019-08-28 16:59:05 -07001770 if (!isA11yUid(uid.first)) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001771 continue;
1772 }
Amith Yamasanibcbb3002019-01-23 13:53:33 -08001773 if (uid.second.second >= ActivityManager::PROCESS_STATE_TOP
1774 && uid.second.second <= ActivityManager::PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001775 return true;
1776 }
1777 }
1778 return false;
1779}
1780
Eric Laurentb78763e2018-10-17 10:08:02 -07001781bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
1782{
1783 std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid);
1784 return it != mA11yUids.end();
1785}
1786
Oscar Azucena829d90d2022-01-28 17:17:56 -08001787void AudioPolicyService::UidPolicy::setAssistantUids(const std::vector<uid_t>& uids) {
1788 mAssistantUids.clear();
1789 mAssistantUids = uids;
1790}
1791
1792bool AudioPolicyService::UidPolicy::isAssistantUid(uid_t uid)
1793{
1794 std::vector<uid_t>::iterator it = find(mAssistantUids.begin(), mAssistantUids.end(), uid);
1795 return it != mAssistantUids.end();
1796}
1797
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001798void AudioPolicyService::UidPolicy::setActiveAssistantUids(const std::vector<uid_t>& activeUids) {
1799 mActiveAssistantUids = activeUids;
1800}
1801
1802bool AudioPolicyService::UidPolicy::isActiveAssistantUid(uid_t uid)
1803{
1804 std::vector<uid_t>::iterator it = find(mActiveAssistantUids.begin(),
1805 mActiveAssistantUids.end(), uid);
1806 return it != mActiveAssistantUids.end();
1807}
1808
Oscar Azucena829d90d2022-01-28 17:17:56 -08001809void AudioPolicyService::UidPolicy::dumpInternals(int fd) {
1810 const size_t SIZE = 256;
1811 char buffer[SIZE];
1812 String8 result;
1813 auto appendUidsToResult = [&](const char* title, const std::vector<uid_t> &uids) {
1814 snprintf(buffer, SIZE, "\t%s: \n", title);
1815 result.append(buffer);
1816 int counter = 0;
1817 if (uids.empty()) {
1818 snprintf(buffer, SIZE, "\t\tNo UIDs present.\n");
1819 result.append(buffer);
1820 return;
1821 }
1822 for (const auto &uid : uids) {
1823 snprintf(buffer, SIZE, "\t\tUID[%d]=%d\n", counter++, uid);
1824 result.append(buffer);
1825 }
1826 };
1827
1828 snprintf(buffer, SIZE, "UID Policy:\n");
1829 result.append(buffer);
1830 snprintf(buffer, SIZE, "\tmObserverRegistered=%s\n",(mObserverRegistered ? "True":"False"));
1831 result.append(buffer);
1832
1833 appendUidsToResult("Assistants UIDs", mAssistantUids);
Oscar Azucenac2cdda32022-01-31 19:10:39 -08001834 appendUidsToResult("Active Assistants UIDs", mActiveAssistantUids);
Oscar Azucena829d90d2022-01-28 17:17:56 -08001835
1836 appendUidsToResult("Accessibility UIDs", mA11yUids);
1837
1838 snprintf(buffer, SIZE, "\tInput Method Service UID=%d\n", mCurrentImeUid);
1839 result.append(buffer);
1840
1841 snprintf(buffer, SIZE, "\tIs RTT Enabled: %s\n", (mRttEnabled ? "True":"False"));
1842 result.append(buffer);
1843
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001844 write(fd, result.c_str(), result.size());
Oscar Azucena829d90d2022-01-28 17:17:56 -08001845}
1846
Michael Groovercfd28302018-12-11 19:16:46 -08001847// ----------- AudioPolicyService::SensorPrivacyService implementation ----------
1848void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
1849 SensorPrivacyManager spm;
1850 mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
1851 spm.addSensorPrivacyListener(this);
1852}
1853
1854void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
1855 SensorPrivacyManager spm;
1856 spm.removeSensorPrivacyListener(this);
1857}
1858
1859bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
1860 return mSensorPrivacyEnabled;
1861}
1862
Evan Seversond8dc6832022-01-27 10:47:03 -08001863binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(
1864 int toggleType __unused, int sensor __unused, bool enabled) {
Michael Groovercfd28302018-12-11 19:16:46 -08001865 mSensorPrivacyEnabled = enabled;
1866 sp<AudioPolicyService> service = mService.promote();
1867 if (service != nullptr) {
1868 service->updateUidStates();
1869 }
1870 return binder::Status::ok();
1871}
1872
Mathias Agopian65ab4712010-07-14 17:59:35 -07001873// ----------- AudioPolicyService::AudioCommandThread implementation ----------
1874
Eric Laurentbfb1b832013-01-07 09:53:42 -08001875AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
1876 const wp<AudioPolicyService>& service)
1877 : Thread(false), mName(name), mService(service)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001878{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001879}
1880
1881
1882AudioPolicyService::AudioCommandThread::~AudioCommandThread()
1883{
Eric Laurentbfb1b832013-01-07 09:53:42 -08001884 if (!mAudioCommands.isEmpty()) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001885 release_wake_lock(mName.c_str());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001886 }
1887 mAudioCommands.clear();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001888}
1889
1890void AudioPolicyService::AudioCommandThread::onFirstRef()
1891{
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001892 run(mName.c_str(), ANDROID_PRIORITY_AUDIO);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001893}
1894
1895bool AudioPolicyService::AudioCommandThread::threadLoop()
1896{
Eric Laurentd7eda8d2016-02-02 17:18:39 -08001897 nsecs_t waitTime = -1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001898
1899 mLock.lock();
1900 while (!exitPending())
1901 {
Eric Laurent59a89232014-06-08 14:14:17 -07001902 sp<AudioPolicyService> svc;
Ytai Ben-Tsvi6958b022022-04-26 15:45:53 -07001903 int numTimesBecameEmpty = 0;
Eric Laurent59a89232014-06-08 14:14:17 -07001904 while (!mAudioCommands.isEmpty() && !exitPending()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001905 nsecs_t curTime = systemTime();
1906 // commands are sorted by increasing time stamp: execute them from index 0 and up
1907 if (mAudioCommands[0]->mTime <= curTime) {
Eric Laurent0ede8922014-05-09 18:04:42 -07001908 sp<AudioCommand> command = mAudioCommands[0];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001909 mAudioCommands.removeAt(0);
Ytai Ben-Tsvi6958b022022-04-26 15:45:53 -07001910 if (mAudioCommands.isEmpty()) {
1911 ++numTimesBecameEmpty;
1912 }
Eric Laurent0ede8922014-05-09 18:04:42 -07001913 mLastCommand = command;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001914
1915 switch (command->mCommand) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001916 case SET_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001917 VolumeData *data = (VolumeData *)command->mParam.get();
Steve Block3856b092011-10-20 11:56:00 +01001918 ALOGV("AudioCommandThread() processing set volume stream %d, \
Eric Laurentde070132010-07-13 04:45:46 -07001919 volume %f, output %d", data->mStream, data->mVolume, data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07001920 mLock.unlock();
Eric Laurentde070132010-07-13 04:45:46 -07001921 command->mStatus = AudioSystem::setStreamVolume(data->mStream,
1922 data->mVolume,
1923 data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07001924 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001925 }break;
1926 case SET_PARAMETERS: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001927 ParametersData *data = (ParametersData *)command->mParam.get();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07001928 ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00001929 data->mKeyValuePairs.c_str(), data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07001930 mLock.unlock();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07001931 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
Andy Hungfe726a62018-09-27 15:17:25 -07001932 mLock.lock();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07001933 }break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001934 case SET_VOICE_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001935 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
Steve Block3856b092011-10-20 11:56:00 +01001936 ALOGV("AudioCommandThread() processing set voice volume volume %f",
Eric Laurentde070132010-07-13 04:45:46 -07001937 data->mVolume);
Andy Hungfe726a62018-09-27 15:17:25 -07001938 mLock.unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001939 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
Andy Hungfe726a62018-09-27 15:17:25 -07001940 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001941 }break;
Eric Laurentbfb1b832013-01-07 09:53:42 -08001942 case STOP_OUTPUT: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001943 StopOutputData *data = (StopOutputData *)command->mParam.get();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001944 ALOGV("AudioCommandThread() processing stop output portId %d",
1945 data->mPortId);
Eric Laurent59a89232014-06-08 14:14:17 -07001946 svc = mService.promote();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001947 if (svc == 0) {
1948 break;
1949 }
1950 mLock.unlock();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001951 svc->doStopOutput(data->mPortId);
Eric Laurentbfb1b832013-01-07 09:53:42 -08001952 mLock.lock();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001953 }break;
1954 case RELEASE_OUTPUT: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001955 ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001956 ALOGV("AudioCommandThread() processing release output portId %d",
1957 data->mPortId);
Eric Laurent59a89232014-06-08 14:14:17 -07001958 svc = mService.promote();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001959 if (svc == 0) {
1960 break;
1961 }
1962 mLock.unlock();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001963 svc->doReleaseOutput(data->mPortId);
Eric Laurentbfb1b832013-01-07 09:53:42 -08001964 mLock.lock();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001965 }break;
Eric Laurent951f4552014-05-20 10:48:17 -07001966 case CREATE_AUDIO_PATCH: {
1967 CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
1968 ALOGV("AudioCommandThread() processing create audio patch");
1969 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1970 if (af == 0) {
1971 command->mStatus = PERMISSION_DENIED;
1972 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07001973 mLock.unlock();
Eric Laurent951f4552014-05-20 10:48:17 -07001974 command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
Andy Hungfe726a62018-09-27 15:17:25 -07001975 mLock.lock();
Eric Laurent951f4552014-05-20 10:48:17 -07001976 }
1977 } break;
1978 case RELEASE_AUDIO_PATCH: {
1979 ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
1980 ALOGV("AudioCommandThread() processing release audio patch");
1981 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1982 if (af == 0) {
1983 command->mStatus = PERMISSION_DENIED;
1984 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07001985 mLock.unlock();
Eric Laurent951f4552014-05-20 10:48:17 -07001986 command->mStatus = af->releaseAudioPatch(data->mHandle);
Andy Hungfe726a62018-09-27 15:17:25 -07001987 mLock.lock();
Eric Laurent951f4552014-05-20 10:48:17 -07001988 }
1989 } break;
Eric Laurentb52c1522014-05-20 11:27:36 -07001990 case UPDATE_AUDIOPORT_LIST: {
1991 ALOGV("AudioCommandThread() processing update audio port list");
Eric Laurent59a89232014-06-08 14:14:17 -07001992 svc = mService.promote();
Eric Laurentb52c1522014-05-20 11:27:36 -07001993 if (svc == 0) {
1994 break;
1995 }
1996 mLock.unlock();
1997 svc->doOnAudioPortListUpdate();
1998 mLock.lock();
1999 }break;
2000 case UPDATE_AUDIOPATCH_LIST: {
2001 ALOGV("AudioCommandThread() processing update audio patch list");
Eric Laurent59a89232014-06-08 14:14:17 -07002002 svc = mService.promote();
Eric Laurentb52c1522014-05-20 11:27:36 -07002003 if (svc == 0) {
2004 break;
2005 }
2006 mLock.unlock();
2007 svc->doOnAudioPatchListUpdate();
2008 mLock.lock();
2009 }break;
François Gaffiecfe17322018-11-07 13:41:29 +01002010 case CHANGED_AUDIOVOLUMEGROUP: {
2011 AudioVolumeGroupData *data =
2012 static_cast<AudioVolumeGroupData *>(command->mParam.get());
2013 ALOGV("AudioCommandThread() processing update audio volume group");
2014 svc = mService.promote();
2015 if (svc == 0) {
2016 break;
2017 }
2018 mLock.unlock();
2019 svc->doOnAudioVolumeGroupChanged(data->mGroup, data->mFlags);
2020 mLock.lock();
2021 }break;
Eric Laurente1715a42014-05-20 11:30:42 -07002022 case SET_AUDIOPORT_CONFIG: {
2023 SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
2024 ALOGV("AudioCommandThread() processing set port config");
2025 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
2026 if (af == 0) {
2027 command->mStatus = PERMISSION_DENIED;
2028 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07002029 mLock.unlock();
Eric Laurente1715a42014-05-20 11:30:42 -07002030 command->mStatus = af->setAudioPortConfig(&data->mConfig);
Andy Hungfe726a62018-09-27 15:17:25 -07002031 mLock.lock();
Eric Laurente1715a42014-05-20 11:30:42 -07002032 }
2033 } break;
Jean-Michel Trivide801052015-04-14 19:10:14 -07002034 case DYN_POLICY_MIX_STATE_UPDATE: {
2035 DynPolicyMixStateUpdateData *data =
2036 (DynPolicyMixStateUpdateData *)command->mParam.get();
Jean-Michel Trivide801052015-04-14 19:10:14 -07002037 ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002038 data->mRegId.c_str(), data->mState);
Jean-Michel Trivide801052015-04-14 19:10:14 -07002039 svc = mService.promote();
2040 if (svc == 0) {
2041 break;
2042 }
2043 mLock.unlock();
2044 svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
2045 mLock.lock();
2046 } break;
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002047 case RECORDING_CONFIGURATION_UPDATE: {
2048 RecordingConfigurationUpdateData *data =
2049 (RecordingConfigurationUpdateData *)command->mParam.get();
2050 ALOGV("AudioCommandThread() processing recording configuration update");
2051 svc = mService.promote();
2052 if (svc == 0) {
2053 break;
2054 }
2055 mLock.unlock();
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002056 svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -08002057 &data->mClientConfig, data->mClientEffects,
2058 &data->mDeviceConfig, data->mEffects,
2059 data->mPatchHandle, data->mSource);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002060 mLock.lock();
2061 } break;
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002062 case SET_EFFECT_SUSPENDED: {
2063 SetEffectSuspendedData *data = (SetEffectSuspendedData *)command->mParam.get();
2064 ALOGV("AudioCommandThread() processing set effect suspended");
2065 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
2066 if (af != 0) {
2067 mLock.unlock();
2068 af->setEffectSuspended(data->mEffectId, data->mSessionId, data->mSuspended);
2069 mLock.lock();
2070 }
2071 } break;
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002072 case AUDIO_MODULES_UPDATE: {
2073 ALOGV("AudioCommandThread() processing audio modules update");
2074 svc = mService.promote();
2075 if (svc == 0) {
2076 break;
2077 }
2078 mLock.unlock();
2079 svc->doOnNewAudioModulesAvailable();
2080 mLock.lock();
2081 } break;
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002082 case ROUTING_UPDATED: {
2083 ALOGV("AudioCommandThread() processing routing update");
2084 svc = mService.promote();
2085 if (svc == 0) {
2086 break;
2087 }
2088 mLock.unlock();
2089 svc->doOnRoutingUpdated();
2090 mLock.lock();
2091 } break;
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002092
Eric Laurented726cc2021-07-01 14:26:41 +02002093 case UPDATE_UID_STATES: {
2094 ALOGV("AudioCommandThread() processing updateUID states");
2095 svc = mService.promote();
2096 if (svc == 0) {
2097 break;
2098 }
2099 mLock.unlock();
2100 svc->updateUidStates();
2101 mLock.lock();
2102 } break;
2103
Eric Laurent15903592022-02-24 20:44:36 +01002104 case CHECK_SPATIALIZER_OUTPUT: {
2105 ALOGV("AudioCommandThread() processing check spatializer");
Eric Laurent81dd0f52021-07-05 11:54:40 +02002106 svc = mService.promote();
2107 if (svc == 0) {
2108 break;
2109 }
2110 mLock.unlock();
2111 svc->doOnCheckSpatializer();
2112 mLock.lock();
2113 } break;
2114
Eric Laurent15903592022-02-24 20:44:36 +01002115 case UPDATE_ACTIVE_SPATIALIZER_TRACKS: {
2116 ALOGV("AudioCommandThread() processing update spatializer tracks");
2117 svc = mService.promote();
2118 if (svc == 0) {
2119 break;
2120 }
2121 mLock.unlock();
2122 svc->doOnUpdateActiveSpatializerTracks();
2123 mLock.lock();
2124 } break;
2125
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +00002126 case VOL_RANGE_INIT_REQUEST: {
2127 ALOGV("AudioCommandThread() processing volume range init request");
2128 svc = mService.promote();
2129 if (svc == 0) {
2130 break;
2131 }
2132 mLock.unlock();
2133 svc->doOnVolumeRangeInitRequest();
2134 mLock.lock();
2135 } break;
2136
Mathias Agopian65ab4712010-07-14 17:59:35 -07002137 default:
Steve Block5ff1dd52012-01-05 23:22:43 +00002138 ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002139 }
Eric Laurent0ede8922014-05-09 18:04:42 -07002140 {
2141 Mutex::Autolock _l(command->mLock);
2142 if (command->mWaitStatus) {
2143 command->mWaitStatus = false;
2144 command->mCond.signal();
2145 }
2146 }
Eric Laurentd7eda8d2016-02-02 17:18:39 -08002147 waitTime = -1;
Zach Janga754b4f2015-10-27 01:29:34 +00002148 // release mLock before releasing strong reference on the service as
2149 // AudioPolicyService destructor calls AudioCommandThread::exit() which
2150 // acquires mLock.
2151 mLock.unlock();
2152 svc.clear();
2153 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002154 } else {
2155 waitTime = mAudioCommands[0]->mTime - curTime;
2156 break;
2157 }
2158 }
Zach Janga754b4f2015-10-27 01:29:34 +00002159
Ytai Ben-Tsvi6958b022022-04-26 15:45:53 -07002160 // release delayed commands wake lock as many times as we made the queue is
2161 // empty during popping.
2162 while (numTimesBecameEmpty--) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002163 release_wake_lock(mName.c_str());
Zach Janga754b4f2015-10-27 01:29:34 +00002164 }
2165
2166 // At this stage we have either an empty command queue or the first command in the queue
2167 // has a finite delay. So unless we are exiting it is safe to wait.
2168 if (!exitPending()) {
Eric Laurent59a89232014-06-08 14:14:17 -07002169 ALOGV("AudioCommandThread() going to sleep");
Eric Laurentd7eda8d2016-02-02 17:18:39 -08002170 if (waitTime == -1) {
2171 mWaitWorkCV.wait(mLock);
2172 } else {
2173 mWaitWorkCV.waitRelative(mLock, waitTime);
2174 }
Eric Laurent59a89232014-06-08 14:14:17 -07002175 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002176 }
Ricardo Garcia05f2fdc2014-07-24 15:48:24 -07002177 // release delayed commands wake lock before quitting
2178 if (!mAudioCommands.isEmpty()) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002179 release_wake_lock(mName.c_str());
Ricardo Garcia05f2fdc2014-07-24 15:48:24 -07002180 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002181 mLock.unlock();
2182 return false;
2183}
2184
2185status_t AudioPolicyService::AudioCommandThread::dump(int fd)
2186{
2187 const size_t SIZE = 256;
2188 char buffer[SIZE];
2189 String8 result;
2190
Mikhail Naganov12b716c2020-04-30 22:37:43 +00002191 const bool locked = dumpTryLock(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002192 if (!locked) {
2193 String8 result2(kCmdDeadlockedString);
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002194 write(fd, result2.c_str(), result2.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002195 }
2196
2197 snprintf(buffer, SIZE, "- Commands:\n");
2198 result = String8(buffer);
2199 result.append(" Command Time Wait pParam\n");
Glenn Kasten8d6a2442012-02-08 14:04:28 -08002200 for (size_t i = 0; i < mAudioCommands.size(); i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002201 mAudioCommands[i]->dump(buffer, SIZE);
2202 result.append(buffer);
2203 }
2204 result.append(" Last Command\n");
Eric Laurent0ede8922014-05-09 18:04:42 -07002205 if (mLastCommand != 0) {
2206 mLastCommand->dump(buffer, SIZE);
2207 result.append(buffer);
2208 } else {
2209 result.append(" none\n");
2210 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002211
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002212 write(fd, result.c_str(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002213
Mikhail Naganov12b716c2020-04-30 22:37:43 +00002214 dumpReleaseLock(mLock, locked);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002215
2216 return NO_ERROR;
2217}
2218
Glenn Kastenfff6d712012-01-12 16:38:12 -08002219status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
Eric Laurentde070132010-07-13 04:45:46 -07002220 float volume,
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002221 audio_io_handle_t output,
Eric Laurentde070132010-07-13 04:45:46 -07002222 int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002223{
Eric Laurent0ede8922014-05-09 18:04:42 -07002224 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002225 command->mCommand = SET_VOLUME;
Eric Laurent0ede8922014-05-09 18:04:42 -07002226 sp<VolumeData> data = new VolumeData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002227 data->mStream = stream;
2228 data->mVolume = volume;
2229 data->mIO = output;
2230 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07002231 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01002232 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
Eric Laurentde070132010-07-13 04:45:46 -07002233 stream, volume, output);
Eric Laurent0ede8922014-05-09 18:04:42 -07002234 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002235}
2236
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002237status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
Dima Zavinfce7a472011-04-19 22:30:36 -07002238 const char *keyValuePairs,
Eric Laurentde070132010-07-13 04:45:46 -07002239 int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002240{
Eric Laurent0ede8922014-05-09 18:04:42 -07002241 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002242 command->mCommand = SET_PARAMETERS;
Eric Laurent0ede8922014-05-09 18:04:42 -07002243 sp<ParametersData> data = new ParametersData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002244 data->mIO = ioHandle;
Dima Zavinfce7a472011-04-19 22:30:36 -07002245 data->mKeyValuePairs = String8(keyValuePairs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002246 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07002247 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01002248 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
Dima Zavinfce7a472011-04-19 22:30:36 -07002249 keyValuePairs, ioHandle, delayMs);
Eric Laurent0ede8922014-05-09 18:04:42 -07002250 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002251}
2252
2253status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
2254{
Eric Laurent0ede8922014-05-09 18:04:42 -07002255 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002256 command->mCommand = SET_VOICE_VOLUME;
Eric Laurent0ede8922014-05-09 18:04:42 -07002257 sp<VoiceVolumeData> data = new VoiceVolumeData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002258 data->mVolume = volume;
2259 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07002260 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01002261 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
Eric Laurent0ede8922014-05-09 18:04:42 -07002262 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002263}
2264
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002265void AudioPolicyService::AudioCommandThread::setEffectSuspendedCommand(int effectId,
2266 audio_session_t sessionId,
2267 bool suspended)
2268{
2269 sp<AudioCommand> command = new AudioCommand();
2270 command->mCommand = SET_EFFECT_SUSPENDED;
2271 sp<SetEffectSuspendedData> data = new SetEffectSuspendedData();
2272 data->mEffectId = effectId;
2273 data->mSessionId = sessionId;
2274 data->mSuspended = suspended;
2275 command->mParam = data;
2276 ALOGV("AudioCommandThread() adding set suspended effectId %d sessionId %d suspended %d",
2277 effectId, sessionId, suspended);
2278 sendCommand(command);
2279}
2280
2281
Eric Laurentd7fe0862018-07-14 16:48:01 -07002282void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_port_handle_t portId)
Eric Laurentbfb1b832013-01-07 09:53:42 -08002283{
Eric Laurent0ede8922014-05-09 18:04:42 -07002284 sp<AudioCommand> command = new AudioCommand();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002285 command->mCommand = STOP_OUTPUT;
Eric Laurent0ede8922014-05-09 18:04:42 -07002286 sp<StopOutputData> data = new StopOutputData();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002287 data->mPortId = portId;
Jesper Tragardh48412dc2014-03-24 14:12:43 +01002288 command->mParam = data;
Eric Laurentd7fe0862018-07-14 16:48:01 -07002289 ALOGV("AudioCommandThread() adding stop output portId %d", portId);
Eric Laurent0ede8922014-05-09 18:04:42 -07002290 sendCommand(command);
Eric Laurentbfb1b832013-01-07 09:53:42 -08002291}
2292
Eric Laurentd7fe0862018-07-14 16:48:01 -07002293void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_port_handle_t portId)
Eric Laurentbfb1b832013-01-07 09:53:42 -08002294{
Eric Laurent0ede8922014-05-09 18:04:42 -07002295 sp<AudioCommand> command = new AudioCommand();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002296 command->mCommand = RELEASE_OUTPUT;
Eric Laurent0ede8922014-05-09 18:04:42 -07002297 sp<ReleaseOutputData> data = new ReleaseOutputData();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002298 data->mPortId = portId;
Jesper Tragardh48412dc2014-03-24 14:12:43 +01002299 command->mParam = data;
Eric Laurentd7fe0862018-07-14 16:48:01 -07002300 ALOGV("AudioCommandThread() adding release output portId %d", portId);
Eric Laurent0ede8922014-05-09 18:04:42 -07002301 sendCommand(command);
2302}
2303
Eric Laurent951f4552014-05-20 10:48:17 -07002304status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
2305 const struct audio_patch *patch,
2306 audio_patch_handle_t *handle,
2307 int delayMs)
2308{
2309 status_t status = NO_ERROR;
2310
2311 sp<AudioCommand> command = new AudioCommand();
2312 command->mCommand = CREATE_AUDIO_PATCH;
2313 CreateAudioPatchData *data = new CreateAudioPatchData();
2314 data->mPatch = *patch;
2315 data->mHandle = *handle;
2316 command->mParam = data;
2317 command->mWaitStatus = true;
2318 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
2319 status = sendCommand(command, delayMs);
2320 if (status == NO_ERROR) {
2321 *handle = data->mHandle;
2322 }
2323 return status;
2324}
2325
2326status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
2327 int delayMs)
2328{
2329 sp<AudioCommand> command = new AudioCommand();
2330 command->mCommand = RELEASE_AUDIO_PATCH;
2331 ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
2332 data->mHandle = handle;
2333 command->mParam = data;
2334 command->mWaitStatus = true;
2335 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
2336 return sendCommand(command, delayMs);
2337}
2338
Eric Laurentb52c1522014-05-20 11:27:36 -07002339void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
2340{
2341 sp<AudioCommand> command = new AudioCommand();
2342 command->mCommand = UPDATE_AUDIOPORT_LIST;
2343 ALOGV("AudioCommandThread() adding update audio port list");
2344 sendCommand(command);
2345}
2346
Eric Laurented726cc2021-07-01 14:26:41 +02002347void AudioPolicyService::AudioCommandThread::updateUidStatesCommand()
2348{
2349 sp<AudioCommand> command = new AudioCommand();
2350 command->mCommand = UPDATE_UID_STATES;
2351 ALOGV("AudioCommandThread() adding update UID states");
2352 sendCommand(command);
2353}
2354
Eric Laurentb52c1522014-05-20 11:27:36 -07002355void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
2356{
2357 sp<AudioCommand>command = new AudioCommand();
2358 command->mCommand = UPDATE_AUDIOPATCH_LIST;
2359 ALOGV("AudioCommandThread() adding update audio patch list");
2360 sendCommand(command);
2361}
2362
François Gaffiecfe17322018-11-07 13:41:29 +01002363void AudioPolicyService::AudioCommandThread::changeAudioVolumeGroupCommand(volume_group_t group,
2364 int flags)
2365{
2366 sp<AudioCommand>command = new AudioCommand();
2367 command->mCommand = CHANGED_AUDIOVOLUMEGROUP;
2368 AudioVolumeGroupData *data= new AudioVolumeGroupData();
2369 data->mGroup = group;
2370 data->mFlags = flags;
2371 command->mParam = data;
2372 ALOGV("AudioCommandThread() adding audio volume group changed");
2373 sendCommand(command);
2374}
2375
Eric Laurente1715a42014-05-20 11:30:42 -07002376status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
2377 const struct audio_port_config *config, int delayMs)
2378{
2379 sp<AudioCommand> command = new AudioCommand();
2380 command->mCommand = SET_AUDIOPORT_CONFIG;
2381 SetAudioPortConfigData *data = new SetAudioPortConfigData();
2382 data->mConfig = *config;
2383 command->mParam = data;
2384 command->mWaitStatus = true;
2385 ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
2386 return sendCommand(command, delayMs);
2387}
2388
Jean-Michel Trivide801052015-04-14 19:10:14 -07002389void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07002390 const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -07002391{
2392 sp<AudioCommand> command = new AudioCommand();
2393 command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
2394 DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
2395 data->mRegId = regId;
2396 data->mState = state;
2397 command->mParam = data;
2398 ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002399 regId.c_str(), state);
Jean-Michel Trivide801052015-04-14 19:10:14 -07002400 sendCommand(command);
2401}
2402
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002403void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
Eric Laurenta9f86652018-11-28 17:23:11 -08002404 int event,
2405 const record_client_info_t *clientInfo,
2406 const audio_config_base_t *clientConfig,
2407 std::vector<effect_descriptor_t> clientEffects,
2408 const audio_config_base_t *deviceConfig,
2409 std::vector<effect_descriptor_t> effects,
2410 audio_patch_handle_t patchHandle,
2411 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002412{
2413 sp<AudioCommand>command = new AudioCommand();
2414 command->mCommand = RECORDING_CONFIGURATION_UPDATE;
2415 RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
2416 data->mEvent = event;
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002417 data->mClientInfo = *clientInfo;
Jean-Michel Trivi7281aa92016-02-17 15:33:40 -08002418 data->mClientConfig = *clientConfig;
Eric Laurenta9f86652018-11-28 17:23:11 -08002419 data->mClientEffects = clientEffects;
Jean-Michel Trivi7281aa92016-02-17 15:33:40 -08002420 data->mDeviceConfig = *deviceConfig;
Eric Laurenta9f86652018-11-28 17:23:11 -08002421 data->mEffects = effects;
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08002422 data->mPatchHandle = patchHandle;
Eric Laurenta9f86652018-11-28 17:23:11 -08002423 data->mSource = source;
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002424 command->mParam = data;
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002425 ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
2426 event, clientInfo->source, clientInfo->uid);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002427 sendCommand(command);
2428}
2429
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002430void AudioPolicyService::AudioCommandThread::audioModulesUpdateCommand()
2431{
2432 sp<AudioCommand> command = new AudioCommand();
2433 command->mCommand = AUDIO_MODULES_UPDATE;
2434 sendCommand(command);
2435}
2436
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002437void AudioPolicyService::AudioCommandThread::routingChangedCommand()
2438{
2439 sp<AudioCommand>command = new AudioCommand();
2440 command->mCommand = ROUTING_UPDATED;
2441 ALOGV("AudioCommandThread() adding routing update");
2442 sendCommand(command);
2443}
2444
Eric Laurent81dd0f52021-07-05 11:54:40 +02002445void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
2446{
2447 sp<AudioCommand>command = new AudioCommand();
Eric Laurent15903592022-02-24 20:44:36 +01002448 command->mCommand = CHECK_SPATIALIZER_OUTPUT;
Eric Laurent81dd0f52021-07-05 11:54:40 +02002449 ALOGV("AudioCommandThread() adding check spatializer");
2450 sendCommand(command);
2451}
2452
Eric Laurent15903592022-02-24 20:44:36 +01002453void AudioPolicyService::AudioCommandThread::updateActiveSpatializerTracksCommand()
2454{
2455 sp<AudioCommand>command = new AudioCommand();
2456 command->mCommand = UPDATE_ACTIVE_SPATIALIZER_TRACKS;
2457 ALOGV("AudioCommandThread() adding update active spatializer tracks");
2458 sendCommand(command);
2459}
2460
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +00002461void AudioPolicyService::AudioCommandThread::volRangeInitReqCommand()
2462{
2463 sp<AudioCommand>command = new AudioCommand();
2464 command->mCommand = VOL_RANGE_INIT_REQUEST;
2465 ALOGV("AudioCommandThread() adding volume range init request");
2466 sendCommand(command);
2467}
2468
Eric Laurent0ede8922014-05-09 18:04:42 -07002469status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
2470{
2471 {
2472 Mutex::Autolock _l(mLock);
2473 insertCommand_l(command, delayMs);
2474 mWaitWorkCV.signal();
2475 }
2476 Mutex::Autolock _l(command->mLock);
2477 while (command->mWaitStatus) {
2478 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
2479 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
2480 command->mStatus = TIMED_OUT;
2481 command->mWaitStatus = false;
2482 }
2483 }
2484 return command->mStatus;
Eric Laurentbfb1b832013-01-07 09:53:42 -08002485}
2486
Mathias Agopian65ab4712010-07-14 17:59:35 -07002487// insertCommand_l() must be called with mLock held
Eric Laurent0ede8922014-05-09 18:04:42 -07002488void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002489{
Glenn Kasten8d6a2442012-02-08 14:04:28 -08002490 ssize_t i; // not size_t because i will count down to -1
Eric Laurent0ede8922014-05-09 18:04:42 -07002491 Vector < sp<AudioCommand> > removedCommands;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002492 command->mTime = systemTime() + milliseconds(delayMs);
2493
2494 // acquire wake lock to make sure delayed commands are processed
Eric Laurentbfb1b832013-01-07 09:53:42 -08002495 if (mAudioCommands.isEmpty()) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002496 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.c_str());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002497 }
2498
2499 // check same pending commands with later time stamps and eliminate them
Ivan Lozano5ff158f2017-10-30 09:06:24 -07002500 for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002501 sp<AudioCommand> command2 = mAudioCommands[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07002502 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
2503 if (command2->mTime <= command->mTime) break;
Eric Laurente45b48a2014-09-04 16:40:57 -07002504
2505 // create audio patch or release audio patch commands are equivalent
2506 // with regard to filtering
2507 if ((command->mCommand == CREATE_AUDIO_PATCH) ||
2508 (command->mCommand == RELEASE_AUDIO_PATCH)) {
2509 if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
2510 (command2->mCommand != RELEASE_AUDIO_PATCH)) {
2511 continue;
2512 }
2513 } else if (command2->mCommand != command->mCommand) continue;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002514
2515 switch (command->mCommand) {
2516 case SET_PARAMETERS: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002517 ParametersData *data = (ParametersData *)command->mParam.get();
2518 ParametersData *data2 = (ParametersData *)command2->mParam.get();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002519 if (data->mIO != data2->mIO) break;
Steve Block3856b092011-10-20 11:56:00 +01002520 ALOGV("Comparing parameter command %s to new command %s",
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002521 data2->mKeyValuePairs.c_str(), data->mKeyValuePairs.c_str());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002522 AudioParameter param = AudioParameter(data->mKeyValuePairs);
2523 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
2524 for (size_t j = 0; j < param.size(); j++) {
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002525 String8 key;
2526 String8 value;
2527 param.getAt(j, key, value);
2528 for (size_t k = 0; k < param2.size(); k++) {
2529 String8 key2;
2530 String8 value2;
2531 param2.getAt(k, key2, value2);
2532 if (key2 == key) {
2533 param2.remove(key2);
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +00002534 ALOGV("Filtering out parameter %s", key2.c_str());
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002535 break;
2536 }
2537 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002538 }
2539 // if all keys have been filtered out, remove the command.
2540 // otherwise, update the key value pairs
2541 if (param2.size() == 0) {
2542 removedCommands.add(command2);
2543 } else {
2544 data2->mKeyValuePairs = param2.toString();
2545 }
Eric Laurent21e54562013-09-23 12:08:05 -07002546 command->mTime = command2->mTime;
2547 // force delayMs to non 0 so that code below does not request to wait for
2548 // command status as the command is now delayed
2549 delayMs = 1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002550 } break;
2551
2552 case SET_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002553 VolumeData *data = (VolumeData *)command->mParam.get();
2554 VolumeData *data2 = (VolumeData *)command2->mParam.get();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002555 if (data->mIO != data2->mIO) break;
2556 if (data->mStream != data2->mStream) break;
Steve Block3856b092011-10-20 11:56:00 +01002557 ALOGV("Filtering out volume command on output %d for stream %d",
Eric Laurentde070132010-07-13 04:45:46 -07002558 data->mIO, data->mStream);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002559 removedCommands.add(command2);
Eric Laurent21e54562013-09-23 12:08:05 -07002560 command->mTime = command2->mTime;
2561 // force delayMs to non 0 so that code below does not request to wait for
2562 // command status as the command is now delayed
2563 delayMs = 1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002564 } break;
Eric Laurente45b48a2014-09-04 16:40:57 -07002565
Eric Laurentbaf35fe2016-07-27 15:36:53 -07002566 case SET_VOICE_VOLUME: {
2567 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
2568 VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
2569 ALOGV("Filtering out voice volume command value %f replaced by %f",
2570 data2->mVolume, data->mVolume);
2571 removedCommands.add(command2);
2572 command->mTime = command2->mTime;
2573 // force delayMs to non 0 so that code below does not request to wait for
2574 // command status as the command is now delayed
2575 delayMs = 1;
2576 } break;
2577
Eric Laurente45b48a2014-09-04 16:40:57 -07002578 case CREATE_AUDIO_PATCH:
2579 case RELEASE_AUDIO_PATCH: {
2580 audio_patch_handle_t handle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002581 struct audio_patch patch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002582 if (command->mCommand == CREATE_AUDIO_PATCH) {
2583 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002584 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002585 } else {
2586 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
Mikhail Naganov7be71d22018-05-23 16:51:46 -07002587 memset(&patch, 0, sizeof(patch));
Eric Laurente45b48a2014-09-04 16:40:57 -07002588 }
2589 audio_patch_handle_t handle2;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002590 struct audio_patch patch2;
Eric Laurente45b48a2014-09-04 16:40:57 -07002591 if (command2->mCommand == CREATE_AUDIO_PATCH) {
2592 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002593 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002594 } else {
2595 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
Glenn Kastenf60b6b62015-07-06 10:53:26 -07002596 memset(&patch2, 0, sizeof(patch2));
Eric Laurente45b48a2014-09-04 16:40:57 -07002597 }
2598 if (handle != handle2) break;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002599 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
2600 same output. */
2601 if( (command->mCommand == CREATE_AUDIO_PATCH) &&
2602 (command2->mCommand == CREATE_AUDIO_PATCH) ) {
2603 bool isOutputDiff = false;
2604 if (patch.num_sources == patch2.num_sources) {
2605 for (unsigned count = 0; count < patch.num_sources; count++) {
2606 if (patch.sources[count].id != patch2.sources[count].id) {
2607 isOutputDiff = true;
2608 break;
2609 }
2610 }
2611 if (isOutputDiff)
2612 break;
2613 }
2614 }
Eric Laurente45b48a2014-09-04 16:40:57 -07002615 ALOGV("Filtering out %s audio patch command for handle %d",
2616 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
2617 removedCommands.add(command2);
2618 command->mTime = command2->mTime;
2619 // force delayMs to non 0 so that code below does not request to wait for
2620 // command status as the command is now delayed
2621 delayMs = 1;
2622 } break;
2623
Jean-Michel Trivide801052015-04-14 19:10:14 -07002624 case DYN_POLICY_MIX_STATE_UPDATE: {
2625
2626 } break;
2627
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002628 case RECORDING_CONFIGURATION_UPDATE: {
2629
2630 } break;
2631
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002632 case ROUTING_UPDATED: {
2633
2634 } break;
2635
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +00002636 case VOL_RANGE_INIT_REQUEST: {
2637 // command may come from different requests, do not filter
2638 } break;
2639
Mathias Agopian65ab4712010-07-14 17:59:35 -07002640 default:
2641 break;
2642 }
2643 }
2644
2645 // remove filtered commands
2646 for (size_t j = 0; j < removedCommands.size(); j++) {
2647 // removed commands always have time stamps greater than current command
2648 for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002649 if (mAudioCommands[k].get() == removedCommands[j].get()) {
Steve Block3856b092011-10-20 11:56:00 +01002650 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002651 mAudioCommands.removeAt(k);
2652 break;
2653 }
2654 }
2655 }
2656 removedCommands.clear();
2657
Eric Laurentaa79bef2015-01-15 14:33:51 -08002658 // Disable wait for status if delay is not 0.
2659 // Except for create audio patch command because the returned patch handle
2660 // is needed by audio policy manager
2661 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
Eric Laurentcec4abb2012-07-03 12:23:02 -07002662 command->mWaitStatus = false;
2663 }
Eric Laurentcec4abb2012-07-03 12:23:02 -07002664
Mathias Agopian65ab4712010-07-14 17:59:35 -07002665 // insert command at the right place according to its time stamp
Eric Laurent1e693b52014-07-09 15:03:28 -07002666 ALOGV("inserting command: %d at index %zd, num commands %zu",
2667 command->mCommand, i+1, mAudioCommands.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002668 mAudioCommands.insertAt(command, i + 1);
2669}
2670
2671void AudioPolicyService::AudioCommandThread::exit()
2672{
Steve Block3856b092011-10-20 11:56:00 +01002673 ALOGV("AudioCommandThread::exit");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002674 {
2675 AutoMutex _l(mLock);
2676 requestExit();
2677 mWaitWorkCV.signal();
2678 }
Zach Janga754b4f2015-10-27 01:29:34 +00002679 // Note that we can call it from the thread loop if all other references have been released
2680 // but it will safely return WOULD_BLOCK in this case
Mathias Agopian65ab4712010-07-14 17:59:35 -07002681 requestExitAndWait();
2682}
2683
2684void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
2685{
2686 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n",
2687 mCommand,
2688 (int)ns2s(mTime),
2689 (int)ns2ms(mTime)%1000,
2690 mWaitStatus,
Eric Laurent0ede8922014-05-09 18:04:42 -07002691 mParam.get());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002692}
2693
Dima Zavinfce7a472011-04-19 22:30:36 -07002694/******* helpers for the service_ops callbacks defined below *********/
2695void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
2696 const char *keyValuePairs,
2697 int delayMs)
2698{
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002699 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
Dima Zavinfce7a472011-04-19 22:30:36 -07002700 delayMs);
2701}
2702
2703int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
2704 float volume,
2705 audio_io_handle_t output,
2706 int delayMs)
2707{
Glenn Kastenfff6d712012-01-12 16:38:12 -08002708 return (int)mAudioCommandThread->volumeCommand(stream, volume,
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002709 output, delayMs);
Dima Zavinfce7a472011-04-19 22:30:36 -07002710}
2711
Dima Zavinfce7a472011-04-19 22:30:36 -07002712int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
2713{
2714 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
2715}
2716
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002717void AudioPolicyService::setEffectSuspended(int effectId,
2718 audio_session_t sessionId,
2719 bool suspended)
2720{
2721 mAudioCommandThread->setEffectSuspendedCommand(effectId, sessionId, suspended);
2722}
2723
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08002724Status AudioPolicyService::onNewAudioModulesAvailable()
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002725{
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002726 mOutputCommandThread->audioModulesUpdateCommand();
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08002727 return Status::ok();
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002728}
2729
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002730
Dima Zavinfce7a472011-04-19 22:30:36 -07002731extern "C" {
Eric Laurent2d388ec2014-03-07 13:25:54 -08002732audio_module_handle_t aps_load_hw_module(void *service __unused,
2733 const char *name);
2734audio_io_handle_t aps_open_output(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002735 audio_devices_t *pDevices,
2736 uint32_t *pSamplingRate,
2737 audio_format_t *pFormat,
2738 audio_channel_mask_t *pChannelMask,
2739 uint32_t *pLatencyMs,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002740 audio_output_flags_t flags);
Eric Laurenta4c5a552012-03-29 10:12:40 -07002741
Eric Laurent2d388ec2014-03-07 13:25:54 -08002742audio_io_handle_t aps_open_output_on_module(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002743 audio_module_handle_t module,
2744 audio_devices_t *pDevices,
2745 uint32_t *pSamplingRate,
2746 audio_format_t *pFormat,
2747 audio_channel_mask_t *pChannelMask,
2748 uint32_t *pLatencyMs,
Richard Fitzgeraldad3af332013-03-25 16:54:37 +00002749 audio_output_flags_t flags,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002750 const audio_offload_info_t *offloadInfo);
2751audio_io_handle_t aps_open_dup_output(void *service __unused,
Dima Zavinfce7a472011-04-19 22:30:36 -07002752 audio_io_handle_t output1,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002753 audio_io_handle_t output2);
2754int aps_close_output(void *service __unused, audio_io_handle_t output);
2755int aps_suspend_output(void *service __unused, audio_io_handle_t output);
2756int aps_restore_output(void *service __unused, audio_io_handle_t output);
2757audio_io_handle_t aps_open_input(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002758 audio_devices_t *pDevices,
2759 uint32_t *pSamplingRate,
2760 audio_format_t *pFormat,
2761 audio_channel_mask_t *pChannelMask,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002762 audio_in_acoustics_t acoustics __unused);
2763audio_io_handle_t aps_open_input_on_module(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002764 audio_module_handle_t module,
2765 audio_devices_t *pDevices,
2766 uint32_t *pSamplingRate,
2767 audio_format_t *pFormat,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002768 audio_channel_mask_t *pChannelMask);
2769int aps_close_input(void *service __unused, audio_io_handle_t input);
2770int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
Glenn Kastend848eb42016-03-08 13:42:11 -08002771int aps_move_effects(void *service __unused, audio_session_t session,
Dima Zavinfce7a472011-04-19 22:30:36 -07002772 audio_io_handle_t src_output,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002773 audio_io_handle_t dst_output);
2774char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
2775 const char *keys);
2776void aps_set_parameters(void *service, audio_io_handle_t io_handle,
2777 const char *kv_pairs, int delay_ms);
2778int aps_set_stream_volume(void *service, audio_stream_type_t stream,
Dima Zavinfce7a472011-04-19 22:30:36 -07002779 float volume, audio_io_handle_t output,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002780 int delay_ms);
Eric Laurent2d388ec2014-03-07 13:25:54 -08002781int aps_set_voice_volume(void *service, float volume, int delay_ms);
2782};
Dima Zavinfce7a472011-04-19 22:30:36 -07002783
Mikhail Naganov1b2a7942017-12-08 10:18:09 -08002784} // namespace android