blob: c21be1ede3468836e097d1ab89625210000d75d1 [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>
37#include "AudioPolicyService.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070038#include <hardware_legacy/power.h>
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -080039#include <media/AidlConversion.h>
Eric Laurent7c7f10b2011-06-17 21:29:58 -070040#include <media/AudioEffect.h>
Chih-Hung Hsiehc84d9d22014-11-14 13:33:34 -080041#include <media/AudioParameter.h>
Andy Hungab7ef302018-05-15 19:35:29 -070042#include <mediautils/ServiceUtilities.h>
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -080043#include <mediautils/TimeCheck.h>
Michael Groovercfd28302018-12-11 19:16:46 -080044#include <sensorprivacy/SensorPrivacyManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070045
Dima Zavin64760242011-05-11 14:15:23 -070046#include <system/audio.h>
Dima Zavin7394a4f2011-06-13 18:16:26 -070047#include <system/audio_policy.h>
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053048#include <AudioPolicyManager.h>
Mikhail Naganov61a4fac2016-10-13 14:44:18 -070049
Mathias Agopian65ab4712010-07-14 17:59:35 -070050namespace android {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -080051using binder::Status;
Mathias Agopian65ab4712010-07-14 17:59:35 -070052
Glenn Kasten8dad0e32012-01-09 08:41:22 -080053static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
54static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053055static const char kAudioPolicyManagerCustomPath[] = "libaudiopolicymanagercustom.so";
Mathias Agopian65ab4712010-07-14 17:59:35 -070056
Mikhail Naganov959e2d02019-03-28 11:08:19 -070057static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Mathias Agopian65ab4712010-07-14 17:59:35 -070058
Eric Laurent0ede8922014-05-09 18:04:42 -070059static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
Christer Fletcher5fa8c4b2013-01-18 15:27:03 +010060
Svet Ganovf4ddfef2018-01-16 07:37:58 -080061static const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY");
Dima Zavinfce7a472011-04-19 22:30:36 -070062
Mathias Agopian65ab4712010-07-14 17:59:35 -070063// ----------------------------------------------------------------------------
64
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053065static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
66{
67 AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
68 status_t status = apm->initialize();
69 if (status != NO_ERROR) {
70 delete apm;
71 apm = nullptr;
72 }
73 return apm;
74}
75
76static void destroyAudioPolicyManager(AudioPolicyInterface *interface)
77{
78 delete interface;
79}
80// ----------------------------------------------------------------------------
81
Mathias Agopian65ab4712010-07-14 17:59:35 -070082AudioPolicyService::AudioPolicyService()
Ytai Ben-Tsvi85093d52020-03-26 09:41:15 -070083 : BnAudioPolicyService(),
Ytai Ben-Tsvi85093d52020-03-26 09:41:15 -070084 mAudioPolicyManager(NULL),
85 mAudioPolicyClient(NULL),
86 mPhoneState(AUDIO_MODE_INVALID),
Jaideep Sharmaba9053b2021-01-25 21:24:26 +053087 mCaptureStateNotifier(false),
88 mCreateAudioPolicyManager(createAudioPolicyManager),
89 mDestroyAudioPolicyManager(destroyAudioPolicyManager) {
90}
91
92void AudioPolicyService::loadAudioPolicyManager()
93{
94 mLibraryHandle = dlopen(kAudioPolicyManagerCustomPath, RTLD_NOW);
95 if (mLibraryHandle != nullptr) {
96 ALOGI("%s loading %s", __func__, kAudioPolicyManagerCustomPath);
97 mCreateAudioPolicyManager = reinterpret_cast<CreateAudioPolicyManagerInstance>
98 (dlsym(mLibraryHandle, "createAudioPolicyManager"));
99 const char *lastError = dlerror();
100 ALOGW_IF(mCreateAudioPolicyManager == nullptr, "%s createAudioPolicyManager is null %s",
101 __func__, lastError != nullptr ? lastError : "no error");
102
103 mDestroyAudioPolicyManager = reinterpret_cast<DestroyAudioPolicyManagerInstance>(
104 dlsym(mLibraryHandle, "destroyAudioPolicyManager"));
105 lastError = dlerror();
106 ALOGW_IF(mDestroyAudioPolicyManager == nullptr, "%s destroyAudioPolicyManager is null %s",
107 __func__, lastError != nullptr ? lastError : "no error");
108 if (mCreateAudioPolicyManager == nullptr || mDestroyAudioPolicyManager == nullptr){
109 unloadAudioPolicyManager();
110 LOG_ALWAYS_FATAL("could not find audiopolicymanager interface methods");
111 }
112 }
Eric Laurentf5ada6e2014-10-09 17:49:00 -0700113}
114
115void AudioPolicyService::onFirstRef()
116{
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700117 {
118 Mutex::Autolock _l(mLock);
Eric Laurent93575202011-01-18 18:39:02 -0800119
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700120 // start audio commands thread
121 mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
122 // start output activity command thread
123 mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
Eric Laurentdce54a12014-03-10 12:19:46 -0700124
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700125 mAudioPolicyClient = new AudioPolicyClient(this);
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530126
127 loadAudioPolicyManager();
128 mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700129 }
Eric Laurentd66d7a12021-07-13 13:35:32 +0200130
bryant_liuba2b4392014-06-11 16:49:30 +0800131 // load audio processing modules
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000132 sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();
133 sp<UidPolicy> uidPolicy = new UidPolicy(this);
134 sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700135 {
136 Mutex::Autolock _l(mLock);
137 mAudioPolicyEffects = audioPolicyEffects;
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000138 mUidPolicy = uidPolicy;
139 mSensorPrivacyPolicy = sensorPrivacyPolicy;
Eric Laurent8b1e80b2014-10-07 09:08:47 -0700140 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000141 uidPolicy->registerSelf();
142 sensorPrivacyPolicy->registerSelf();
Eric Laurentd66d7a12021-07-13 13:35:32 +0200143
Eric Laurent81dd0f52021-07-05 11:54:40 +0200144 // Create spatializer if supported
145 const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
146 AudioDeviceTypeAddrVector devices;
147 bool hasSpatializer = mAudioPolicyManager->canBeSpatialized(&attr, nullptr, devices);
148 if (hasSpatializer) {
149 mSpatializer = Spatializer::create(this);
150 }
Eric Laurentd66d7a12021-07-13 13:35:32 +0200151 AudioSystem::audioPolicyReady();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700152}
153
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530154void AudioPolicyService::unloadAudioPolicyManager()
155{
156 ALOGV("%s ", __func__);
157 if (mLibraryHandle != nullptr) {
158 dlclose(mLibraryHandle);
159 }
160 mLibraryHandle = nullptr;
161 mCreateAudioPolicyManager = nullptr;
162 mDestroyAudioPolicyManager = nullptr;
163}
164
Mathias Agopian65ab4712010-07-14 17:59:35 -0700165AudioPolicyService::~AudioPolicyService()
166{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700167 mAudioCommandThread->exit();
Eric Laurent657ff612014-05-07 11:58:24 -0700168 mOutputCommandThread->exit();
Eric Laurent7c7f10b2011-06-17 21:29:58 -0700169
Jaideep Sharmaba9053b2021-01-25 21:24:26 +0530170 mDestroyAudioPolicyManager(mAudioPolicyManager);
171 unloadAudioPolicyManager();
172
Eric Laurentdce54a12014-03-10 12:19:46 -0700173 delete mAudioPolicyClient;
Eric Laurentb52c1522014-05-20 11:27:36 -0700174
175 mNotificationClients.clear();
bryant_liuba2b4392014-06-11 16:49:30 +0800176 mAudioPolicyEffects.clear();
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800177
178 mUidPolicy->unregisterSelf();
Michael Groovercfd28302018-12-11 19:16:46 -0800179 mSensorPrivacyPolicy->unregisterSelf();
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000180
181 mUidPolicy.clear();
Michael Groovercfd28302018-12-11 19:16:46 -0800182 mSensorPrivacyPolicy.clear();
Eric Laurentb52c1522014-05-20 11:27:36 -0700183}
184
185// A notification client is always registered by AudioSystem when the client process
186// connects to AudioPolicyService.
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800187Status AudioPolicyService::registerClient(const sp<media::IAudioPolicyServiceClient>& client)
Eric Laurentb52c1522014-05-20 11:27:36 -0700188{
Eric Laurent12590252015-08-21 18:40:20 -0700189 if (client == 0) {
190 ALOGW("%s got NULL client", __FUNCTION__);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800191 return Status::ok();
Eric Laurent12590252015-08-21 18:40:20 -0700192 }
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800193 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700194
195 uid_t uid = IPCThreadState::self()->getCallingUid();
luochaojiang908c7d72018-06-21 14:58:04 +0800196 pid_t pid = IPCThreadState::self()->getCallingPid();
197 int64_t token = ((int64_t)uid<<32) | pid;
198
199 if (mNotificationClients.indexOfKey(token) < 0) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700200 sp<NotificationClient> notificationClient = new NotificationClient(this,
201 client,
luochaojiang908c7d72018-06-21 14:58:04 +0800202 uid,
203 pid);
204 ALOGV("registerClient() client %p, uid %d pid %d", client.get(), uid, pid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700205
luochaojiang908c7d72018-06-21 14:58:04 +0800206 mNotificationClients.add(token, notificationClient);
Eric Laurentb52c1522014-05-20 11:27:36 -0700207
Marco Nelissenf8880202014-11-14 07:58:25 -0800208 sp<IBinder> binder = IInterface::asBinder(client);
Eric Laurentb52c1522014-05-20 11:27:36 -0700209 binder->linkToDeath(notificationClient);
210 }
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800211 return Status::ok();
Eric Laurentb52c1522014-05-20 11:27:36 -0700212}
213
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800214Status AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
Eric Laurente8726fe2015-06-26 09:39:24 -0700215{
216 Mutex::Autolock _l(mNotificationClientsLock);
217
218 uid_t uid = IPCThreadState::self()->getCallingUid();
luochaojiang908c7d72018-06-21 14:58:04 +0800219 pid_t pid = IPCThreadState::self()->getCallingPid();
220 int64_t token = ((int64_t)uid<<32) | pid;
221
222 if (mNotificationClients.indexOfKey(token) < 0) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800223 return Status::ok();
Eric Laurente8726fe2015-06-26 09:39:24 -0700224 }
luochaojiang908c7d72018-06-21 14:58:04 +0800225 mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800226 return Status::ok();
Eric Laurente8726fe2015-06-26 09:39:24 -0700227}
228
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800229Status AudioPolicyService::setAudioVolumeGroupCallbacksEnabled(bool enabled)
François Gaffiecfe17322018-11-07 13:41:29 +0100230{
231 Mutex::Autolock _l(mNotificationClientsLock);
232
233 uid_t uid = IPCThreadState::self()->getCallingUid();
234 pid_t pid = IPCThreadState::self()->getCallingPid();
235 int64_t token = ((int64_t)uid<<32) | pid;
236
237 if (mNotificationClients.indexOfKey(token) < 0) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800238 return Status::ok();
François Gaffiecfe17322018-11-07 13:41:29 +0100239 }
240 mNotificationClients.valueFor(token)->setAudioVolumeGroupCallbacksEnabled(enabled);
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800241 return Status::ok();
François Gaffiecfe17322018-11-07 13:41:29 +0100242}
243
Eric Laurentb52c1522014-05-20 11:27:36 -0700244// removeNotificationClient() is called when the client process dies.
luochaojiang908c7d72018-06-21 14:58:04 +0800245void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
Eric Laurentb52c1522014-05-20 11:27:36 -0700246{
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000247 bool hasSameUid = false;
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800248 {
249 Mutex::Autolock _l(mNotificationClientsLock);
luochaojiang908c7d72018-06-21 14:58:04 +0800250 int64_t token = ((int64_t)uid<<32) | pid;
251 mNotificationClients.removeItem(token);
luochaojiang908c7d72018-06-21 14:58:04 +0800252 for (size_t i = 0; i < mNotificationClients.size(); i++) {
253 if (mNotificationClients.valueAt(i)->uid() == uid) {
254 hasSameUid = true;
255 break;
256 }
257 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000258 }
259 {
260 Mutex::Autolock _l(mLock);
luochaojiang908c7d72018-06-21 14:58:04 +0800261 if (mAudioPolicyManager && !hasSameUid) {
Eric Laurent10b71232018-04-13 18:14:44 -0700262 // called from binder death notification: no need to clear caller identity
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700263 mAudioPolicyManager->releaseResourcesForUid(uid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700264 }
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800265 }
Eric Laurentb52c1522014-05-20 11:27:36 -0700266}
267
268void AudioPolicyService::onAudioPortListUpdate()
269{
270 mOutputCommandThread->updateAudioPortListCommand();
271}
272
273void AudioPolicyService::doOnAudioPortListUpdate()
274{
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800275 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700276 for (size_t i = 0; i < mNotificationClients.size(); i++) {
277 mNotificationClients.valueAt(i)->onAudioPortListUpdate();
278 }
279}
280
281void AudioPolicyService::onAudioPatchListUpdate()
282{
283 mOutputCommandThread->updateAudioPatchListCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700284}
285
Eric Laurentb52c1522014-05-20 11:27:36 -0700286void AudioPolicyService::doOnAudioPatchListUpdate()
287{
Eric Laurent0ebd5f92014-11-19 19:04:52 -0800288 Mutex::Autolock _l(mNotificationClientsLock);
Eric Laurentb52c1522014-05-20 11:27:36 -0700289 for (size_t i = 0; i < mNotificationClients.size(); i++) {
290 mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
291 }
292}
293
François Gaffiecfe17322018-11-07 13:41:29 +0100294void AudioPolicyService::onAudioVolumeGroupChanged(volume_group_t group, int flags)
295{
296 mOutputCommandThread->changeAudioVolumeGroupCommand(group, flags);
297}
298
299void AudioPolicyService::doOnAudioVolumeGroupChanged(volume_group_t group, int flags)
300{
301 Mutex::Autolock _l(mNotificationClientsLock);
302 for (size_t i = 0; i < mNotificationClients.size(); i++) {
303 mNotificationClients.valueAt(i)->onAudioVolumeGroupChanged(group, flags);
304 }
305}
306
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700307void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700308{
309 ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
310 regId.string(), state);
311 mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
312}
313
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700314void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700315{
316 Mutex::Autolock _l(mNotificationClientsLock);
317 for (size_t i = 0; i < mNotificationClients.size(); i++) {
318 mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
319 }
320}
321
Eric Laurenta9f86652018-11-28 17:23:11 -0800322void AudioPolicyService::onRecordingConfigurationUpdate(
323 int event,
324 const record_client_info_t *clientInfo,
325 const audio_config_base_t *clientConfig,
326 std::vector<effect_descriptor_t> clientEffects,
327 const audio_config_base_t *deviceConfig,
328 std::vector<effect_descriptor_t> effects,
329 audio_patch_handle_t patchHandle,
330 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800331{
Jean-Michel Triviac4e4292016-12-22 11:39:31 -0800332 mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -0800333 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800334}
335
Eric Laurenta9f86652018-11-28 17:23:11 -0800336void AudioPolicyService::doOnRecordingConfigurationUpdate(
337 int event,
338 const record_client_info_t *clientInfo,
339 const audio_config_base_t *clientConfig,
340 std::vector<effect_descriptor_t> clientEffects,
341 const audio_config_base_t *deviceConfig,
342 std::vector<effect_descriptor_t> effects,
343 audio_patch_handle_t patchHandle,
344 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800345{
346 Mutex::Autolock _l(mNotificationClientsLock);
347 for (size_t i = 0; i < mNotificationClients.size(); i++) {
Jean-Michel Triviac4e4292016-12-22 11:39:31 -0800348 mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -0800349 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800350 }
351}
352
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700353void AudioPolicyService::onRoutingUpdated()
354{
355 mOutputCommandThread->routingChangedCommand();
356}
357
358void AudioPolicyService::doOnRoutingUpdated()
359{
360 Mutex::Autolock _l(mNotificationClientsLock);
361 for (size_t i = 0; i < mNotificationClients.size(); i++) {
362 mNotificationClients.valueAt(i)->onRoutingUpdated();
363 }
364}
365
Eric Laurent81dd0f52021-07-05 11:54:40 +0200366void AudioPolicyService::onCheckSpatializer()
367{
368 Mutex::Autolock _l(mLock);
Eric Laurent39095982021-08-24 18:29:27 +0200369 onCheckSpatializer_l();
370}
371
372void AudioPolicyService::onCheckSpatializer_l()
373{
374 if (mSpatializer != nullptr) {
375 mOutputCommandThread->checkSpatializerCommand();
376 }
Eric Laurent81dd0f52021-07-05 11:54:40 +0200377}
378
379void AudioPolicyService::doOnCheckSpatializer()
380{
Eric Laurent39095982021-08-24 18:29:27 +0200381 Mutex::Autolock _l(mLock);
Eric Laurent81dd0f52021-07-05 11:54:40 +0200382
Eric Laurent39095982021-08-24 18:29:27 +0200383 if (mSpatializer != nullptr) {
384 if (mSpatializer->getLevel() != media::SpatializationLevel::NONE) {
385 audio_io_handle_t currentOutput = mSpatializer->getOutput();
386 audio_io_handle_t newOutput;
387 const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
388 audio_config_base_t config = mSpatializer->getAudioInConfig();
389 status_t status =
390 mAudioPolicyManager->getSpatializerOutput(&config, &attr, &newOutput);
391
392 if (status == NO_ERROR && currentOutput == newOutput) {
393 return;
394 }
395 mLock.unlock();
396 // It is OK to call detachOutput() is none is already attached.
397 mSpatializer->detachOutput();
398 if (status != NO_ERROR || newOutput == AUDIO_IO_HANDLE_NONE) {
Eric Laurent81dd0f52021-07-05 11:54:40 +0200399 mLock.lock();
Eric Laurent39095982021-08-24 18:29:27 +0200400 return;
401 }
402 status = mSpatializer->attachOutput(newOutput);
403 mLock.lock();
404 if (status != NO_ERROR) {
405 mAudioPolicyManager->releaseSpatializerOutput(newOutput);
406 }
407 } else if (mSpatializer->getLevel() == media::SpatializationLevel::NONE
408 && mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
409 mLock.unlock();
410 audio_io_handle_t output = mSpatializer->detachOutput();
411 mLock.lock();
412 if (output != AUDIO_IO_HANDLE_NONE) {
413 mAudioPolicyManager->releaseSpatializerOutput(output);
Eric Laurent81dd0f52021-07-05 11:54:40 +0200414 }
415 }
416 }
417}
418
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800419status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
420 audio_patch_handle_t *handle,
421 int delayMs)
422{
423 return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
424}
425
426status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
427 int delayMs)
428{
429 return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
430}
431
Eric Laurente1715a42014-05-20 11:30:42 -0700432status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
433 int delayMs)
434{
435 return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
436}
437
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800438AudioPolicyService::NotificationClient::NotificationClient(
439 const sp<AudioPolicyService>& service,
440 const sp<media::IAudioPolicyServiceClient>& client,
441 uid_t uid,
442 pid_t pid)
luochaojiang908c7d72018-06-21 14:58:04 +0800443 : mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
François Gaffiecfe17322018-11-07 13:41:29 +0100444 mAudioPortCallbacksEnabled(false), mAudioVolumeGroupCallbacksEnabled(false)
Eric Laurentb52c1522014-05-20 11:27:36 -0700445{
446}
447
448AudioPolicyService::NotificationClient::~NotificationClient()
449{
450}
451
452void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
453{
454 sp<NotificationClient> keep(this);
455 sp<AudioPolicyService> service = mService.promote();
456 if (service != 0) {
luochaojiang908c7d72018-06-21 14:58:04 +0800457 service->removeNotificationClient(mUid, mPid);
Eric Laurentb52c1522014-05-20 11:27:36 -0700458 }
459}
460
461void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
462{
Eric Laurente8726fe2015-06-26 09:39:24 -0700463 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700464 mAudioPolicyServiceClient->onAudioPortListUpdate();
465 }
466}
467
468void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
469{
Eric Laurente8726fe2015-06-26 09:39:24 -0700470 if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
Eric Laurentb52c1522014-05-20 11:27:36 -0700471 mAudioPolicyServiceClient->onAudioPatchListUpdate();
472 }
473}
Eric Laurent57dae992011-07-24 13:36:09 -0700474
François Gaffiecfe17322018-11-07 13:41:29 +0100475void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
476 int flags)
477{
478 if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
479 mAudioPolicyServiceClient->onAudioVolumeGroupChanged(group, flags);
480 }
481}
482
483
Jean-Michel Trivide801052015-04-14 19:10:14 -0700484void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700485 const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -0700486{
Andy Hung4ef19fa2018-05-15 19:35:29 -0700487 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800488 mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(
489 legacy2aidl_String8_string(regId).value(), state);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800490 }
491}
492
493void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
Eric Laurenta9f86652018-11-28 17:23:11 -0800494 int event,
495 const record_client_info_t *clientInfo,
496 const audio_config_base_t *clientConfig,
497 std::vector<effect_descriptor_t> clientEffects,
498 const audio_config_base_t *deviceConfig,
499 std::vector<effect_descriptor_t> effects,
500 audio_patch_handle_t patchHandle,
501 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -0800502{
Andy Hung4ef19fa2018-05-15 19:35:29 -0700503 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800504 status_t status = [&]() -> status_t {
505 int32_t eventAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(event));
506 media::RecordClientInfo clientInfoAidl = VALUE_OR_RETURN_STATUS(
507 legacy2aidl_record_client_info_t_RecordClientInfo(*clientInfo));
Mikhail Naganovdbf03642021-08-25 18:15:32 -0700508 AudioConfigBase clientConfigAidl = VALUE_OR_RETURN_STATUS(
Mikhail Naganovde3fa182021-07-30 15:06:42 -0700509 legacy2aidl_audio_config_base_t_AudioConfigBase(
510 *clientConfig, true /*isInput*/));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800511 std::vector<media::EffectDescriptor> clientEffectsAidl = VALUE_OR_RETURN_STATUS(
512 convertContainer<std::vector<media::EffectDescriptor>>(
513 clientEffects,
514 legacy2aidl_effect_descriptor_t_EffectDescriptor));
Mikhail Naganovdbf03642021-08-25 18:15:32 -0700515 AudioConfigBase deviceConfigAidl = VALUE_OR_RETURN_STATUS(
Mikhail Naganovde3fa182021-07-30 15:06:42 -0700516 legacy2aidl_audio_config_base_t_AudioConfigBase(
517 *deviceConfig, true /*isInput*/));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800518 std::vector<media::EffectDescriptor> effectsAidl = VALUE_OR_RETURN_STATUS(
519 convertContainer<std::vector<media::EffectDescriptor>>(
520 effects,
521 legacy2aidl_effect_descriptor_t_EffectDescriptor));
522 int32_t patchHandleAidl = VALUE_OR_RETURN_STATUS(
523 legacy2aidl_audio_patch_handle_t_int32_t(patchHandle));
Mikhail Naganovddceecc2021-09-03 13:58:56 -0700524 media::audio::common::AudioSource sourceAidl = VALUE_OR_RETURN_STATUS(
525 legacy2aidl_audio_source_t_AudioSource(source));
Ytai Ben-Tsvi7e7a79d2020-12-15 16:48:16 -0800526 return aidl_utils::statusTFromBinderStatus(
527 mAudioPolicyServiceClient->onRecordingConfigurationUpdate(eventAidl,
528 clientInfoAidl,
529 clientConfigAidl,
530 clientEffectsAidl,
531 deviceConfigAidl,
532 effectsAidl,
533 patchHandleAidl,
534 sourceAidl));
535 }();
536 ALOGW_IF(status != OK, "onRecordingConfigurationUpdate() failed: %d", status);
Jean-Michel Trivide801052015-04-14 19:10:14 -0700537 }
538}
539
Eric Laurente8726fe2015-06-26 09:39:24 -0700540void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
541{
542 mAudioPortCallbacksEnabled = enabled;
543}
544
François Gaffiecfe17322018-11-07 13:41:29 +0100545void AudioPolicyService::NotificationClient::setAudioVolumeGroupCallbacksEnabled(bool enabled)
546{
547 mAudioVolumeGroupCallbacksEnabled = enabled;
548}
Eric Laurente8726fe2015-06-26 09:39:24 -0700549
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700550void AudioPolicyService::NotificationClient::onRoutingUpdated()
551{
552 if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
553 mAudioPolicyServiceClient->onRoutingUpdated();
554 }
555}
556
Mathias Agopian65ab4712010-07-14 17:59:35 -0700557void AudioPolicyService::binderDied(const wp<IBinder>& who) {
Glenn Kasten411e4472012-11-02 10:00:06 -0700558 ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
Eric Laurentde070132010-07-13 04:45:46 -0700559 IPCThreadState::self()->getCallingPid());
Mathias Agopian65ab4712010-07-14 17:59:35 -0700560}
561
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000562static bool dumpTryLock(Mutex& mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Mathias Agopian65ab4712010-07-14 17:59:35 -0700563{
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000564 return mutex.timedLock(kDumpLockTimeoutNs) == NO_ERROR;
565}
566
567static void dumpReleaseLock(Mutex& mutex, bool locked) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
568{
569 if (locked) mutex.unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700570}
571
572status_t AudioPolicyService::dumpInternals(int fd)
573{
574 const size_t SIZE = 256;
575 char buffer[SIZE];
576 String8 result;
577
Eric Laurentdce54a12014-03-10 12:19:46 -0700578 snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700579 result.append(buffer);
580 snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
581 result.append(buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700582
Hayden Gomes524159d2019-12-23 14:41:47 -0800583 snprintf(buffer, SIZE, "Supported System Usages:\n");
584 result.append(buffer);
585 for (std::vector<audio_usage_t>::iterator it = mSupportedSystemUsages.begin();
586 it != mSupportedSystemUsages.end(); ++it) {
587 snprintf(buffer, SIZE, "\t%d\n", *it);
588 result.append(buffer);
589 }
590
Mathias Agopian65ab4712010-07-14 17:59:35 -0700591 write(fd, result.string(), result.size());
592 return NO_ERROR;
593}
594
Eric Laurente8c8b432018-10-17 10:08:02 -0700595void AudioPolicyService::updateUidStates()
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800596{
Eric Laurente8c8b432018-10-17 10:08:02 -0700597 Mutex::Autolock _l(mLock);
598 updateUidStates_l();
599}
600
601void AudioPolicyService::updateUidStates_l()
602{
Eric Laurent4eb58f12018-12-07 16:41:02 -0800603// Go over all active clients and allow capture (does not force silence) in the
604// following cases:
Evan Severson1f700cd2021-02-10 13:10:37 -0800605// The client is the assistant
606// AND an accessibility service is on TOP or a RTT call is active
Eric Laurent589171c2019-07-25 18:04:29 -0700607// AND the source is VOICE_RECOGNITION or HOTWORD
Evan Severson1f700cd2021-02-10 13:10:37 -0800608// OR uses VOICE_RECOGNITION AND is on TOP
609// OR uses HOTWORD
610// AND there is no active privacy sensitive capture or call
611// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
612// OR The client is an accessibility service
613// AND Is on TOP
614// AND the source is VOICE_RECOGNITION or HOTWORD
615// OR The assistant is not on TOP
Eric Laurent589171c2019-07-25 18:04:29 -0700616// AND there is no active privacy sensitive capture or call
617// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Evan Severson1f700cd2021-02-10 13:10:37 -0800618// AND is on TOP
619// AND the source is VOICE_RECOGNITION or HOTWORD
620// OR the client source is virtual (remote submix, call audio TX or RX...)
621// OR the client source is HOTWORD
622// AND is on TOP
623// OR all active clients are using HOTWORD source
624// AND no call is active
625// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
626// OR the client is the current InputMethodService
627// AND a RTT call is active AND the source is VOICE_RECOGNITION
628// OR Any client
629// AND The assistant is not on TOP
630// AND is on TOP or latest started
631// AND there is no active privacy sensitive capture or call
632// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent4eb58f12018-12-07 16:41:02 -0800633
Eric Laurent4e947da2019-10-17 15:24:06 -0700634
Eric Laurent4eb58f12018-12-07 16:41:02 -0800635 sp<AudioRecordClient> topActive;
636 sp<AudioRecordClient> latestActive;
Eric Laurentc21d5692020-02-25 10:24:36 -0800637 sp<AudioRecordClient> topSensitiveActive;
Eric Laurentb809a752020-06-29 09:53:13 -0700638 sp<AudioRecordClient> latestSensitiveActiveOrComm;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700639
Eric Laurenta46bedb2018-12-07 18:01:26 -0800640 nsecs_t topStartNs = 0;
641 nsecs_t latestStartNs = 0;
Eric Laurentc21d5692020-02-25 10:24:36 -0800642 nsecs_t topSensitiveStartNs = 0;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800643 nsecs_t latestSensitiveStartNs = 0;
644 bool isA11yOnTop = mUidPolicy->isA11yOnTop();
645 bool isAssistantOnTop = false;
646 bool isSensitiveActive = false;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700647 bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
Eric Laurentc21d5692020-02-25 10:24:36 -0800648 bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION;
649 bool rttCallActive = (isInCall || isInCommunication)
Eric Laurent6ede98f2019-06-11 14:50:30 -0700650 && mUidPolicy->isRttEnabled();
Eric Laurent4e947da2019-10-17 15:24:06 -0700651 bool onlyHotwordActive = true;
Eric Laurentb809a752020-06-29 09:53:13 -0700652 bool isPhoneStateOwnerActive = false;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800653
Michael Groovercfd28302018-12-11 19:16:46 -0800654 // if Sensor Privacy is enabled then all recordings should be silenced.
655 if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
656 silenceAllRecordings_l();
657 return;
658 }
659
Eric Laurente8c8b432018-10-17 10:08:02 -0700660 for (size_t i =0; i < mAudioRecordClients.size(); i++) {
661 sp<AudioRecordClient> current = mAudioRecordClients[i];
Svet Ganov33761132021-05-13 22:51:08 +0000662 uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
663 current->attributionSource.uid));
Evan Severson1f700cd2021-02-10 13:10:37 -0800664 if (!current->active) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700665 continue;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800666 }
Eric Laurent1ff16a72019-03-14 18:35:04 -0700667
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700668 app_state_t appState = apmStatFromAmState(mUidPolicy->getUidState(currentUid));
Eric Laurent1ff16a72019-03-14 18:35:04 -0700669 // clients which app is in IDLE state are not eligible for top active or
670 // latest active
671 if (appState == APP_STATE_IDLE) {
672 continue;
673 }
674
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700675 bool isAccessibility = mUidPolicy->isA11yUid(currentUid);
Eric Laurent14a88632020-07-16 12:28:30 -0700676 // Clients capturing for Accessibility services or virtual sources are not considered
Eric Laurentc21d5692020-02-25 10:24:36 -0800677 // for top or latest active to avoid masking regular clients started before
Eric Laurent14a88632020-07-16 12:28:30 -0700678 if (!isAccessibility && !isVirtualSource(current->attributes.source)) {
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700679 bool isAssistant = mUidPolicy->isAssistantUid(currentUid);
Eric Laurentc21d5692020-02-25 10:24:36 -0800680 bool isPrivacySensitive =
681 (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0;
Eric Laurentb809a752020-06-29 09:53:13 -0700682
Eric Laurentc21d5692020-02-25 10:24:36 -0800683 if (appState == APP_STATE_TOP) {
684 if (isPrivacySensitive) {
685 if (current->startTimeNs > topSensitiveStartNs) {
686 topSensitiveActive = current;
687 topSensitiveStartNs = current->startTimeNs;
688 }
689 } else {
690 if (current->startTimeNs > topStartNs) {
691 topActive = current;
692 topStartNs = current->startTimeNs;
693 }
694 }
695 if (isAssistant) {
696 isAssistantOnTop = true;
697 }
Eric Laurenta46bedb2018-12-07 18:01:26 -0800698 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800699 // Clients capturing for HOTWORD are not considered
700 // for latest active to avoid masking regular clients started before
701 if (!(current->attributes.source == AUDIO_SOURCE_HOTWORD
702 || ((isA11yOnTop || rttCallActive) && isAssistant))) {
703 if (isPrivacySensitive) {
Eric Laurentb809a752020-06-29 09:53:13 -0700704 // if audio mode is IN_COMMUNICATION, make sure the audio mode owner
705 // is marked latest sensitive active even if another app qualifies.
706 if (current->startTimeNs > latestSensitiveStartNs
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700707 || (isInCommunication && currentUid == mPhoneStateOwnerUid)) {
Eric Laurentb809a752020-06-29 09:53:13 -0700708 if (!isInCommunication || latestSensitiveActiveOrComm == nullptr
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700709 || VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +0000710 latestSensitiveActiveOrComm->attributionSource.uid))
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700711 != mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -0700712 latestSensitiveActiveOrComm = current;
713 latestSensitiveStartNs = current->startTimeNs;
714 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800715 }
716 isSensitiveActive = true;
717 } else {
718 if (current->startTimeNs > latestStartNs) {
719 latestActive = current;
720 latestStartNs = current->startTimeNs;
721 }
722 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800723 }
724 }
Eric Laurent4e947da2019-10-17 15:24:06 -0700725 if (current->attributes.source != AUDIO_SOURCE_HOTWORD) {
726 onlyHotwordActive = false;
727 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700728 if (currentUid == mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -0700729 isPhoneStateOwnerActive = true;
730 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800731 }
732
Eric Laurent1ff16a72019-03-14 18:35:04 -0700733 // if no active client with UI on Top, consider latest active as top
734 if (topActive == nullptr) {
735 topActive = latestActive;
Eric Laurentc21d5692020-02-25 10:24:36 -0800736 topStartNs = latestStartNs;
737 }
738 if (topSensitiveActive == nullptr) {
Eric Laurentb809a752020-06-29 09:53:13 -0700739 topSensitiveActive = latestSensitiveActiveOrComm;
Eric Laurentc21d5692020-02-25 10:24:36 -0800740 topSensitiveStartNs = latestSensitiveStartNs;
Eric Laurentb809a752020-06-29 09:53:13 -0700741 } else if (latestSensitiveActiveOrComm != nullptr) {
742 // if audio mode is IN_COMMUNICATION, favor audio mode owner over an app with
743 // foreground UI in case both are capturing with privacy sensitive flag.
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700744 uid_t latestActiveUid = VALUE_OR_FATAL(
Svet Ganov33761132021-05-13 22:51:08 +0000745 aidl2legacy_int32_t_uid_t(latestSensitiveActiveOrComm->attributionSource.uid));
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700746 if (isInCommunication && latestActiveUid == mPhoneStateOwnerUid) {
Eric Laurentb809a752020-06-29 09:53:13 -0700747 topSensitiveActive = latestSensitiveActiveOrComm;
748 topSensitiveStartNs = latestSensitiveStartNs;
749 }
Eric Laurentc21d5692020-02-25 10:24:36 -0800750 }
751
752 // If both privacy sensitive and regular capture are active:
753 // if the regular capture is privileged
754 // allow concurrency
755 // else
756 // favor the privacy sensitive case
757 if (topActive != nullptr && topSensitiveActive != nullptr
Ricardo Correa57a37692020-03-23 17:27:25 -0700758 && !topActive->canCaptureOutput) {
Eric Laurentc21d5692020-02-25 10:24:36 -0800759 topActive = nullptr;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800760 }
761
762 for (size_t i =0; i < mAudioRecordClients.size(); i++) {
763 sp<AudioRecordClient> current = mAudioRecordClients[i];
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700764 uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +0000765 current->attributionSource.uid));
Eric Laurent1ff16a72019-03-14 18:35:04 -0700766 if (!current->active) {
767 continue;
768 }
769
Eric Laurent4eb58f12018-12-07 16:41:02 -0800770 audio_source_t source = current->attributes.source;
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700771 bool isTopOrLatestActive = topActive == nullptr ? false :
Svet Ganov33761132021-05-13 22:51:08 +0000772 current->attributionSource.uid == topActive->attributionSource.uid;
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700773 bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false :
Svet Ganov33761132021-05-13 22:51:08 +0000774 current->attributionSource.uid == topSensitiveActive->attributionSource.uid;
Eric Laurentc21d5692020-02-25 10:24:36 -0800775
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000776 auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) REQUIRES(mLock) {
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700777 uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
Svet Ganov33761132021-05-13 22:51:08 +0000778 recordClient->attributionSource.uid));
Ricardo Correa57a37692020-03-23 17:27:25 -0700779 bool canCaptureCall = recordClient->canCaptureOutput;
Eric Laurentb809a752020-06-29 09:53:13 -0700780 bool canCaptureCommunication = recordClient->canCaptureOutput
781 || !isPhoneStateOwnerActive
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700782 || recordUid == mPhoneStateOwnerUid;
Eric Laurentb809a752020-06-29 09:53:13 -0700783 return !(isInCall && !canCaptureCall)
784 && !(isInCommunication && !canCaptureCommunication);
Eric Laurentc21d5692020-02-25 10:24:36 -0800785 };
Eric Laurent1ff16a72019-03-14 18:35:04 -0700786
787 // By default allow capture if:
788 // The assistant is not on TOP
Eric Laurenta171e352019-05-07 13:04:45 -0700789 // AND is on TOP or latest started
Eric Laurent1ff16a72019-03-14 18:35:04 -0700790 // AND there is no active privacy sensitive capture or call
791 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
792 bool allowCapture = !isAssistantOnTop
Eric Laurentc21d5692020-02-25 10:24:36 -0800793 && (isTopOrLatestActive || isTopOrLatestSensitive)
794 && !(isSensitiveActive
Ricardo Correa57a37692020-03-23 17:27:25 -0700795 && !(isTopOrLatestSensitive || current->canCaptureOutput))
Eric Laurentc21d5692020-02-25 10:24:36 -0800796 && canCaptureIfInCallOrCommunication(current);
Eric Laurent2dc962b2019-03-01 08:25:25 -0800797
Eric Laurented726cc2021-07-01 14:26:41 +0200798 if (!current->hasOp()) {
799 // Never allow capture if app op is denied
800 allowCapture = false;
801 } else if (isVirtualSource(source)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700802 // Allow capture for virtual (remote submix, call audio TX or RX...) sources
803 allowCapture = true;
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700804 } else if (mUidPolicy->isAssistantUid(currentUid)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700805 // For assistant allow capture if:
Eric Laurent6ede98f2019-06-11 14:50:30 -0700806 // An accessibility service is on TOP or a RTT call is active
Eric Laurent1ff16a72019-03-14 18:35:04 -0700807 // AND the source is VOICE_RECOGNITION or HOTWORD
Eric Laurenta171e352019-05-07 13:04:45 -0700808 // OR is on TOP AND uses VOICE_RECOGNITION
Eric Laurent1ff16a72019-03-14 18:35:04 -0700809 // OR uses HOTWORD
810 // AND there is no active privacy sensitive capture or call
811 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent6ede98f2019-06-11 14:50:30 -0700812 if (isA11yOnTop || rttCallActive) {
Eric Laurent4eb58f12018-12-07 16:41:02 -0800813 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700814 allowCapture = true;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800815 }
816 } else {
Eric Laurenta171e352019-05-07 13:04:45 -0700817 if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
Eric Laurentc21d5692020-02-25 10:24:36 -0800818 source == AUDIO_SOURCE_HOTWORD)
Ricardo Correa57a37692020-03-23 17:27:25 -0700819 && !(isSensitiveActive && !current->canCaptureOutput)
Eric Laurentc21d5692020-02-25 10:24:36 -0800820 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700821 allowCapture = true;
Eric Laurent4eb58f12018-12-07 16:41:02 -0800822 }
823 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700824 } else if (mUidPolicy->isA11yUid(currentUid)) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700825 // For accessibility service allow capture if:
Eric Laurent47670c92019-08-28 16:59:05 -0700826 // The assistant is not on TOP
827 // AND there is no active privacy sensitive capture or call
Eric Laurent589171c2019-07-25 18:04:29 -0700828 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurent47670c92019-08-28 16:59:05 -0700829 // OR
830 // Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
831 if (!isAssistantOnTop
Ricardo Correa57a37692020-03-23 17:27:25 -0700832 && !(isSensitiveActive && !current->canCaptureOutput)
Eric Laurentc21d5692020-02-25 10:24:36 -0800833 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent47670c92019-08-28 16:59:05 -0700834 allowCapture = true;
835 }
Eric Laurent589171c2019-07-25 18:04:29 -0700836 if (isA11yOnTop) {
837 if (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD) {
838 allowCapture = true;
839 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800840 }
Eric Laurent4e947da2019-10-17 15:24:06 -0700841 } else if (source == AUDIO_SOURCE_HOTWORD) {
842 // For HOTWORD source allow capture when not on TOP if:
843 // All active clients are using HOTWORD source
844 // AND no call is active
845 // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
Eric Laurentc21d5692020-02-25 10:24:36 -0800846 if (onlyHotwordActive
847 && canCaptureIfInCallOrCommunication(current)) {
Eric Laurent4e947da2019-10-17 15:24:06 -0700848 allowCapture = true;
849 }
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700850 } else if (mUidPolicy->isCurrentImeUid(currentUid)) {
Kohsuke Yatoha623a132020-03-24 20:10:26 -0700851 // For current InputMethodService allow capture if:
852 // A RTT call is active AND the source is VOICE_RECOGNITION
853 if (rttCallActive && source == AUDIO_SOURCE_VOICE_RECOGNITION) {
854 allowCapture = true;
855 }
Eric Laurent4eb58f12018-12-07 16:41:02 -0800856 }
Eric Laurent8c7ef892021-06-10 13:32:16 +0200857 setAppState_l(current,
Philip P. Moltmannbda45752020-07-17 16:41:18 -0700858 allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(currentUid)) :
Eric Laurent1ff16a72019-03-14 18:35:04 -0700859 APP_STATE_IDLE);
Eric Laurente8c8b432018-10-17 10:08:02 -0700860 }
861}
862
Michael Groovercfd28302018-12-11 19:16:46 -0800863void AudioPolicyService::silenceAllRecordings_l() {
864 for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
865 sp<AudioRecordClient> current = mAudioRecordClients[i];
Eric Laurent1ff16a72019-03-14 18:35:04 -0700866 if (!isVirtualSource(current->attributes.source)) {
Eric Laurent8c7ef892021-06-10 13:32:16 +0200867 setAppState_l(current, APP_STATE_IDLE);
Eric Laurent1ff16a72019-03-14 18:35:04 -0700868 }
Michael Groovercfd28302018-12-11 19:16:46 -0800869 }
870}
871
Eric Laurente8c8b432018-10-17 10:08:02 -0700872/* static */
873app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
Eric Laurent1ff16a72019-03-14 18:35:04 -0700874
875 if (amState == ActivityManager::PROCESS_STATE_UNKNOWN) {
Eric Laurente8c8b432018-10-17 10:08:02 -0700876 return APP_STATE_IDLE;
Eric Laurent1ff16a72019-03-14 18:35:04 -0700877 } else if (amState <= ActivityManager::PROCESS_STATE_TOP) {
878 // include persistent services
879 return APP_STATE_TOP;
Eric Laurente8c8b432018-10-17 10:08:02 -0700880 }
881 return APP_STATE_FOREGROUND;
882}
883
Eric Laurent4eb58f12018-12-07 16:41:02 -0800884/* static */
Eric Laurent2dc962b2019-03-01 08:25:25 -0800885bool AudioPolicyService::isVirtualSource(audio_source_t source)
Eric Laurent4eb58f12018-12-07 16:41:02 -0800886{
887 switch (source) {
888 case AUDIO_SOURCE_VOICE_UPLINK:
889 case AUDIO_SOURCE_VOICE_DOWNLINK:
890 case AUDIO_SOURCE_VOICE_CALL:
Eric Laurent2dc962b2019-03-01 08:25:25 -0800891 case AUDIO_SOURCE_REMOTE_SUBMIX:
892 case AUDIO_SOURCE_FM_TUNER:
Eric Laurent68eb2122020-04-30 17:40:57 -0700893 case AUDIO_SOURCE_ECHO_REFERENCE:
Eric Laurent4eb58f12018-12-07 16:41:02 -0800894 return true;
895 default:
896 break;
897 }
898 return false;
899}
900
Eric Laurented726cc2021-07-01 14:26:41 +0200901/* static */
902bool AudioPolicyService::isAppOpSource(audio_source_t source)
903{
904 switch (source) {
905 case AUDIO_SOURCE_FM_TUNER:
906 case AUDIO_SOURCE_ECHO_REFERENCE:
907 return false;
908 default:
909 break;
910 }
911 return true;
912}
913
Eric Laurent8c7ef892021-06-10 13:32:16 +0200914void AudioPolicyService::setAppState_l(sp<AudioRecordClient> client, app_state_t state)
Eric Laurente8c8b432018-10-17 10:08:02 -0700915{
916 AutoCallerClear acc;
917
918 if (mAudioPolicyManager) {
Eric Laurent8c7ef892021-06-10 13:32:16 +0200919 mAudioPolicyManager->setAppState(client->portId, state);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -0700920 }
921 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
922 if (af) {
Eric Laurentf32108e2018-10-04 17:22:04 -0700923 bool silenced = state == APP_STATE_IDLE;
Eric Laurent8c7ef892021-06-10 13:32:16 +0200924 if (client->silenced != silenced) {
925 if (client->active) {
926 if (silenced) {
927 finishRecording(client->attributionSource, client->attributes.source);
928 } else {
929 std::stringstream msg;
930 msg << "Audio recording un-silenced on session " << client->session;
931 if (!startRecording(client->attributionSource, String16(msg.str().c_str()),
932 client->attributes.source)) {
933 silenced = true;
934 }
935 }
936 }
937 af->setRecordSilenced(client->portId, silenced);
938 client->silenced = silenced;
939 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -0700940 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800941}
942
Glenn Kasten0f11b512014-01-31 16:18:54 -0800943status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700944{
Glenn Kasten44deb052012-02-05 18:09:08 -0800945 if (!dumpAllowed()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700946 dumpPermissionDenial(fd);
947 } else {
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000948 const bool locked = dumpTryLock(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700949 if (!locked) {
950 String8 result(kDeadlockedString);
951 write(fd, result.string(), result.size());
952 }
953
954 dumpInternals(fd);
Glenn Kasten9d1f02d2012-02-08 17:47:58 -0800955 if (mAudioCommandThread != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700956 mAudioCommandThread->dump(fd);
957 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700958
Eric Laurentdce54a12014-03-10 12:19:46 -0700959 if (mAudioPolicyManager) {
960 mAudioPolicyManager->dump(fd);
961 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700962
Kevin Rocard8be94972019-02-22 13:26:25 -0800963 mPackageManager.dump(fd);
964
Mikhail Naganov12b716c2020-04-30 22:37:43 +0000965 dumpReleaseLock(mLock, locked);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700966 }
967 return NO_ERROR;
968}
969
970status_t AudioPolicyService::dumpPermissionDenial(int fd)
971{
972 const size_t SIZE = 256;
973 char buffer[SIZE];
974 String8 result;
975 snprintf(buffer, SIZE, "Permission Denial: "
976 "can't dump AudioPolicyService from pid=%d, uid=%d\n",
977 IPCThreadState::self()->getCallingPid(),
978 IPCThreadState::self()->getCallingUid());
979 result.append(buffer);
980 write(fd, result.string(), result.size());
981 return NO_ERROR;
982}
983
984status_t AudioPolicyService::onTransact(
Svet Ganovf4ddfef2018-01-16 07:37:58 -0800985 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -0800986 // make sure transactions reserved to AudioFlinger do not come from other processes
987 switch (code) {
988 case TRANSACTION_startOutput:
989 case TRANSACTION_stopOutput:
990 case TRANSACTION_releaseOutput:
991 case TRANSACTION_getInputForAttr:
992 case TRANSACTION_startInput:
993 case TRANSACTION_stopInput:
994 case TRANSACTION_releaseInput:
995 case TRANSACTION_getOutputForEffect:
996 case TRANSACTION_registerEffect:
997 case TRANSACTION_unregisterEffect:
998 case TRANSACTION_setEffectEnabled:
999 case TRANSACTION_getStrategyForStream:
1000 case TRANSACTION_getOutputForAttr:
1001 case TRANSACTION_moveEffectsToIo:
1002 ALOGW("%s: transaction %d received from PID %d",
1003 __func__, code, IPCThreadState::self()->getCallingPid());
1004 return INVALID_OPERATION;
1005 default:
1006 break;
1007 }
1008
1009 // make sure the following transactions come from system components
1010 switch (code) {
1011 case TRANSACTION_setDeviceConnectionState:
1012 case TRANSACTION_handleDeviceConfigChange:
1013 case TRANSACTION_setPhoneState:
1014//FIXME: Allow setForceUse calls from system apps until a better use case routing API is available
1015// case TRANSACTION_setForceUse:
1016 case TRANSACTION_initStreamVolume:
1017 case TRANSACTION_setStreamVolumeIndex:
1018 case TRANSACTION_setVolumeIndexForAttributes:
1019 case TRANSACTION_getStreamVolumeIndex:
1020 case TRANSACTION_getVolumeIndexForAttributes:
1021 case TRANSACTION_getMinVolumeIndexForAttributes:
1022 case TRANSACTION_getMaxVolumeIndexForAttributes:
1023 case TRANSACTION_isStreamActive:
1024 case TRANSACTION_isStreamActiveRemotely:
1025 case TRANSACTION_isSourceActive:
1026 case TRANSACTION_getDevicesForStream:
1027 case TRANSACTION_registerPolicyMixes:
1028 case TRANSACTION_setMasterMono:
1029 case TRANSACTION_getSurroundFormats:
Kriti Dang6537def2021-03-02 13:46:59 +01001030 case TRANSACTION_getReportedSurroundFormats:
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001031 case TRANSACTION_setSurroundFormatEnabled:
1032 case TRANSACTION_setAssistantUid:
1033 case TRANSACTION_setA11yServicesUids:
1034 case TRANSACTION_setUidDeviceAffinities:
1035 case TRANSACTION_removeUidDeviceAffinities:
1036 case TRANSACTION_setUserIdDeviceAffinities:
1037 case TRANSACTION_removeUserIdDeviceAffinities:
1038 case TRANSACTION_getHwOffloadEncodingFormatsSupportedForA2DP:
1039 case TRANSACTION_listAudioVolumeGroups:
1040 case TRANSACTION_getVolumeGroupFromAudioAttributes:
1041 case TRANSACTION_acquireSoundTriggerSession:
1042 case TRANSACTION_releaseSoundTriggerSession:
1043 case TRANSACTION_setRttEnabled:
1044 case TRANSACTION_isCallScreenModeSupported:
1045 case TRANSACTION_setDevicesRoleForStrategy:
1046 case TRANSACTION_setSupportedSystemUsages:
1047 case TRANSACTION_removeDevicesRoleForStrategy:
1048 case TRANSACTION_getDevicesForRoleAndStrategy:
1049 case TRANSACTION_getDevicesForAttributes:
1050 case TRANSACTION_setAllowedCapturePolicy:
1051 case TRANSACTION_onNewAudioModulesAvailable:
1052 case TRANSACTION_setCurrentImeUid:
1053 case TRANSACTION_registerSoundTriggerCaptureStateListener:
1054 case TRANSACTION_setDevicesRoleForCapturePreset:
1055 case TRANSACTION_addDevicesRoleForCapturePreset:
1056 case TRANSACTION_removeDevicesRoleForCapturePreset:
1057 case TRANSACTION_clearDevicesRoleForCapturePreset:
Eric Laurent81dd0f52021-07-05 11:54:40 +02001058 case TRANSACTION_getDevicesForRoleAndCapturePreset:
1059 case TRANSACTION_getSpatializer: {
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08001060 if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
1061 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
1062 __func__, code, IPCThreadState::self()->getCallingPid(),
1063 IPCThreadState::self()->getCallingUid());
1064 return INVALID_OPERATION;
1065 }
1066 } break;
1067 default:
1068 break;
1069 }
1070
1071 std::string tag("IAudioPolicyService command " + std::to_string(code));
1072 TimeCheck check(tag.c_str());
1073
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001074 switch (code) {
1075 case SHELL_COMMAND_TRANSACTION: {
1076 int in = data.readFileDescriptor();
1077 int out = data.readFileDescriptor();
1078 int err = data.readFileDescriptor();
1079 int argc = data.readInt32();
1080 Vector<String16> args;
1081 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1082 args.add(data.readString16());
1083 }
1084 sp<IBinder> unusedCallback;
1085 sp<IResultReceiver> resultReceiver;
1086 status_t status;
1087 if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1088 return status;
1089 }
1090 if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1091 return status;
1092 }
1093 status = shellCommand(in, out, err, args);
1094 if (resultReceiver != nullptr) {
1095 resultReceiver->send(status);
1096 }
1097 return NO_ERROR;
1098 }
1099 }
1100
Mathias Agopian65ab4712010-07-14 17:59:35 -07001101 return BnAudioPolicyService::onTransact(code, data, reply, flags);
1102}
1103
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001104// ------------------- Shell command implementation -------------------
1105
1106// NOTE: This is a remote API - make sure all args are validated
1107status_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
1108 if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
1109 return PERMISSION_DENIED;
1110 }
1111 if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
1112 return BAD_VALUE;
1113 }
jovanakbe066e12019-09-02 11:54:39 -07001114 if (args.size() >= 3 && args[0] == String16("set-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001115 return handleSetUidState(args, err);
jovanakbe066e12019-09-02 11:54:39 -07001116 } else if (args.size() >= 2 && args[0] == String16("reset-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001117 return handleResetUidState(args, err);
jovanakbe066e12019-09-02 11:54:39 -07001118 } else if (args.size() >= 2 && args[0] == String16("get-uid-state")) {
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001119 return handleGetUidState(args, out, err);
Eric Laurent269acb42021-04-23 16:53:22 +02001120 } else if (args.size() >= 1 && args[0] == String16("purge_permission-cache")) {
1121 purgePermissionCache();
1122 return NO_ERROR;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001123 } else if (args.size() == 1 && args[0] == String16("help")) {
1124 printHelp(out);
1125 return NO_ERROR;
1126 }
1127 printHelp(err);
1128 return BAD_VALUE;
1129}
1130
jovanakbe066e12019-09-02 11:54:39 -07001131static status_t getUidForPackage(String16 packageName, int userId, /*inout*/uid_t& uid, int err) {
1132 if (userId < 0) {
1133 ALOGE("Invalid user: %d", userId);
1134 dprintf(err, "Invalid user: %d\n", userId);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001135 return BAD_VALUE;
1136 }
jovanakbe066e12019-09-02 11:54:39 -07001137
1138 PermissionController pc;
1139 uid = pc.getPackageUid(packageName, 0);
1140 if (uid <= 0) {
1141 ALOGE("Unknown package: '%s'", String8(packageName).string());
1142 dprintf(err, "Unknown package: '%s'\n", String8(packageName).string());
1143 return BAD_VALUE;
1144 }
1145
1146 uid = multiuser_get_uid(userId, uid);
1147 return NO_ERROR;
1148}
1149
1150status_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) {
1151 // Valid arg.size() is 3 or 5, args.size() is 5 with --user option.
1152 if (!(args.size() == 3 || args.size() == 5)) {
1153 printHelp(err);
1154 return BAD_VALUE;
1155 }
1156
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001157 bool active = false;
1158 if (args[2] == String16("active")) {
1159 active = true;
1160 } else if ((args[2] != String16("idle"))) {
1161 ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
1162 return BAD_VALUE;
1163 }
jovanakbe066e12019-09-02 11:54:39 -07001164
1165 int userId = 0;
1166 if (args.size() >= 5 && args[3] == String16("--user")) {
1167 userId = atoi(String8(args[4]));
1168 }
1169
1170 uid_t uid;
1171 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1172 return BAD_VALUE;
1173 }
1174
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001175 sp<UidPolicy> uidPolicy;
1176 {
1177 Mutex::Autolock _l(mLock);
1178 uidPolicy = mUidPolicy;
1179 }
1180 if (uidPolicy) {
1181 uidPolicy->addOverrideUid(uid, active);
1182 return NO_ERROR;
1183 }
1184 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001185}
1186
1187status_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) {
jovanakbe066e12019-09-02 11:54:39 -07001188 // Valid arg.size() is 2 or 4, args.size() is 4 with --user option.
1189 if (!(args.size() == 2 || args.size() == 4)) {
1190 printHelp(err);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001191 return BAD_VALUE;
1192 }
jovanakbe066e12019-09-02 11:54:39 -07001193
1194 int userId = 0;
1195 if (args.size() >= 4 && args[2] == String16("--user")) {
1196 userId = atoi(String8(args[3]));
1197 }
1198
1199 uid_t uid;
1200 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1201 return BAD_VALUE;
1202 }
1203
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001204 sp<UidPolicy> uidPolicy;
1205 {
1206 Mutex::Autolock _l(mLock);
1207 uidPolicy = mUidPolicy;
1208 }
1209 if (uidPolicy) {
1210 uidPolicy->removeOverrideUid(uid);
1211 return NO_ERROR;
1212 }
1213 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001214}
1215
1216status_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) {
jovanakbe066e12019-09-02 11:54:39 -07001217 // Valid arg.size() is 2 or 4, args.size() is 4 with --user option.
1218 if (!(args.size() == 2 || args.size() == 4)) {
1219 printHelp(err);
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001220 return BAD_VALUE;
1221 }
jovanakbe066e12019-09-02 11:54:39 -07001222
1223 int userId = 0;
1224 if (args.size() >= 4 && args[2] == String16("--user")) {
1225 userId = atoi(String8(args[3]));
1226 }
1227
1228 uid_t uid;
1229 if (getUidForPackage(args[1], userId, uid, err) == BAD_VALUE) {
1230 return BAD_VALUE;
1231 }
1232
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001233 sp<UidPolicy> uidPolicy;
1234 {
1235 Mutex::Autolock _l(mLock);
1236 uidPolicy = mUidPolicy;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001237 }
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001238 if (uidPolicy) {
1239 return dprintf(out, uidPolicy->isUidActive(uid) ? "active\n" : "idle\n");
1240 }
1241 return NO_INIT;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001242}
1243
1244status_t AudioPolicyService::printHelp(int out) {
1245 return dprintf(out, "Audio policy service commands:\n"
jovanakbe066e12019-09-02 11:54:39 -07001246 " get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
1247 " set-uid-state <PACKAGE> <active|idle> [--user USER_ID] overrides the uid state\n"
1248 " reset-uid-state <PACKAGE> [--user USER_ID] clears the uid state override\n"
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001249 " help print this message\n");
1250}
1251
1252// ----------- AudioPolicyService::UidPolicy implementation ----------
1253
1254void AudioPolicyService::UidPolicy::registerSelf() {
Steven Moreland2f348142019-07-02 15:59:07 -07001255 status_t res = mAm.linkToDeath(this);
1256 mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001257 | ActivityManager::UID_OBSERVER_IDLE
Eric Laurente8c8b432018-10-17 10:08:02 -07001258 | ActivityManager::UID_OBSERVER_ACTIVE
1259 | ActivityManager::UID_OBSERVER_PROCSTATE,
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001260 ActivityManager::PROCESS_STATE_UNKNOWN,
1261 String16("audioserver"));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001262 if (!res) {
1263 Mutex::Autolock _l(mLock);
1264 mObserverRegistered = true;
1265 } else {
1266 ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
Eric Laurent4eb58f12018-12-07 16:41:02 -08001267
Steven Moreland2f348142019-07-02 15:59:07 -07001268 mAm.unregisterUidObserver(this);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001269 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001270}
1271
1272void AudioPolicyService::UidPolicy::unregisterSelf() {
Steven Moreland2f348142019-07-02 15:59:07 -07001273 mAm.unlinkToDeath(this);
1274 mAm.unregisterUidObserver(this);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001275 Mutex::Autolock _l(mLock);
1276 mObserverRegistered = false;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001277}
1278
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001279void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
1280 Mutex::Autolock _l(mLock);
1281 mCachedUids.clear();
1282 mObserverRegistered = false;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001283}
1284
Eric Laurente8c8b432018-10-17 10:08:02 -07001285void AudioPolicyService::UidPolicy::checkRegistered() {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001286 bool needToReregister = false;
1287 {
1288 Mutex::Autolock _l(mLock);
1289 needToReregister = !mObserverRegistered;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001290 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001291 if (needToReregister) {
1292 // Looks like ActivityManager has died previously, attempt to re-register.
1293 registerSelf();
1294 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001295}
1296
1297bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
1298 if (isServiceUid(uid)) return true;
1299 checkRegistered();
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001300 {
1301 Mutex::Autolock _l(mLock);
1302 auto overrideIter = mOverrideUids.find(uid);
1303 if (overrideIter != mOverrideUids.end()) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001304 return overrideIter->second.first;
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001305 }
1306 // In an absense of the ActivityManager, assume everything to be active.
1307 if (!mObserverRegistered) return true;
1308 auto cacheIter = mCachedUids.find(uid);
Mikhail Naganoveba668a2018-04-05 08:13:15 -07001309 if (cacheIter != mCachedUids.end()) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001310 return cacheIter->second.first;
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001311 }
1312 }
1313 ActivityManager am;
Hui Yu12c7ec72020-05-04 17:40:52 +00001314 bool active = am.isUidActive(uid, String16("audioserver"));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001315 {
1316 Mutex::Autolock _l(mLock);
Eric Laurente8c8b432018-10-17 10:08:02 -07001317 mCachedUids.insert(std::pair<uid_t,
1318 std::pair<bool, int>>(uid, std::pair<bool, int>(active,
1319 ActivityManager::PROCESS_STATE_UNKNOWN)));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001320 }
1321 return active;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001322}
1323
Eric Laurente8c8b432018-10-17 10:08:02 -07001324int AudioPolicyService::UidPolicy::getUidState(uid_t uid) {
1325 if (isServiceUid(uid)) {
1326 return ActivityManager::PROCESS_STATE_TOP;
1327 }
1328 checkRegistered();
1329 {
1330 Mutex::Autolock _l(mLock);
1331 auto overrideIter = mOverrideUids.find(uid);
1332 if (overrideIter != mOverrideUids.end()) {
1333 if (overrideIter->second.first) {
1334 if (overrideIter->second.second != ActivityManager::PROCESS_STATE_UNKNOWN) {
1335 return overrideIter->second.second;
1336 } else {
1337 auto cacheIter = mCachedUids.find(uid);
1338 if (cacheIter != mCachedUids.end()) {
1339 return cacheIter->second.second;
1340 }
1341 }
1342 }
1343 return ActivityManager::PROCESS_STATE_UNKNOWN;
1344 }
1345 // In an absense of the ActivityManager, assume everything to be active.
1346 if (!mObserverRegistered) {
1347 return ActivityManager::PROCESS_STATE_TOP;
1348 }
1349 auto cacheIter = mCachedUids.find(uid);
1350 if (cacheIter != mCachedUids.end()) {
1351 if (cacheIter->second.first) {
1352 return cacheIter->second.second;
1353 } else {
1354 return ActivityManager::PROCESS_STATE_UNKNOWN;
1355 }
1356 }
1357 }
1358 ActivityManager am;
Hui Yu12c7ec72020-05-04 17:40:52 +00001359 bool active = am.isUidActive(uid, String16("audioserver"));
Eric Laurente8c8b432018-10-17 10:08:02 -07001360 int state = ActivityManager::PROCESS_STATE_UNKNOWN;
1361 if (active) {
1362 state = am.getUidProcessState(uid, String16("audioserver"));
1363 }
1364 {
1365 Mutex::Autolock _l(mLock);
1366 mCachedUids.insert(std::pair<uid_t,
1367 std::pair<bool, int>>(uid, std::pair<bool, int>(active, state)));
1368 }
Eric Laurent4eb58f12018-12-07 16:41:02 -08001369
Eric Laurente8c8b432018-10-17 10:08:02 -07001370 return state;
1371}
1372
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001373void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001374 updateUid(&mCachedUids, uid, true, ActivityManager::PROCESS_STATE_UNKNOWN, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001375}
1376
1377void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001378 updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, false);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001379}
1380
1381void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001382 updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001383}
1384
Eric Laurente8c8b432018-10-17 10:08:02 -07001385void AudioPolicyService::UidPolicy::onUidStateChanged(uid_t uid,
1386 int32_t procState,
Hui Yu13ad0eb2019-09-09 10:27:07 -07001387 int64_t procStateSeq __unused,
1388 int32_t capability __unused) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001389 if (procState != ActivityManager::PROCESS_STATE_UNKNOWN) {
1390 updateUid(&mCachedUids, uid, true, procState, true);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001391 }
1392}
1393
1394void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001395 updateUid(&mOverrideUids, uid, active, ActivityManager::PROCESS_STATE_UNKNOWN, insert);
1396}
1397
1398void AudioPolicyService::UidPolicy::notifyService() {
1399 sp<AudioPolicyService> service = mService.promote();
1400 if (service != nullptr) {
1401 service->updateUidStates();
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001402 }
1403}
1404
Eric Laurente8c8b432018-10-17 10:08:02 -07001405void AudioPolicyService::UidPolicy::updateUid(std::unordered_map<uid_t,
1406 std::pair<bool, int>> *uids,
1407 uid_t uid,
1408 bool active,
1409 int state,
1410 bool insert) {
1411 if (isServiceUid(uid)) {
1412 return;
1413 }
1414 bool wasActive = isUidActive(uid);
1415 int previousState = getUidState(uid);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001416 {
1417 Mutex::Autolock _l(mLock);
Eric Laurente8c8b432018-10-17 10:08:02 -07001418 updateUidLocked(uids, uid, active, state, insert);
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001419 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001420 if (wasActive != isUidActive(uid) || state != previousState) {
1421 notifyService();
1422 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001423}
1424
Eric Laurente8c8b432018-10-17 10:08:02 -07001425void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t,
1426 std::pair<bool, int>> *uids,
1427 uid_t uid,
1428 bool active,
1429 int state,
1430 bool insert) {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001431 auto it = uids->find(uid);
1432 if (it != uids->end()) {
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001433 if (insert) {
Eric Laurente8c8b432018-10-17 10:08:02 -07001434 if (state == ActivityManager::PROCESS_STATE_UNKNOWN) {
1435 it->second.first = active;
1436 }
1437 if (it->second.first) {
1438 it->second.second = state;
1439 } else {
1440 it->second.second = ActivityManager::PROCESS_STATE_UNKNOWN;
1441 }
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001442 } else {
1443 uids->erase(it);
1444 }
Eric Laurente8c8b432018-10-17 10:08:02 -07001445 } else if (insert && (state == ActivityManager::PROCESS_STATE_UNKNOWN)) {
1446 uids->insert(std::pair<uid_t, std::pair<bool, int>>(uid,
1447 std::pair<bool, int>(active, state)));
Mikhail Naganoveae73eb2018-04-03 16:57:36 -07001448 }
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001449}
Mathias Agopian65ab4712010-07-14 17:59:35 -07001450
Eric Laurent4eb58f12018-12-07 16:41:02 -08001451bool AudioPolicyService::UidPolicy::isA11yOnTop() {
1452 for (const auto &uid : mCachedUids) {
Eric Laurent47670c92019-08-28 16:59:05 -07001453 if (!isA11yUid(uid.first)) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001454 continue;
1455 }
Amith Yamasanibcbb3002019-01-23 13:53:33 -08001456 if (uid.second.second >= ActivityManager::PROCESS_STATE_TOP
1457 && uid.second.second <= ActivityManager::PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
Eric Laurent4eb58f12018-12-07 16:41:02 -08001458 return true;
1459 }
1460 }
1461 return false;
1462}
1463
Eric Laurentb78763e2018-10-17 10:08:02 -07001464bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
1465{
1466 std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid);
1467 return it != mA11yUids.end();
1468}
1469
Michael Groovercfd28302018-12-11 19:16:46 -08001470// ----------- AudioPolicyService::SensorPrivacyService implementation ----------
1471void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
1472 SensorPrivacyManager spm;
1473 mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
1474 spm.addSensorPrivacyListener(this);
1475}
1476
Evan Severson241d9592021-01-08 12:16:02 -08001477void AudioPolicyService::SensorPrivacyPolicy::registerSelfForMicrophoneOnly(int userId) {
1478 SensorPrivacyManager spm;
1479 mSensorPrivacyEnabled = spm.isIndividualSensorPrivacyEnabled(userId,
1480 SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE);
1481 spm.addIndividualSensorPrivacyListener(userId,
1482 SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE, this);
1483}
1484
Michael Groovercfd28302018-12-11 19:16:46 -08001485void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
1486 SensorPrivacyManager spm;
1487 spm.removeSensorPrivacyListener(this);
1488}
1489
1490bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
1491 return mSensorPrivacyEnabled;
1492}
1493
1494binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
1495 mSensorPrivacyEnabled = enabled;
1496 sp<AudioPolicyService> service = mService.promote();
1497 if (service != nullptr) {
1498 service->updateUidStates();
1499 }
1500 return binder::Status::ok();
1501}
1502
Eric Laurented726cc2021-07-01 14:26:41 +02001503// ----------- AudioPolicyService::OpRecordAudioMonitor implementation ----------
1504
1505// static
1506sp<AudioPolicyService::OpRecordAudioMonitor>
1507AudioPolicyService::OpRecordAudioMonitor::createIfNeeded(
1508 const AttributionSourceState& attributionSource, const audio_attributes_t& attr,
1509 wp<AudioCommandThread> commandThread)
1510{
Eric Laurent987ce102021-07-05 12:11:51 +02001511 if (isAudioServerOrRootUid(attributionSource.uid)) {
1512 ALOGV("not silencing record for audio or root source %s",
Eric Laurented726cc2021-07-01 14:26:41 +02001513 attributionSource.toString().c_str());
1514 return nullptr;
1515 }
1516
1517 if (!AudioPolicyService::isAppOpSource(attr.source)) {
1518 ALOGD("not monitoring app op for uid %d and source %d",
1519 attributionSource.uid, attr.source);
1520 return nullptr;
1521 }
1522
1523 if (!attributionSource.packageName.has_value()
1524 || attributionSource.packageName.value().size() == 0) {
1525 return nullptr;
1526 }
1527 return new OpRecordAudioMonitor(attributionSource, getOpForSource(attr.source), commandThread);
1528}
1529
1530AudioPolicyService::OpRecordAudioMonitor::OpRecordAudioMonitor(
1531 const AttributionSourceState& attributionSource, int32_t appOp,
1532 wp<AudioCommandThread> commandThread) :
1533 mHasOp(true), mAttributionSource(attributionSource), mAppOp(appOp),
1534 mCommandThread(commandThread)
1535{
1536}
1537
1538AudioPolicyService::OpRecordAudioMonitor::~OpRecordAudioMonitor()
1539{
1540 if (mOpCallback != 0) {
1541 mAppOpsManager.stopWatchingMode(mOpCallback);
1542 }
1543 mOpCallback.clear();
1544}
1545
1546void AudioPolicyService::OpRecordAudioMonitor::onFirstRef()
1547{
1548 checkOp();
1549 mOpCallback = new RecordAudioOpCallback(this);
1550 ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
1551 // TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
1552 // since it controls the mic permission for legacy apps.
1553 mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
1554 mAttributionSource.packageName.value_or(""))),
1555 mOpCallback);
1556}
1557
1558bool AudioPolicyService::OpRecordAudioMonitor::hasOp() const {
1559 return mHasOp.load();
1560}
1561
1562// Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
1563// is updated in AppOp callback and in onFirstRef()
1564// Note this method is never called (and never to be) for audio server / root track
1565// due to the UID in createIfNeeded(). As a result for those record track, it's:
1566// - not called from constructor,
1567// - not called from RecordAudioOpCallback because the callback is not installed in this case
1568void AudioPolicyService::OpRecordAudioMonitor::checkOp(bool updateUidStates)
1569{
1570 // TODO: We need to always check AppOpsManager::OP_RECORD_AUDIO too
1571 // since it controls the mic permission for legacy apps.
1572 const int32_t mode = mAppOpsManager.checkOp(mAppOp,
1573 mAttributionSource.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
1574 mAttributionSource.packageName.value_or(""))));
1575 const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
1576 // verbose logging only log when appOp changed
1577 ALOGI_IF(hasIt != mHasOp.load(),
1578 "App op %d missing, %ssilencing record %s",
1579 mAppOp, hasIt ? "un" : "", mAttributionSource.toString().c_str());
1580 mHasOp.store(hasIt);
1581
1582 if (updateUidStates) {
1583 sp<AudioCommandThread> commandThread = mCommandThread.promote();
1584 if (commandThread != nullptr) {
1585 commandThread->updateUidStatesCommand();
1586 }
1587 }
1588}
1589
1590AudioPolicyService::OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
1591 const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
1592{ }
1593
1594void AudioPolicyService::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
1595 const String16& packageName __unused) {
1596 sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
1597 if (monitor != NULL) {
1598 if (op != monitor->getOp()) {
1599 return;
1600 }
1601 monitor->checkOp(true);
1602 }
1603}
1604
1605
Mathias Agopian65ab4712010-07-14 17:59:35 -07001606// ----------- AudioPolicyService::AudioCommandThread implementation ----------
1607
Eric Laurentbfb1b832013-01-07 09:53:42 -08001608AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
1609 const wp<AudioPolicyService>& service)
1610 : Thread(false), mName(name), mService(service)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001611{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001612}
1613
1614
1615AudioPolicyService::AudioCommandThread::~AudioCommandThread()
1616{
Eric Laurentbfb1b832013-01-07 09:53:42 -08001617 if (!mAudioCommands.isEmpty()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001618 release_wake_lock(mName.string());
1619 }
1620 mAudioCommands.clear();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001621}
1622
1623void AudioPolicyService::AudioCommandThread::onFirstRef()
1624{
Eric Laurentbfb1b832013-01-07 09:53:42 -08001625 run(mName.string(), ANDROID_PRIORITY_AUDIO);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001626}
1627
1628bool AudioPolicyService::AudioCommandThread::threadLoop()
1629{
Eric Laurentd7eda8d2016-02-02 17:18:39 -08001630 nsecs_t waitTime = -1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001631
1632 mLock.lock();
1633 while (!exitPending())
1634 {
Eric Laurent59a89232014-06-08 14:14:17 -07001635 sp<AudioPolicyService> svc;
1636 while (!mAudioCommands.isEmpty() && !exitPending()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001637 nsecs_t curTime = systemTime();
1638 // commands are sorted by increasing time stamp: execute them from index 0 and up
1639 if (mAudioCommands[0]->mTime <= curTime) {
Eric Laurent0ede8922014-05-09 18:04:42 -07001640 sp<AudioCommand> command = mAudioCommands[0];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001641 mAudioCommands.removeAt(0);
Eric Laurent0ede8922014-05-09 18:04:42 -07001642 mLastCommand = command;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001643
1644 switch (command->mCommand) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001645 case SET_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001646 VolumeData *data = (VolumeData *)command->mParam.get();
Steve Block3856b092011-10-20 11:56:00 +01001647 ALOGV("AudioCommandThread() processing set volume stream %d, \
Eric Laurentde070132010-07-13 04:45:46 -07001648 volume %f, output %d", data->mStream, data->mVolume, data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07001649 mLock.unlock();
Eric Laurentde070132010-07-13 04:45:46 -07001650 command->mStatus = AudioSystem::setStreamVolume(data->mStream,
1651 data->mVolume,
1652 data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07001653 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001654 }break;
1655 case SET_PARAMETERS: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001656 ParametersData *data = (ParametersData *)command->mParam.get();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07001657 ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
1658 data->mKeyValuePairs.string(), data->mIO);
Andy Hungfe726a62018-09-27 15:17:25 -07001659 mLock.unlock();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07001660 command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
Andy Hungfe726a62018-09-27 15:17:25 -07001661 mLock.lock();
Glenn Kastene53b9ea2012-03-12 16:29:55 -07001662 }break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001663 case SET_VOICE_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001664 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
Steve Block3856b092011-10-20 11:56:00 +01001665 ALOGV("AudioCommandThread() processing set voice volume volume %f",
Eric Laurentde070132010-07-13 04:45:46 -07001666 data->mVolume);
Andy Hungfe726a62018-09-27 15:17:25 -07001667 mLock.unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001668 command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
Andy Hungfe726a62018-09-27 15:17:25 -07001669 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001670 }break;
Eric Laurentbfb1b832013-01-07 09:53:42 -08001671 case STOP_OUTPUT: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001672 StopOutputData *data = (StopOutputData *)command->mParam.get();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001673 ALOGV("AudioCommandThread() processing stop output portId %d",
1674 data->mPortId);
Eric Laurent59a89232014-06-08 14:14:17 -07001675 svc = mService.promote();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001676 if (svc == 0) {
1677 break;
1678 }
1679 mLock.unlock();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001680 svc->doStopOutput(data->mPortId);
Eric Laurentbfb1b832013-01-07 09:53:42 -08001681 mLock.lock();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001682 }break;
1683 case RELEASE_OUTPUT: {
Eric Laurent0ede8922014-05-09 18:04:42 -07001684 ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001685 ALOGV("AudioCommandThread() processing release output portId %d",
1686 data->mPortId);
Eric Laurent59a89232014-06-08 14:14:17 -07001687 svc = mService.promote();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001688 if (svc == 0) {
1689 break;
1690 }
1691 mLock.unlock();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001692 svc->doReleaseOutput(data->mPortId);
Eric Laurentbfb1b832013-01-07 09:53:42 -08001693 mLock.lock();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001694 }break;
Eric Laurent951f4552014-05-20 10:48:17 -07001695 case CREATE_AUDIO_PATCH: {
1696 CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
1697 ALOGV("AudioCommandThread() processing create audio patch");
1698 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1699 if (af == 0) {
1700 command->mStatus = PERMISSION_DENIED;
1701 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07001702 mLock.unlock();
Eric Laurent951f4552014-05-20 10:48:17 -07001703 command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
Andy Hungfe726a62018-09-27 15:17:25 -07001704 mLock.lock();
Eric Laurent951f4552014-05-20 10:48:17 -07001705 }
1706 } break;
1707 case RELEASE_AUDIO_PATCH: {
1708 ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
1709 ALOGV("AudioCommandThread() processing release audio patch");
1710 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1711 if (af == 0) {
1712 command->mStatus = PERMISSION_DENIED;
1713 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07001714 mLock.unlock();
Eric Laurent951f4552014-05-20 10:48:17 -07001715 command->mStatus = af->releaseAudioPatch(data->mHandle);
Andy Hungfe726a62018-09-27 15:17:25 -07001716 mLock.lock();
Eric Laurent951f4552014-05-20 10:48:17 -07001717 }
1718 } break;
Eric Laurentb52c1522014-05-20 11:27:36 -07001719 case UPDATE_AUDIOPORT_LIST: {
1720 ALOGV("AudioCommandThread() processing update audio port list");
Eric Laurent59a89232014-06-08 14:14:17 -07001721 svc = mService.promote();
Eric Laurentb52c1522014-05-20 11:27:36 -07001722 if (svc == 0) {
1723 break;
1724 }
1725 mLock.unlock();
1726 svc->doOnAudioPortListUpdate();
1727 mLock.lock();
1728 }break;
1729 case UPDATE_AUDIOPATCH_LIST: {
1730 ALOGV("AudioCommandThread() processing update audio patch list");
Eric Laurent59a89232014-06-08 14:14:17 -07001731 svc = mService.promote();
Eric Laurentb52c1522014-05-20 11:27:36 -07001732 if (svc == 0) {
1733 break;
1734 }
1735 mLock.unlock();
1736 svc->doOnAudioPatchListUpdate();
1737 mLock.lock();
1738 }break;
François Gaffiecfe17322018-11-07 13:41:29 +01001739 case CHANGED_AUDIOVOLUMEGROUP: {
1740 AudioVolumeGroupData *data =
1741 static_cast<AudioVolumeGroupData *>(command->mParam.get());
1742 ALOGV("AudioCommandThread() processing update audio volume group");
1743 svc = mService.promote();
1744 if (svc == 0) {
1745 break;
1746 }
1747 mLock.unlock();
1748 svc->doOnAudioVolumeGroupChanged(data->mGroup, data->mFlags);
1749 mLock.lock();
1750 }break;
Eric Laurente1715a42014-05-20 11:30:42 -07001751 case SET_AUDIOPORT_CONFIG: {
1752 SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
1753 ALOGV("AudioCommandThread() processing set port config");
1754 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1755 if (af == 0) {
1756 command->mStatus = PERMISSION_DENIED;
1757 } else {
Andy Hungfe726a62018-09-27 15:17:25 -07001758 mLock.unlock();
Eric Laurente1715a42014-05-20 11:30:42 -07001759 command->mStatus = af->setAudioPortConfig(&data->mConfig);
Andy Hungfe726a62018-09-27 15:17:25 -07001760 mLock.lock();
Eric Laurente1715a42014-05-20 11:30:42 -07001761 }
1762 } break;
Jean-Michel Trivide801052015-04-14 19:10:14 -07001763 case DYN_POLICY_MIX_STATE_UPDATE: {
1764 DynPolicyMixStateUpdateData *data =
1765 (DynPolicyMixStateUpdateData *)command->mParam.get();
Jean-Michel Trivide801052015-04-14 19:10:14 -07001766 ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
1767 data->mRegId.string(), data->mState);
1768 svc = mService.promote();
1769 if (svc == 0) {
1770 break;
1771 }
1772 mLock.unlock();
1773 svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
1774 mLock.lock();
1775 } break;
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08001776 case RECORDING_CONFIGURATION_UPDATE: {
1777 RecordingConfigurationUpdateData *data =
1778 (RecordingConfigurationUpdateData *)command->mParam.get();
1779 ALOGV("AudioCommandThread() processing recording configuration update");
1780 svc = mService.promote();
1781 if (svc == 0) {
1782 break;
1783 }
1784 mLock.unlock();
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08001785 svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
Eric Laurenta9f86652018-11-28 17:23:11 -08001786 &data->mClientConfig, data->mClientEffects,
1787 &data->mDeviceConfig, data->mEffects,
1788 data->mPatchHandle, data->mSource);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08001789 mLock.lock();
1790 } break;
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001791 case SET_EFFECT_SUSPENDED: {
1792 SetEffectSuspendedData *data = (SetEffectSuspendedData *)command->mParam.get();
1793 ALOGV("AudioCommandThread() processing set effect suspended");
1794 sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1795 if (af != 0) {
1796 mLock.unlock();
1797 af->setEffectSuspended(data->mEffectId, data->mSessionId, data->mSuspended);
1798 mLock.lock();
1799 }
1800 } break;
Mikhail Naganov88b30d22020-03-09 19:43:13 +00001801 case AUDIO_MODULES_UPDATE: {
1802 ALOGV("AudioCommandThread() processing audio modules update");
1803 svc = mService.promote();
1804 if (svc == 0) {
1805 break;
1806 }
1807 mLock.unlock();
1808 svc->doOnNewAudioModulesAvailable();
1809 mLock.lock();
1810 } break;
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07001811 case ROUTING_UPDATED: {
1812 ALOGV("AudioCommandThread() processing routing update");
1813 svc = mService.promote();
1814 if (svc == 0) {
1815 break;
1816 }
1817 mLock.unlock();
1818 svc->doOnRoutingUpdated();
1819 mLock.lock();
1820 } break;
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001821
Eric Laurented726cc2021-07-01 14:26:41 +02001822 case UPDATE_UID_STATES: {
1823 ALOGV("AudioCommandThread() processing updateUID states");
1824 svc = mService.promote();
1825 if (svc == 0) {
1826 break;
1827 }
1828 mLock.unlock();
1829 svc->updateUidStates();
1830 mLock.lock();
1831 } break;
1832
Eric Laurent81dd0f52021-07-05 11:54:40 +02001833 case CHECK_SPATIALIZER: {
1834 ALOGV("AudioCommandThread() processing updateUID states");
1835 svc = mService.promote();
1836 if (svc == 0) {
1837 break;
1838 }
1839 mLock.unlock();
1840 svc->doOnCheckSpatializer();
1841 mLock.lock();
1842 } break;
1843
Mathias Agopian65ab4712010-07-14 17:59:35 -07001844 default:
Steve Block5ff1dd52012-01-05 23:22:43 +00001845 ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001846 }
Eric Laurent0ede8922014-05-09 18:04:42 -07001847 {
1848 Mutex::Autolock _l(command->mLock);
1849 if (command->mWaitStatus) {
1850 command->mWaitStatus = false;
1851 command->mCond.signal();
1852 }
1853 }
Eric Laurentd7eda8d2016-02-02 17:18:39 -08001854 waitTime = -1;
Zach Janga754b4f2015-10-27 01:29:34 +00001855 // release mLock before releasing strong reference on the service as
1856 // AudioPolicyService destructor calls AudioCommandThread::exit() which
1857 // acquires mLock.
1858 mLock.unlock();
1859 svc.clear();
1860 mLock.lock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001861 } else {
1862 waitTime = mAudioCommands[0]->mTime - curTime;
1863 break;
1864 }
1865 }
Zach Janga754b4f2015-10-27 01:29:34 +00001866
1867 // release delayed commands wake lock if the queue is empty
1868 if (mAudioCommands.isEmpty()) {
Ricardo Garcia05f2fdc2014-07-24 15:48:24 -07001869 release_wake_lock(mName.string());
Zach Janga754b4f2015-10-27 01:29:34 +00001870 }
1871
1872 // At this stage we have either an empty command queue or the first command in the queue
1873 // has a finite delay. So unless we are exiting it is safe to wait.
1874 if (!exitPending()) {
Eric Laurent59a89232014-06-08 14:14:17 -07001875 ALOGV("AudioCommandThread() going to sleep");
Eric Laurentd7eda8d2016-02-02 17:18:39 -08001876 if (waitTime == -1) {
1877 mWaitWorkCV.wait(mLock);
1878 } else {
1879 mWaitWorkCV.waitRelative(mLock, waitTime);
1880 }
Eric Laurent59a89232014-06-08 14:14:17 -07001881 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001882 }
Ricardo Garcia05f2fdc2014-07-24 15:48:24 -07001883 // release delayed commands wake lock before quitting
1884 if (!mAudioCommands.isEmpty()) {
1885 release_wake_lock(mName.string());
1886 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001887 mLock.unlock();
1888 return false;
1889}
1890
1891status_t AudioPolicyService::AudioCommandThread::dump(int fd)
1892{
1893 const size_t SIZE = 256;
1894 char buffer[SIZE];
1895 String8 result;
1896
1897 snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
1898 result.append(buffer);
1899 write(fd, result.string(), result.size());
1900
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001901 const bool locked = dumpTryLock(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001902 if (!locked) {
1903 String8 result2(kCmdDeadlockedString);
1904 write(fd, result2.string(), result2.size());
1905 }
1906
1907 snprintf(buffer, SIZE, "- Commands:\n");
1908 result = String8(buffer);
1909 result.append(" Command Time Wait pParam\n");
Glenn Kasten8d6a2442012-02-08 14:04:28 -08001910 for (size_t i = 0; i < mAudioCommands.size(); i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001911 mAudioCommands[i]->dump(buffer, SIZE);
1912 result.append(buffer);
1913 }
1914 result.append(" Last Command\n");
Eric Laurent0ede8922014-05-09 18:04:42 -07001915 if (mLastCommand != 0) {
1916 mLastCommand->dump(buffer, SIZE);
1917 result.append(buffer);
1918 } else {
1919 result.append(" none\n");
1920 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001921
1922 write(fd, result.string(), result.size());
1923
Mikhail Naganov12b716c2020-04-30 22:37:43 +00001924 dumpReleaseLock(mLock, locked);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001925
1926 return NO_ERROR;
1927}
1928
Glenn Kastenfff6d712012-01-12 16:38:12 -08001929status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
Eric Laurentde070132010-07-13 04:45:46 -07001930 float volume,
Glenn Kasten72ef00d2012-01-17 11:09:42 -08001931 audio_io_handle_t output,
Eric Laurentde070132010-07-13 04:45:46 -07001932 int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001933{
Eric Laurent0ede8922014-05-09 18:04:42 -07001934 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001935 command->mCommand = SET_VOLUME;
Eric Laurent0ede8922014-05-09 18:04:42 -07001936 sp<VolumeData> data = new VolumeData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001937 data->mStream = stream;
1938 data->mVolume = volume;
1939 data->mIO = output;
1940 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07001941 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01001942 ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
Eric Laurentde070132010-07-13 04:45:46 -07001943 stream, volume, output);
Eric Laurent0ede8922014-05-09 18:04:42 -07001944 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001945}
1946
Glenn Kasten72ef00d2012-01-17 11:09:42 -08001947status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
Dima Zavinfce7a472011-04-19 22:30:36 -07001948 const char *keyValuePairs,
Eric Laurentde070132010-07-13 04:45:46 -07001949 int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001950{
Eric Laurent0ede8922014-05-09 18:04:42 -07001951 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001952 command->mCommand = SET_PARAMETERS;
Eric Laurent0ede8922014-05-09 18:04:42 -07001953 sp<ParametersData> data = new ParametersData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001954 data->mIO = ioHandle;
Dima Zavinfce7a472011-04-19 22:30:36 -07001955 data->mKeyValuePairs = String8(keyValuePairs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001956 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07001957 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01001958 ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
Dima Zavinfce7a472011-04-19 22:30:36 -07001959 keyValuePairs, ioHandle, delayMs);
Eric Laurent0ede8922014-05-09 18:04:42 -07001960 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001961}
1962
1963status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
1964{
Eric Laurent0ede8922014-05-09 18:04:42 -07001965 sp<AudioCommand> command = new AudioCommand();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001966 command->mCommand = SET_VOICE_VOLUME;
Eric Laurent0ede8922014-05-09 18:04:42 -07001967 sp<VoiceVolumeData> data = new VoiceVolumeData();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001968 data->mVolume = volume;
1969 command->mParam = data;
Eric Laurent0ede8922014-05-09 18:04:42 -07001970 command->mWaitStatus = true;
Steve Block3856b092011-10-20 11:56:00 +01001971 ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
Eric Laurent0ede8922014-05-09 18:04:42 -07001972 return sendCommand(command, delayMs);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001973}
1974
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001975void AudioPolicyService::AudioCommandThread::setEffectSuspendedCommand(int effectId,
1976 audio_session_t sessionId,
1977 bool suspended)
1978{
1979 sp<AudioCommand> command = new AudioCommand();
1980 command->mCommand = SET_EFFECT_SUSPENDED;
1981 sp<SetEffectSuspendedData> data = new SetEffectSuspendedData();
1982 data->mEffectId = effectId;
1983 data->mSessionId = sessionId;
1984 data->mSuspended = suspended;
1985 command->mParam = data;
1986 ALOGV("AudioCommandThread() adding set suspended effectId %d sessionId %d suspended %d",
1987 effectId, sessionId, suspended);
1988 sendCommand(command);
1989}
1990
1991
Eric Laurentd7fe0862018-07-14 16:48:01 -07001992void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_port_handle_t portId)
Eric Laurentbfb1b832013-01-07 09:53:42 -08001993{
Eric Laurent0ede8922014-05-09 18:04:42 -07001994 sp<AudioCommand> command = new AudioCommand();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001995 command->mCommand = STOP_OUTPUT;
Eric Laurent0ede8922014-05-09 18:04:42 -07001996 sp<StopOutputData> data = new StopOutputData();
Eric Laurentd7fe0862018-07-14 16:48:01 -07001997 data->mPortId = portId;
Jesper Tragardh48412dc2014-03-24 14:12:43 +01001998 command->mParam = data;
Eric Laurentd7fe0862018-07-14 16:48:01 -07001999 ALOGV("AudioCommandThread() adding stop output portId %d", portId);
Eric Laurent0ede8922014-05-09 18:04:42 -07002000 sendCommand(command);
Eric Laurentbfb1b832013-01-07 09:53:42 -08002001}
2002
Eric Laurentd7fe0862018-07-14 16:48:01 -07002003void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_port_handle_t portId)
Eric Laurentbfb1b832013-01-07 09:53:42 -08002004{
Eric Laurent0ede8922014-05-09 18:04:42 -07002005 sp<AudioCommand> command = new AudioCommand();
Eric Laurentbfb1b832013-01-07 09:53:42 -08002006 command->mCommand = RELEASE_OUTPUT;
Eric Laurent0ede8922014-05-09 18:04:42 -07002007 sp<ReleaseOutputData> data = new ReleaseOutputData();
Eric Laurentd7fe0862018-07-14 16:48:01 -07002008 data->mPortId = portId;
Jesper Tragardh48412dc2014-03-24 14:12:43 +01002009 command->mParam = data;
Eric Laurentd7fe0862018-07-14 16:48:01 -07002010 ALOGV("AudioCommandThread() adding release output portId %d", portId);
Eric Laurent0ede8922014-05-09 18:04:42 -07002011 sendCommand(command);
2012}
2013
Eric Laurent951f4552014-05-20 10:48:17 -07002014status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
2015 const struct audio_patch *patch,
2016 audio_patch_handle_t *handle,
2017 int delayMs)
2018{
2019 status_t status = NO_ERROR;
2020
2021 sp<AudioCommand> command = new AudioCommand();
2022 command->mCommand = CREATE_AUDIO_PATCH;
2023 CreateAudioPatchData *data = new CreateAudioPatchData();
2024 data->mPatch = *patch;
2025 data->mHandle = *handle;
2026 command->mParam = data;
2027 command->mWaitStatus = true;
2028 ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
2029 status = sendCommand(command, delayMs);
2030 if (status == NO_ERROR) {
2031 *handle = data->mHandle;
2032 }
2033 return status;
2034}
2035
2036status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
2037 int delayMs)
2038{
2039 sp<AudioCommand> command = new AudioCommand();
2040 command->mCommand = RELEASE_AUDIO_PATCH;
2041 ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
2042 data->mHandle = handle;
2043 command->mParam = data;
2044 command->mWaitStatus = true;
2045 ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
2046 return sendCommand(command, delayMs);
2047}
2048
Eric Laurentb52c1522014-05-20 11:27:36 -07002049void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
2050{
2051 sp<AudioCommand> command = new AudioCommand();
2052 command->mCommand = UPDATE_AUDIOPORT_LIST;
2053 ALOGV("AudioCommandThread() adding update audio port list");
2054 sendCommand(command);
2055}
2056
Eric Laurented726cc2021-07-01 14:26:41 +02002057void AudioPolicyService::AudioCommandThread::updateUidStatesCommand()
2058{
2059 sp<AudioCommand> command = new AudioCommand();
2060 command->mCommand = UPDATE_UID_STATES;
2061 ALOGV("AudioCommandThread() adding update UID states");
2062 sendCommand(command);
2063}
2064
Eric Laurentb52c1522014-05-20 11:27:36 -07002065void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
2066{
2067 sp<AudioCommand>command = new AudioCommand();
2068 command->mCommand = UPDATE_AUDIOPATCH_LIST;
2069 ALOGV("AudioCommandThread() adding update audio patch list");
2070 sendCommand(command);
2071}
2072
François Gaffiecfe17322018-11-07 13:41:29 +01002073void AudioPolicyService::AudioCommandThread::changeAudioVolumeGroupCommand(volume_group_t group,
2074 int flags)
2075{
2076 sp<AudioCommand>command = new AudioCommand();
2077 command->mCommand = CHANGED_AUDIOVOLUMEGROUP;
2078 AudioVolumeGroupData *data= new AudioVolumeGroupData();
2079 data->mGroup = group;
2080 data->mFlags = flags;
2081 command->mParam = data;
2082 ALOGV("AudioCommandThread() adding audio volume group changed");
2083 sendCommand(command);
2084}
2085
Eric Laurente1715a42014-05-20 11:30:42 -07002086status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
2087 const struct audio_port_config *config, int delayMs)
2088{
2089 sp<AudioCommand> command = new AudioCommand();
2090 command->mCommand = SET_AUDIOPORT_CONFIG;
2091 SetAudioPortConfigData *data = new SetAudioPortConfigData();
2092 data->mConfig = *config;
2093 command->mParam = data;
2094 command->mWaitStatus = true;
2095 ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
2096 return sendCommand(command, delayMs);
2097}
2098
Jean-Michel Trivide801052015-04-14 19:10:14 -07002099void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07002100 const String8& regId, int32_t state)
Jean-Michel Trivide801052015-04-14 19:10:14 -07002101{
2102 sp<AudioCommand> command = new AudioCommand();
2103 command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
2104 DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
2105 data->mRegId = regId;
2106 data->mState = state;
2107 command->mParam = data;
2108 ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
2109 regId.string(), state);
2110 sendCommand(command);
2111}
2112
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002113void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
Eric Laurenta9f86652018-11-28 17:23:11 -08002114 int event,
2115 const record_client_info_t *clientInfo,
2116 const audio_config_base_t *clientConfig,
2117 std::vector<effect_descriptor_t> clientEffects,
2118 const audio_config_base_t *deviceConfig,
2119 std::vector<effect_descriptor_t> effects,
2120 audio_patch_handle_t patchHandle,
2121 audio_source_t source)
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002122{
2123 sp<AudioCommand>command = new AudioCommand();
2124 command->mCommand = RECORDING_CONFIGURATION_UPDATE;
2125 RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
2126 data->mEvent = event;
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002127 data->mClientInfo = *clientInfo;
Jean-Michel Trivi7281aa92016-02-17 15:33:40 -08002128 data->mClientConfig = *clientConfig;
Eric Laurenta9f86652018-11-28 17:23:11 -08002129 data->mClientEffects = clientEffects;
Jean-Michel Trivi7281aa92016-02-17 15:33:40 -08002130 data->mDeviceConfig = *deviceConfig;
Eric Laurenta9f86652018-11-28 17:23:11 -08002131 data->mEffects = effects;
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08002132 data->mPatchHandle = patchHandle;
Eric Laurenta9f86652018-11-28 17:23:11 -08002133 data->mSource = source;
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002134 command->mParam = data;
Jean-Michel Triviac4e4292016-12-22 11:39:31 -08002135 ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
2136 event, clientInfo->source, clientInfo->uid);
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002137 sendCommand(command);
2138}
2139
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002140void AudioPolicyService::AudioCommandThread::audioModulesUpdateCommand()
2141{
2142 sp<AudioCommand> command = new AudioCommand();
2143 command->mCommand = AUDIO_MODULES_UPDATE;
2144 sendCommand(command);
2145}
2146
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002147void AudioPolicyService::AudioCommandThread::routingChangedCommand()
2148{
2149 sp<AudioCommand>command = new AudioCommand();
2150 command->mCommand = ROUTING_UPDATED;
2151 ALOGV("AudioCommandThread() adding routing update");
2152 sendCommand(command);
2153}
2154
Eric Laurent81dd0f52021-07-05 11:54:40 +02002155void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
2156{
2157 sp<AudioCommand>command = new AudioCommand();
2158 command->mCommand = CHECK_SPATIALIZER;
2159 ALOGV("AudioCommandThread() adding check spatializer");
2160 sendCommand(command);
2161}
2162
Eric Laurent0ede8922014-05-09 18:04:42 -07002163status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
2164{
2165 {
2166 Mutex::Autolock _l(mLock);
2167 insertCommand_l(command, delayMs);
2168 mWaitWorkCV.signal();
2169 }
2170 Mutex::Autolock _l(command->mLock);
2171 while (command->mWaitStatus) {
2172 nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
2173 if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
2174 command->mStatus = TIMED_OUT;
2175 command->mWaitStatus = false;
2176 }
2177 }
2178 return command->mStatus;
Eric Laurentbfb1b832013-01-07 09:53:42 -08002179}
2180
Mathias Agopian65ab4712010-07-14 17:59:35 -07002181// insertCommand_l() must be called with mLock held
Eric Laurent0ede8922014-05-09 18:04:42 -07002182void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002183{
Glenn Kasten8d6a2442012-02-08 14:04:28 -08002184 ssize_t i; // not size_t because i will count down to -1
Eric Laurent0ede8922014-05-09 18:04:42 -07002185 Vector < sp<AudioCommand> > removedCommands;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002186 command->mTime = systemTime() + milliseconds(delayMs);
2187
2188 // acquire wake lock to make sure delayed commands are processed
Eric Laurentbfb1b832013-01-07 09:53:42 -08002189 if (mAudioCommands.isEmpty()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002190 acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
2191 }
2192
2193 // check same pending commands with later time stamps and eliminate them
Ivan Lozano5ff158f2017-10-30 09:06:24 -07002194 for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002195 sp<AudioCommand> command2 = mAudioCommands[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07002196 // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
2197 if (command2->mTime <= command->mTime) break;
Eric Laurente45b48a2014-09-04 16:40:57 -07002198
2199 // create audio patch or release audio patch commands are equivalent
2200 // with regard to filtering
2201 if ((command->mCommand == CREATE_AUDIO_PATCH) ||
2202 (command->mCommand == RELEASE_AUDIO_PATCH)) {
2203 if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
2204 (command2->mCommand != RELEASE_AUDIO_PATCH)) {
2205 continue;
2206 }
2207 } else if (command2->mCommand != command->mCommand) continue;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002208
2209 switch (command->mCommand) {
2210 case SET_PARAMETERS: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002211 ParametersData *data = (ParametersData *)command->mParam.get();
2212 ParametersData *data2 = (ParametersData *)command2->mParam.get();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002213 if (data->mIO != data2->mIO) break;
Steve Block3856b092011-10-20 11:56:00 +01002214 ALOGV("Comparing parameter command %s to new command %s",
Eric Laurentde070132010-07-13 04:45:46 -07002215 data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002216 AudioParameter param = AudioParameter(data->mKeyValuePairs);
2217 AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
2218 for (size_t j = 0; j < param.size(); j++) {
Glenn Kastene53b9ea2012-03-12 16:29:55 -07002219 String8 key;
2220 String8 value;
2221 param.getAt(j, key, value);
2222 for (size_t k = 0; k < param2.size(); k++) {
2223 String8 key2;
2224 String8 value2;
2225 param2.getAt(k, key2, value2);
2226 if (key2 == key) {
2227 param2.remove(key2);
2228 ALOGV("Filtering out parameter %s", key2.string());
2229 break;
2230 }
2231 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07002232 }
2233 // if all keys have been filtered out, remove the command.
2234 // otherwise, update the key value pairs
2235 if (param2.size() == 0) {
2236 removedCommands.add(command2);
2237 } else {
2238 data2->mKeyValuePairs = param2.toString();
2239 }
Eric Laurent21e54562013-09-23 12:08:05 -07002240 command->mTime = command2->mTime;
2241 // force delayMs to non 0 so that code below does not request to wait for
2242 // command status as the command is now delayed
2243 delayMs = 1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002244 } break;
2245
2246 case SET_VOLUME: {
Eric Laurent0ede8922014-05-09 18:04:42 -07002247 VolumeData *data = (VolumeData *)command->mParam.get();
2248 VolumeData *data2 = (VolumeData *)command2->mParam.get();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002249 if (data->mIO != data2->mIO) break;
2250 if (data->mStream != data2->mStream) break;
Steve Block3856b092011-10-20 11:56:00 +01002251 ALOGV("Filtering out volume command on output %d for stream %d",
Eric Laurentde070132010-07-13 04:45:46 -07002252 data->mIO, data->mStream);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002253 removedCommands.add(command2);
Eric Laurent21e54562013-09-23 12:08:05 -07002254 command->mTime = command2->mTime;
2255 // force delayMs to non 0 so that code below does not request to wait for
2256 // command status as the command is now delayed
2257 delayMs = 1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002258 } break;
Eric Laurente45b48a2014-09-04 16:40:57 -07002259
Eric Laurentbaf35fe2016-07-27 15:36:53 -07002260 case SET_VOICE_VOLUME: {
2261 VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
2262 VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
2263 ALOGV("Filtering out voice volume command value %f replaced by %f",
2264 data2->mVolume, data->mVolume);
2265 removedCommands.add(command2);
2266 command->mTime = command2->mTime;
2267 // force delayMs to non 0 so that code below does not request to wait for
2268 // command status as the command is now delayed
2269 delayMs = 1;
2270 } break;
2271
Eric Laurente45b48a2014-09-04 16:40:57 -07002272 case CREATE_AUDIO_PATCH:
2273 case RELEASE_AUDIO_PATCH: {
2274 audio_patch_handle_t handle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002275 struct audio_patch patch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002276 if (command->mCommand == CREATE_AUDIO_PATCH) {
2277 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002278 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002279 } else {
2280 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
Mikhail Naganov7be71d22018-05-23 16:51:46 -07002281 memset(&patch, 0, sizeof(patch));
Eric Laurente45b48a2014-09-04 16:40:57 -07002282 }
2283 audio_patch_handle_t handle2;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002284 struct audio_patch patch2;
Eric Laurente45b48a2014-09-04 16:40:57 -07002285 if (command2->mCommand == CREATE_AUDIO_PATCH) {
2286 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002287 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
Eric Laurente45b48a2014-09-04 16:40:57 -07002288 } else {
2289 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
Glenn Kastenf60b6b62015-07-06 10:53:26 -07002290 memset(&patch2, 0, sizeof(patch2));
Eric Laurente45b48a2014-09-04 16:40:57 -07002291 }
2292 if (handle != handle2) break;
Haynes Mathew Georgea2d4a6d2014-10-13 13:05:22 -07002293 /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
2294 same output. */
2295 if( (command->mCommand == CREATE_AUDIO_PATCH) &&
2296 (command2->mCommand == CREATE_AUDIO_PATCH) ) {
2297 bool isOutputDiff = false;
2298 if (patch.num_sources == patch2.num_sources) {
2299 for (unsigned count = 0; count < patch.num_sources; count++) {
2300 if (patch.sources[count].id != patch2.sources[count].id) {
2301 isOutputDiff = true;
2302 break;
2303 }
2304 }
2305 if (isOutputDiff)
2306 break;
2307 }
2308 }
Eric Laurente45b48a2014-09-04 16:40:57 -07002309 ALOGV("Filtering out %s audio patch command for handle %d",
2310 (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
2311 removedCommands.add(command2);
2312 command->mTime = command2->mTime;
2313 // force delayMs to non 0 so that code below does not request to wait for
2314 // command status as the command is now delayed
2315 delayMs = 1;
2316 } break;
2317
Jean-Michel Trivide801052015-04-14 19:10:14 -07002318 case DYN_POLICY_MIX_STATE_UPDATE: {
2319
2320 } break;
2321
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002322 case RECORDING_CONFIGURATION_UPDATE: {
2323
2324 } break;
2325
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002326 case ROUTING_UPDATED: {
2327
2328 } break;
2329
Mathias Agopian65ab4712010-07-14 17:59:35 -07002330 default:
2331 break;
2332 }
2333 }
2334
2335 // remove filtered commands
2336 for (size_t j = 0; j < removedCommands.size(); j++) {
2337 // removed commands always have time stamps greater than current command
2338 for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
Eric Laurent0ede8922014-05-09 18:04:42 -07002339 if (mAudioCommands[k].get() == removedCommands[j].get()) {
Steve Block3856b092011-10-20 11:56:00 +01002340 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002341 mAudioCommands.removeAt(k);
2342 break;
2343 }
2344 }
2345 }
2346 removedCommands.clear();
2347
Eric Laurentaa79bef2015-01-15 14:33:51 -08002348 // Disable wait for status if delay is not 0.
2349 // Except for create audio patch command because the returned patch handle
2350 // is needed by audio policy manager
2351 if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
Eric Laurentcec4abb2012-07-03 12:23:02 -07002352 command->mWaitStatus = false;
2353 }
Eric Laurentcec4abb2012-07-03 12:23:02 -07002354
Mathias Agopian65ab4712010-07-14 17:59:35 -07002355 // insert command at the right place according to its time stamp
Eric Laurent1e693b52014-07-09 15:03:28 -07002356 ALOGV("inserting command: %d at index %zd, num commands %zu",
2357 command->mCommand, i+1, mAudioCommands.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002358 mAudioCommands.insertAt(command, i + 1);
2359}
2360
2361void AudioPolicyService::AudioCommandThread::exit()
2362{
Steve Block3856b092011-10-20 11:56:00 +01002363 ALOGV("AudioCommandThread::exit");
Mathias Agopian65ab4712010-07-14 17:59:35 -07002364 {
2365 AutoMutex _l(mLock);
2366 requestExit();
2367 mWaitWorkCV.signal();
2368 }
Zach Janga754b4f2015-10-27 01:29:34 +00002369 // Note that we can call it from the thread loop if all other references have been released
2370 // but it will safely return WOULD_BLOCK in this case
Mathias Agopian65ab4712010-07-14 17:59:35 -07002371 requestExitAndWait();
2372}
2373
2374void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
2375{
2376 snprintf(buffer, size, " %02d %06d.%03d %01u %p\n",
2377 mCommand,
2378 (int)ns2s(mTime),
2379 (int)ns2ms(mTime)%1000,
2380 mWaitStatus,
Eric Laurent0ede8922014-05-09 18:04:42 -07002381 mParam.get());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002382}
2383
Dima Zavinfce7a472011-04-19 22:30:36 -07002384/******* helpers for the service_ops callbacks defined below *********/
2385void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
2386 const char *keyValuePairs,
2387 int delayMs)
2388{
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002389 mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
Dima Zavinfce7a472011-04-19 22:30:36 -07002390 delayMs);
2391}
2392
2393int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
2394 float volume,
2395 audio_io_handle_t output,
2396 int delayMs)
2397{
Glenn Kastenfff6d712012-01-12 16:38:12 -08002398 return (int)mAudioCommandThread->volumeCommand(stream, volume,
Glenn Kasten72ef00d2012-01-17 11:09:42 -08002399 output, delayMs);
Dima Zavinfce7a472011-04-19 22:30:36 -07002400}
2401
Dima Zavinfce7a472011-04-19 22:30:36 -07002402int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
2403{
2404 return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
2405}
2406
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002407void AudioPolicyService::setEffectSuspended(int effectId,
2408 audio_session_t sessionId,
2409 bool suspended)
2410{
2411 mAudioCommandThread->setEffectSuspendedCommand(effectId, sessionId, suspended);
2412}
2413
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08002414Status AudioPolicyService::onNewAudioModulesAvailable()
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002415{
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002416 mOutputCommandThread->audioModulesUpdateCommand();
Ytai Ben-Tsvi0a4904a2021-01-06 12:57:05 -08002417 return Status::ok();
Mikhail Naganov88b30d22020-03-09 19:43:13 +00002418}
2419
Eric Laurentb20cf7d2019-04-05 19:37:34 -07002420
Dima Zavinfce7a472011-04-19 22:30:36 -07002421extern "C" {
Eric Laurent2d388ec2014-03-07 13:25:54 -08002422audio_module_handle_t aps_load_hw_module(void *service __unused,
2423 const char *name);
2424audio_io_handle_t aps_open_output(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002425 audio_devices_t *pDevices,
2426 uint32_t *pSamplingRate,
2427 audio_format_t *pFormat,
2428 audio_channel_mask_t *pChannelMask,
2429 uint32_t *pLatencyMs,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002430 audio_output_flags_t flags);
Eric Laurenta4c5a552012-03-29 10:12:40 -07002431
Eric Laurent2d388ec2014-03-07 13:25:54 -08002432audio_io_handle_t aps_open_output_on_module(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002433 audio_module_handle_t module,
2434 audio_devices_t *pDevices,
2435 uint32_t *pSamplingRate,
2436 audio_format_t *pFormat,
2437 audio_channel_mask_t *pChannelMask,
2438 uint32_t *pLatencyMs,
Richard Fitzgeraldad3af332013-03-25 16:54:37 +00002439 audio_output_flags_t flags,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002440 const audio_offload_info_t *offloadInfo);
2441audio_io_handle_t aps_open_dup_output(void *service __unused,
Dima Zavinfce7a472011-04-19 22:30:36 -07002442 audio_io_handle_t output1,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002443 audio_io_handle_t output2);
2444int aps_close_output(void *service __unused, audio_io_handle_t output);
2445int aps_suspend_output(void *service __unused, audio_io_handle_t output);
2446int aps_restore_output(void *service __unused, audio_io_handle_t output);
2447audio_io_handle_t aps_open_input(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002448 audio_devices_t *pDevices,
2449 uint32_t *pSamplingRate,
2450 audio_format_t *pFormat,
2451 audio_channel_mask_t *pChannelMask,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002452 audio_in_acoustics_t acoustics __unused);
2453audio_io_handle_t aps_open_input_on_module(void *service __unused,
Eric Laurenta4c5a552012-03-29 10:12:40 -07002454 audio_module_handle_t module,
2455 audio_devices_t *pDevices,
2456 uint32_t *pSamplingRate,
2457 audio_format_t *pFormat,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002458 audio_channel_mask_t *pChannelMask);
2459int aps_close_input(void *service __unused, audio_io_handle_t input);
2460int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
Glenn Kastend848eb42016-03-08 13:42:11 -08002461int aps_move_effects(void *service __unused, audio_session_t session,
Dima Zavinfce7a472011-04-19 22:30:36 -07002462 audio_io_handle_t src_output,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002463 audio_io_handle_t dst_output);
2464char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
2465 const char *keys);
2466void aps_set_parameters(void *service, audio_io_handle_t io_handle,
2467 const char *kv_pairs, int delay_ms);
2468int aps_set_stream_volume(void *service, audio_stream_type_t stream,
Dima Zavinfce7a472011-04-19 22:30:36 -07002469 float volume, audio_io_handle_t output,
Eric Laurent2d388ec2014-03-07 13:25:54 -08002470 int delay_ms);
Eric Laurent2d388ec2014-03-07 13:25:54 -08002471int aps_set_voice_volume(void *service, float volume, int delay_ms);
2472};
Dima Zavinfce7a472011-04-19 22:30:36 -07002473
Mikhail Naganov1b2a7942017-12-08 10:18:09 -08002474} // namespace android