xref: /aosp_15_r20/frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2009 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioPolicyService"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include "Configuration.h"
21*ec779b8eSAndroid Build Coastguard Worker #include <stdint.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <sys/time.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <dlfcn.h>
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/clock.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <binder/PermissionController.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <binder/IResultReceiver.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <utils/String16.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <utils/threads.h>
34*ec779b8eSAndroid Build Coastguard Worker #include "AudioRecordClient.h"
35*ec779b8eSAndroid Build Coastguard Worker #include "AudioPolicyService.h"
36*ec779b8eSAndroid Build Coastguard Worker #include <hardware_legacy/power.h>
37*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversion.h>
38*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioEffect.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioParameter.h>
40*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/MethodStatistics.h>
41*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/ServiceUtilities.h>
42*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/TimeCheck.h>
43*ec779b8eSAndroid Build Coastguard Worker #include <sensorprivacy/SensorPrivacyManager.h>
44*ec779b8eSAndroid Build Coastguard Worker 
45*ec779b8eSAndroid Build Coastguard Worker #include <system/audio.h>
46*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_policy.h>
47*ec779b8eSAndroid Build Coastguard Worker #include <AudioPolicyConfig.h>
48*ec779b8eSAndroid Build Coastguard Worker #include <AudioPolicyManager.h>
49*ec779b8eSAndroid Build Coastguard Worker 
50*ec779b8eSAndroid Build Coastguard Worker namespace android {
51*ec779b8eSAndroid Build Coastguard Worker using binder::Status;
52*ec779b8eSAndroid Build Coastguard Worker using media::audio::common::Spatialization;
53*ec779b8eSAndroid Build Coastguard Worker 
54*ec779b8eSAndroid Build Coastguard Worker static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
55*ec779b8eSAndroid Build Coastguard Worker static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
56*ec779b8eSAndroid Build Coastguard Worker static const char kAudioPolicyManagerCustomPath[] = "libaudiopolicymanagercustom.so";
57*ec779b8eSAndroid Build Coastguard Worker 
58*ec779b8eSAndroid Build Coastguard Worker static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
59*ec779b8eSAndroid Build Coastguard Worker 
60*ec779b8eSAndroid Build Coastguard Worker static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
61*ec779b8eSAndroid Build Coastguard Worker 
62*ec779b8eSAndroid Build Coastguard Worker static const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY");
63*ec779b8eSAndroid Build Coastguard Worker 
64*ec779b8eSAndroid Build Coastguard Worker namespace {
65*ec779b8eSAndroid Build Coastguard Worker constexpr auto PERMISSION_GRANTED = permission::PermissionChecker::PERMISSION_GRANTED;
66*ec779b8eSAndroid Build Coastguard Worker }
67*ec779b8eSAndroid Build Coastguard Worker 
68*ec779b8eSAndroid Build Coastguard Worker // Creates an association between Binder code to name for IAudioPolicyService.
69*ec779b8eSAndroid Build Coastguard Worker #define IAUDIOPOLICYSERVICE_BINDER_METHOD_MACRO_LIST \
70*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(onNewAudioModulesAvailable) \
71*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setDeviceConnectionState) \
72*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getDeviceConnectionState) \
73*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(handleDeviceConfigChange) \
74*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setPhoneState) \
75*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setForceUse) \
76*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getForceUse) \
77*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getOutput) \
78*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getOutputForAttr) \
79*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(startOutput) \
80*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(stopOutput) \
81*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(releaseOutput) \
82*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getInputForAttr) \
83*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(startInput) \
84*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(stopInput) \
85*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(releaseInput) \
86*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setDeviceAbsoluteVolumeEnabled) \
87*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(initStreamVolume) \
88*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setStreamVolumeIndex) \
89*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getStreamVolumeIndex) \
90*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setVolumeIndexForAttributes) \
91*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getVolumeIndexForAttributes) \
92*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMaxVolumeIndexForAttributes) \
93*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMinVolumeIndexForAttributes) \
94*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getStrategyForStream) \
95*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getDevicesForAttributes) \
96*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getOutputForEffect) \
97*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(registerEffect) \
98*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(unregisterEffect) \
99*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setEffectEnabled) \
100*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(moveEffectsToIo) \
101*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isStreamActive) \
102*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isStreamActiveRemotely) \
103*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isSourceActive) \
104*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(queryDefaultPreProcessing) \
105*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(addSourceDefaultEffect) \
106*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(addStreamDefaultEffect) \
107*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(removeSourceDefaultEffect) \
108*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(removeStreamDefaultEffect) \
109*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setSupportedSystemUsages) \
110*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAllowedCapturePolicy) \
111*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getOffloadSupport) \
112*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isDirectOutputSupported) \
113*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(listAudioPorts) \
114*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAudioPort) \
115*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(createAudioPatch) \
116*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(releaseAudioPatch) \
117*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(listAudioPatches) \
118*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAudioPortConfig) \
119*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(registerClient) \
120*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAudioPortCallbacksEnabled) \
121*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAudioVolumeGroupCallbacksEnabled) \
122*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(acquireSoundTriggerSession) \
123*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(releaseSoundTriggerSession) \
124*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getPhoneState) \
125*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(registerPolicyMixes) \
126*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(updatePolicyMixes) \
127*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setUidDeviceAffinities) \
128*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(removeUidDeviceAffinities) \
129*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setUserIdDeviceAffinities) \
130*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(removeUserIdDeviceAffinities) \
131*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(startAudioSource) \
132*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(stopAudioSource) \
133*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setMasterMono) \
134*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMasterMono) \
135*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getStreamVolumeDB) \
136*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getSurroundFormats) \
137*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getReportedSurroundFormats) \
138*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getHwOffloadFormatsSupportedForBluetoothMedia) \
139*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setSurroundFormatEnabled) \
140*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAssistantServicesUids) \
141*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setActiveAssistantServicesUids) \
142*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setA11yServicesUids) \
143*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setCurrentImeUid) \
144*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isHapticPlaybackSupported) \
145*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isUltrasoundSupported) \
146*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isHotwordStreamSupported) \
147*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(listAudioProductStrategies) \
148*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getProductStrategyFromAudioAttributes) \
149*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(listAudioVolumeGroups) \
150*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getVolumeGroupFromAudioAttributes) \
151*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setRttEnabled) \
152*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isCallScreenModeSupported) \
153*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setDevicesRoleForStrategy) \
154*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(removeDevicesRoleForStrategy) \
155*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(clearDevicesRoleForStrategy) \
156*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getDevicesForRoleAndStrategy) \
157*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setDevicesRoleForCapturePreset) \
158*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(addDevicesRoleForCapturePreset) \
159*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(removeDevicesRoleForCapturePreset) \
160*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(clearDevicesRoleForCapturePreset) \
161*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getDevicesForRoleAndCapturePreset) \
162*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(registerSoundTriggerCaptureStateListener) \
163*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getSpatializer) \
164*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(canBeSpatialized) \
165*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getDirectPlaybackSupport) \
166*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getDirectProfilesForAttributes)  \
167*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getSupportedMixerAttributes) \
168*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setPreferredMixerAttributes) \
169*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getPreferredMixerAttributes) \
170*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(clearPreferredMixerAttributes) \
171*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getRegisteredPolicyMixes) \
172*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getPermissionController) \
173*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMmapPolicyInfos) \
174*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMmapPolicyForDevice) \
175*ec779b8eSAndroid Build Coastguard Worker                                                      \
176*ec779b8eSAndroid Build Coastguard Worker // singleton for Binder Method Statistics for IAudioPolicyService
getIAudioPolicyServiceStatistics()177*ec779b8eSAndroid Build Coastguard Worker static auto& getIAudioPolicyServiceStatistics() {
178*ec779b8eSAndroid Build Coastguard Worker     using Code = int;
179*ec779b8eSAndroid Build Coastguard Worker 
180*ec779b8eSAndroid Build Coastguard Worker #pragma push_macro("BINDER_METHOD_ENTRY")
181*ec779b8eSAndroid Build Coastguard Worker #undef BINDER_METHOD_ENTRY
182*ec779b8eSAndroid Build Coastguard Worker #define BINDER_METHOD_ENTRY(ENTRY) \
183*ec779b8eSAndroid Build Coastguard Worker         {(Code)media::BnAudioPolicyService::TRANSACTION_##ENTRY, #ENTRY},
184*ec779b8eSAndroid Build Coastguard Worker 
185*ec779b8eSAndroid Build Coastguard Worker     static mediautils::MethodStatistics<Code> methodStatistics{
186*ec779b8eSAndroid Build Coastguard Worker         IAUDIOPOLICYSERVICE_BINDER_METHOD_MACRO_LIST
187*ec779b8eSAndroid Build Coastguard Worker         METHOD_STATISTICS_BINDER_CODE_NAMES(Code)
188*ec779b8eSAndroid Build Coastguard Worker     };
189*ec779b8eSAndroid Build Coastguard Worker #pragma pop_macro("BINDER_METHOD_ENTRY")
190*ec779b8eSAndroid Build Coastguard Worker 
191*ec779b8eSAndroid Build Coastguard Worker     return methodStatistics;
192*ec779b8eSAndroid Build Coastguard Worker }
193*ec779b8eSAndroid Build Coastguard Worker 
194*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
195*ec779b8eSAndroid Build Coastguard Worker 
createAudioPolicyManager(AudioPolicyClientInterface * clientInterface)196*ec779b8eSAndroid Build Coastguard Worker static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
197*ec779b8eSAndroid Build Coastguard Worker {
198*ec779b8eSAndroid Build Coastguard Worker     AudioPolicyManager *apm = nullptr;
199*ec779b8eSAndroid Build Coastguard Worker     media::AudioPolicyConfig apmConfig;
200*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
201*ec779b8eSAndroid Build Coastguard Worker         auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
202*ec779b8eSAndroid Build Coastguard Worker         ALOGD("%s loading APM engine %s", __func__, config->getEngineLibraryNameSuffix().c_str());
203*ec779b8eSAndroid Build Coastguard Worker         apm = new AudioPolicyManager(config,
204*ec779b8eSAndroid Build Coastguard Worker                 loadApmEngineLibraryAndCreateEngine(
205*ec779b8eSAndroid Build Coastguard Worker                         config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
206*ec779b8eSAndroid Build Coastguard Worker                 clientInterface);
207*ec779b8eSAndroid Build Coastguard Worker     } else {
208*ec779b8eSAndroid Build Coastguard Worker         auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();  // This can't fail.
209*ec779b8eSAndroid Build Coastguard Worker         apm = new AudioPolicyManager(config,
210*ec779b8eSAndroid Build Coastguard Worker                 loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
211*ec779b8eSAndroid Build Coastguard Worker                 clientInterface);
212*ec779b8eSAndroid Build Coastguard Worker     }
213*ec779b8eSAndroid Build Coastguard Worker     status_t status = apm->initialize();
214*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
215*ec779b8eSAndroid Build Coastguard Worker         delete apm;
216*ec779b8eSAndroid Build Coastguard Worker         apm = nullptr;
217*ec779b8eSAndroid Build Coastguard Worker     }
218*ec779b8eSAndroid Build Coastguard Worker     return apm;
219*ec779b8eSAndroid Build Coastguard Worker }
220*ec779b8eSAndroid Build Coastguard Worker 
destroyAudioPolicyManager(AudioPolicyInterface * interface)221*ec779b8eSAndroid Build Coastguard Worker static void destroyAudioPolicyManager(AudioPolicyInterface *interface)
222*ec779b8eSAndroid Build Coastguard Worker {
223*ec779b8eSAndroid Build Coastguard Worker     delete interface;
224*ec779b8eSAndroid Build Coastguard Worker }
225*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
226*ec779b8eSAndroid Build Coastguard Worker 
AudioPolicyService()227*ec779b8eSAndroid Build Coastguard Worker AudioPolicyService::AudioPolicyService()
228*ec779b8eSAndroid Build Coastguard Worker     : BnAudioPolicyService(),
229*ec779b8eSAndroid Build Coastguard Worker       mAudioPolicyManager(NULL),
230*ec779b8eSAndroid Build Coastguard Worker       mAudioPolicyClient(NULL),
231*ec779b8eSAndroid Build Coastguard Worker       mPhoneState(AUDIO_MODE_INVALID),
232*ec779b8eSAndroid Build Coastguard Worker       mCaptureStateNotifier(false),
233*ec779b8eSAndroid Build Coastguard Worker       mCreateAudioPolicyManager(createAudioPolicyManager),
234*ec779b8eSAndroid Build Coastguard Worker       mDestroyAudioPolicyManager(destroyAudioPolicyManager),
235*ec779b8eSAndroid Build Coastguard Worker       mUsecaseValidator(media::createUsecaseValidator()),
236*ec779b8eSAndroid Build Coastguard Worker       mPermissionController(sp<NativePermissionController>::make())
237*ec779b8eSAndroid Build Coastguard Worker {
238*ec779b8eSAndroid Build Coastguard Worker       setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
239*ec779b8eSAndroid Build Coastguard Worker       setInheritRt(true);
240*ec779b8eSAndroid Build Coastguard Worker }
241*ec779b8eSAndroid Build Coastguard Worker 
loadAudioPolicyManager()242*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::loadAudioPolicyManager()
243*ec779b8eSAndroid Build Coastguard Worker {
244*ec779b8eSAndroid Build Coastguard Worker     mLibraryHandle = dlopen(kAudioPolicyManagerCustomPath, RTLD_NOW);
245*ec779b8eSAndroid Build Coastguard Worker     if (mLibraryHandle != nullptr) {
246*ec779b8eSAndroid Build Coastguard Worker         ALOGI("%s loading %s", __func__, kAudioPolicyManagerCustomPath);
247*ec779b8eSAndroid Build Coastguard Worker         mCreateAudioPolicyManager = reinterpret_cast<CreateAudioPolicyManagerInstance>
248*ec779b8eSAndroid Build Coastguard Worker                                             (dlsym(mLibraryHandle, "createAudioPolicyManager"));
249*ec779b8eSAndroid Build Coastguard Worker         const char *lastError = dlerror();
250*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(mCreateAudioPolicyManager == nullptr, "%s createAudioPolicyManager is null %s",
251*ec779b8eSAndroid Build Coastguard Worker                     __func__, lastError != nullptr ? lastError : "no error");
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker         mDestroyAudioPolicyManager = reinterpret_cast<DestroyAudioPolicyManagerInstance>(
254*ec779b8eSAndroid Build Coastguard Worker                                         dlsym(mLibraryHandle, "destroyAudioPolicyManager"));
255*ec779b8eSAndroid Build Coastguard Worker         lastError = dlerror();
256*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(mDestroyAudioPolicyManager == nullptr, "%s destroyAudioPolicyManager is null %s",
257*ec779b8eSAndroid Build Coastguard Worker                     __func__, lastError != nullptr ? lastError : "no error");
258*ec779b8eSAndroid Build Coastguard Worker         if (mCreateAudioPolicyManager == nullptr || mDestroyAudioPolicyManager == nullptr){
259*ec779b8eSAndroid Build Coastguard Worker             unloadAudioPolicyManager();
260*ec779b8eSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("could not find audiopolicymanager interface methods");
261*ec779b8eSAndroid Build Coastguard Worker         }
262*ec779b8eSAndroid Build Coastguard Worker     }
263*ec779b8eSAndroid Build Coastguard Worker }
264*ec779b8eSAndroid Build Coastguard Worker 
onFirstRef()265*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onFirstRef()
266*ec779b8eSAndroid Build Coastguard Worker {
267*ec779b8eSAndroid Build Coastguard Worker     // Log an AudioPolicy "constructor" mediametrics event on first ref.
268*ec779b8eSAndroid Build Coastguard Worker     // This records the time it takes to load the audio modules and devices.
269*ec779b8eSAndroid Build Coastguard Worker     mediametrics::Defer defer([beginNs = systemTime()] {
270*ec779b8eSAndroid Build Coastguard Worker         mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_POLICY)
271*ec779b8eSAndroid Build Coastguard Worker             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR)
272*ec779b8eSAndroid Build Coastguard Worker             .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
273*ec779b8eSAndroid Build Coastguard Worker             .record(); });
274*ec779b8eSAndroid Build Coastguard Worker     {
275*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
276*ec779b8eSAndroid Build Coastguard Worker 
277*ec779b8eSAndroid Build Coastguard Worker         // start audio commands thread
278*ec779b8eSAndroid Build Coastguard Worker         mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
279*ec779b8eSAndroid Build Coastguard Worker         // start output activity command thread
280*ec779b8eSAndroid Build Coastguard Worker         mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
281*ec779b8eSAndroid Build Coastguard Worker 
282*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyClient = new AudioPolicyClient(this);
283*ec779b8eSAndroid Build Coastguard Worker 
284*ec779b8eSAndroid Build Coastguard Worker         loadAudioPolicyManager();
285*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyManager = mCreateAudioPolicyManager(mAudioPolicyClient);
286*ec779b8eSAndroid Build Coastguard Worker     }
287*ec779b8eSAndroid Build Coastguard Worker 
288*ec779b8eSAndroid Build Coastguard Worker     // load audio processing modules
289*ec779b8eSAndroid Build Coastguard Worker     const sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
290*ec779b8eSAndroid Build Coastguard Worker     auto audioPolicyEffects = sp<AudioPolicyEffects>::make(effectsFactoryHal);
291*ec779b8eSAndroid Build Coastguard Worker     auto uidPolicy = sp<UidPolicy>::make(this);
292*ec779b8eSAndroid Build Coastguard Worker     auto sensorPrivacyPolicy = sp<SensorPrivacyPolicy>::make(this);
293*ec779b8eSAndroid Build Coastguard Worker     {
294*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
295*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyEffects = audioPolicyEffects;
296*ec779b8eSAndroid Build Coastguard Worker         mUidPolicy = uidPolicy;
297*ec779b8eSAndroid Build Coastguard Worker         mSensorPrivacyPolicy = sensorPrivacyPolicy;
298*ec779b8eSAndroid Build Coastguard Worker     }
299*ec779b8eSAndroid Build Coastguard Worker     uidPolicy->registerSelf();
300*ec779b8eSAndroid Build Coastguard Worker     sensorPrivacyPolicy->registerSelf();
301*ec779b8eSAndroid Build Coastguard Worker 
302*ec779b8eSAndroid Build Coastguard Worker     // Create spatializer if supported
303*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyManager != nullptr) {
304*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
305*ec779b8eSAndroid Build Coastguard Worker         const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
306*ec779b8eSAndroid Build Coastguard Worker         AudioDeviceTypeAddrVector devices;
307*ec779b8eSAndroid Build Coastguard Worker         bool hasSpatializer = mAudioPolicyManager->canBeSpatialized(&attr, nullptr, devices);
308*ec779b8eSAndroid Build Coastguard Worker         if (hasSpatializer) {
309*ec779b8eSAndroid Build Coastguard Worker             // Unlock as Spatializer::create() will use the callback and acquire the
310*ec779b8eSAndroid Build Coastguard Worker             // AudioPolicyService_Mutex.
311*ec779b8eSAndroid Build Coastguard Worker             mMutex.unlock();
312*ec779b8eSAndroid Build Coastguard Worker             mSpatializer = Spatializer::create(this, effectsFactoryHal);
313*ec779b8eSAndroid Build Coastguard Worker             mMutex.lock();
314*ec779b8eSAndroid Build Coastguard Worker         }
315*ec779b8eSAndroid Build Coastguard Worker         if (mSpatializer == nullptr) {
316*ec779b8eSAndroid Build Coastguard Worker             // No spatializer created, signal the reason: NO_INIT a failure, OK means intended.
317*ec779b8eSAndroid Build Coastguard Worker             const status_t createStatus = hasSpatializer ? NO_INIT : OK;
318*ec779b8eSAndroid Build Coastguard Worker             Spatializer::sendEmptyCreateSpatializerMetricWithStatus(createStatus);
319*ec779b8eSAndroid Build Coastguard Worker         }
320*ec779b8eSAndroid Build Coastguard Worker     }
321*ec779b8eSAndroid Build Coastguard Worker     AudioSystem::audioPolicyReady();
322*ec779b8eSAndroid Build Coastguard Worker }
323*ec779b8eSAndroid Build Coastguard Worker 
getPermissionProvider() const324*ec779b8eSAndroid Build Coastguard Worker const IPermissionProvider& AudioPolicyService::getPermissionProvider() const {
325*ec779b8eSAndroid Build Coastguard Worker     return *mPermissionController;
326*ec779b8eSAndroid Build Coastguard Worker }
327*ec779b8eSAndroid Build Coastguard Worker 
onAudioSystemReady()328*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onAudioSystemReady() {
329*ec779b8eSAndroid Build Coastguard Worker     sp<AudioPolicyEffects> audioPolicyEffects;
330*ec779b8eSAndroid Build Coastguard Worker     {
331*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
332*ec779b8eSAndroid Build Coastguard Worker 
333*ec779b8eSAndroid Build Coastguard Worker         audioPolicyEffects = mAudioPolicyEffects;
334*ec779b8eSAndroid Build Coastguard Worker     }
335*ec779b8eSAndroid Build Coastguard Worker     audioPolicyEffects->initDefaultDeviceEffects();
336*ec779b8eSAndroid Build Coastguard Worker }
337*ec779b8eSAndroid Build Coastguard Worker 
unloadAudioPolicyManager()338*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::unloadAudioPolicyManager()
339*ec779b8eSAndroid Build Coastguard Worker {
340*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s ", __func__);
341*ec779b8eSAndroid Build Coastguard Worker     if (mLibraryHandle != nullptr) {
342*ec779b8eSAndroid Build Coastguard Worker         dlclose(mLibraryHandle);
343*ec779b8eSAndroid Build Coastguard Worker     }
344*ec779b8eSAndroid Build Coastguard Worker     mLibraryHandle = nullptr;
345*ec779b8eSAndroid Build Coastguard Worker     mCreateAudioPolicyManager = nullptr;
346*ec779b8eSAndroid Build Coastguard Worker     mDestroyAudioPolicyManager = nullptr;
347*ec779b8eSAndroid Build Coastguard Worker }
348*ec779b8eSAndroid Build Coastguard Worker 
~AudioPolicyService()349*ec779b8eSAndroid Build Coastguard Worker AudioPolicyService::~AudioPolicyService()
350*ec779b8eSAndroid Build Coastguard Worker {
351*ec779b8eSAndroid Build Coastguard Worker     mAudioCommandThread->exit();
352*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->exit();
353*ec779b8eSAndroid Build Coastguard Worker 
354*ec779b8eSAndroid Build Coastguard Worker     mDestroyAudioPolicyManager(mAudioPolicyManager);
355*ec779b8eSAndroid Build Coastguard Worker     unloadAudioPolicyManager();
356*ec779b8eSAndroid Build Coastguard Worker 
357*ec779b8eSAndroid Build Coastguard Worker     delete mAudioPolicyClient;
358*ec779b8eSAndroid Build Coastguard Worker 
359*ec779b8eSAndroid Build Coastguard Worker     mNotificationClients.clear();
360*ec779b8eSAndroid Build Coastguard Worker     mAudioPolicyEffects.clear();
361*ec779b8eSAndroid Build Coastguard Worker 
362*ec779b8eSAndroid Build Coastguard Worker     mUidPolicy->unregisterSelf();
363*ec779b8eSAndroid Build Coastguard Worker     mSensorPrivacyPolicy->unregisterSelf();
364*ec779b8eSAndroid Build Coastguard Worker 
365*ec779b8eSAndroid Build Coastguard Worker     mUidPolicy.clear();
366*ec779b8eSAndroid Build Coastguard Worker     mSensorPrivacyPolicy.clear();
367*ec779b8eSAndroid Build Coastguard Worker }
368*ec779b8eSAndroid Build Coastguard Worker 
369*ec779b8eSAndroid Build Coastguard Worker // A notification client is always registered by AudioSystem when the client process
370*ec779b8eSAndroid Build Coastguard Worker // connects to AudioPolicyService.
registerClient(const sp<media::IAudioPolicyServiceClient> & client)371*ec779b8eSAndroid Build Coastguard Worker Status AudioPolicyService::registerClient(const sp<media::IAudioPolicyServiceClient>& client)
372*ec779b8eSAndroid Build Coastguard Worker {
373*ec779b8eSAndroid Build Coastguard Worker     if (client == 0) {
374*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s got NULL client", __FUNCTION__);
375*ec779b8eSAndroid Build Coastguard Worker         return Status::ok();
376*ec779b8eSAndroid Build Coastguard Worker     }
377*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
378*ec779b8eSAndroid Build Coastguard Worker 
379*ec779b8eSAndroid Build Coastguard Worker     uid_t uid = IPCThreadState::self()->getCallingUid();
380*ec779b8eSAndroid Build Coastguard Worker     pid_t pid = IPCThreadState::self()->getCallingPid();
381*ec779b8eSAndroid Build Coastguard Worker     int64_t token = ((int64_t)uid<<32) | pid;
382*ec779b8eSAndroid Build Coastguard Worker 
383*ec779b8eSAndroid Build Coastguard Worker     if (mNotificationClients.indexOfKey(token) < 0) {
384*ec779b8eSAndroid Build Coastguard Worker         sp<NotificationClient> notificationClient = new NotificationClient(this,
385*ec779b8eSAndroid Build Coastguard Worker                                                                            client,
386*ec779b8eSAndroid Build Coastguard Worker                                                                            uid,
387*ec779b8eSAndroid Build Coastguard Worker                                                                            pid);
388*ec779b8eSAndroid Build Coastguard Worker         ALOGV("registerClient() client %p, uid %d pid %d", client.get(), uid, pid);
389*ec779b8eSAndroid Build Coastguard Worker 
390*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.add(token, notificationClient);
391*ec779b8eSAndroid Build Coastguard Worker 
392*ec779b8eSAndroid Build Coastguard Worker         sp<IBinder> binder = IInterface::asBinder(client);
393*ec779b8eSAndroid Build Coastguard Worker         binder->linkToDeath(notificationClient);
394*ec779b8eSAndroid Build Coastguard Worker     }
395*ec779b8eSAndroid Build Coastguard Worker         return Status::ok();
396*ec779b8eSAndroid Build Coastguard Worker }
397*ec779b8eSAndroid Build Coastguard Worker 
setAudioPortCallbacksEnabled(bool enabled)398*ec779b8eSAndroid Build Coastguard Worker Status AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
399*ec779b8eSAndroid Build Coastguard Worker {
400*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
401*ec779b8eSAndroid Build Coastguard Worker 
402*ec779b8eSAndroid Build Coastguard Worker     uid_t uid = IPCThreadState::self()->getCallingUid();
403*ec779b8eSAndroid Build Coastguard Worker     pid_t pid = IPCThreadState::self()->getCallingPid();
404*ec779b8eSAndroid Build Coastguard Worker     int64_t token = ((int64_t)uid<<32) | pid;
405*ec779b8eSAndroid Build Coastguard Worker 
406*ec779b8eSAndroid Build Coastguard Worker     if (mNotificationClients.indexOfKey(token) < 0) {
407*ec779b8eSAndroid Build Coastguard Worker         return Status::ok();
408*ec779b8eSAndroid Build Coastguard Worker     }
409*ec779b8eSAndroid Build Coastguard Worker     mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
410*ec779b8eSAndroid Build Coastguard Worker     return Status::ok();
411*ec779b8eSAndroid Build Coastguard Worker }
412*ec779b8eSAndroid Build Coastguard Worker 
setAudioVolumeGroupCallbacksEnabled(bool enabled)413*ec779b8eSAndroid Build Coastguard Worker Status AudioPolicyService::setAudioVolumeGroupCallbacksEnabled(bool enabled)
414*ec779b8eSAndroid Build Coastguard Worker {
415*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
416*ec779b8eSAndroid Build Coastguard Worker 
417*ec779b8eSAndroid Build Coastguard Worker     uid_t uid = IPCThreadState::self()->getCallingUid();
418*ec779b8eSAndroid Build Coastguard Worker     pid_t pid = IPCThreadState::self()->getCallingPid();
419*ec779b8eSAndroid Build Coastguard Worker     int64_t token = ((int64_t)uid<<32) | pid;
420*ec779b8eSAndroid Build Coastguard Worker 
421*ec779b8eSAndroid Build Coastguard Worker     if (mNotificationClients.indexOfKey(token) < 0) {
422*ec779b8eSAndroid Build Coastguard Worker         return Status::ok();
423*ec779b8eSAndroid Build Coastguard Worker     }
424*ec779b8eSAndroid Build Coastguard Worker     mNotificationClients.valueFor(token)->setAudioVolumeGroupCallbacksEnabled(enabled);
425*ec779b8eSAndroid Build Coastguard Worker     return Status::ok();
426*ec779b8eSAndroid Build Coastguard Worker }
427*ec779b8eSAndroid Build Coastguard Worker 
428*ec779b8eSAndroid Build Coastguard Worker // removeNotificationClient() is called when the client process dies.
removeNotificationClient(uid_t uid,pid_t pid)429*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
430*ec779b8eSAndroid Build Coastguard Worker {
431*ec779b8eSAndroid Build Coastguard Worker     bool hasSameUid = false;
432*ec779b8eSAndroid Build Coastguard Worker     {
433*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mNotificationClientsMutex);
434*ec779b8eSAndroid Build Coastguard Worker         int64_t token = ((int64_t)uid<<32) | pid;
435*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.removeItem(token);
436*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mNotificationClients.size(); i++) {
437*ec779b8eSAndroid Build Coastguard Worker             if (mNotificationClients.valueAt(i)->uid() == uid) {
438*ec779b8eSAndroid Build Coastguard Worker                 hasSameUid = true;
439*ec779b8eSAndroid Build Coastguard Worker                 break;
440*ec779b8eSAndroid Build Coastguard Worker             }
441*ec779b8eSAndroid Build Coastguard Worker         }
442*ec779b8eSAndroid Build Coastguard Worker     }
443*ec779b8eSAndroid Build Coastguard Worker     {
444*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
445*ec779b8eSAndroid Build Coastguard Worker         if (mAudioPolicyManager && !hasSameUid) {
446*ec779b8eSAndroid Build Coastguard Worker             // called from binder death notification: no need to clear caller identity
447*ec779b8eSAndroid Build Coastguard Worker             mAudioPolicyManager->releaseResourcesForUid(uid);
448*ec779b8eSAndroid Build Coastguard Worker         }
449*ec779b8eSAndroid Build Coastguard Worker     }
450*ec779b8eSAndroid Build Coastguard Worker }
451*ec779b8eSAndroid Build Coastguard Worker 
onAudioPortListUpdate()452*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onAudioPortListUpdate()
453*ec779b8eSAndroid Build Coastguard Worker {
454*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->updateAudioPortListCommand();
455*ec779b8eSAndroid Build Coastguard Worker }
456*ec779b8eSAndroid Build Coastguard Worker 
doOnAudioPortListUpdate()457*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnAudioPortListUpdate()
458*ec779b8eSAndroid Build Coastguard Worker {
459*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
460*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
461*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onAudioPortListUpdate();
462*ec779b8eSAndroid Build Coastguard Worker     }
463*ec779b8eSAndroid Build Coastguard Worker }
464*ec779b8eSAndroid Build Coastguard Worker 
onAudioPatchListUpdate()465*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onAudioPatchListUpdate()
466*ec779b8eSAndroid Build Coastguard Worker {
467*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->updateAudioPatchListCommand();
468*ec779b8eSAndroid Build Coastguard Worker }
469*ec779b8eSAndroid Build Coastguard Worker 
doOnAudioPatchListUpdate()470*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnAudioPatchListUpdate()
471*ec779b8eSAndroid Build Coastguard Worker {
472*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
473*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
474*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
475*ec779b8eSAndroid Build Coastguard Worker     }
476*ec779b8eSAndroid Build Coastguard Worker }
477*ec779b8eSAndroid Build Coastguard Worker 
onAudioVolumeGroupChanged(volume_group_t group,int flags)478*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onAudioVolumeGroupChanged(volume_group_t group, int flags)
479*ec779b8eSAndroid Build Coastguard Worker {
480*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->changeAudioVolumeGroupCommand(group, flags);
481*ec779b8eSAndroid Build Coastguard Worker }
482*ec779b8eSAndroid Build Coastguard Worker 
doOnAudioVolumeGroupChanged(volume_group_t group,int flags)483*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnAudioVolumeGroupChanged(volume_group_t group, int flags)
484*ec779b8eSAndroid Build Coastguard Worker {
485*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
486*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
487*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onAudioVolumeGroupChanged(group, flags);
488*ec779b8eSAndroid Build Coastguard Worker     }
489*ec779b8eSAndroid Build Coastguard Worker }
490*ec779b8eSAndroid Build Coastguard Worker 
onDynamicPolicyMixStateUpdate(const String8 & regId,int32_t state)491*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
492*ec779b8eSAndroid Build Coastguard Worker {
493*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
494*ec779b8eSAndroid Build Coastguard Worker             regId.c_str(), state);
495*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
496*ec779b8eSAndroid Build Coastguard Worker }
497*ec779b8eSAndroid Build Coastguard Worker 
doOnDynamicPolicyMixStateUpdate(const String8 & regId,int32_t state)498*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
499*ec779b8eSAndroid Build Coastguard Worker {
500*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
501*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
502*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
503*ec779b8eSAndroid Build Coastguard Worker     }
504*ec779b8eSAndroid Build Coastguard Worker }
505*ec779b8eSAndroid Build Coastguard Worker 
onRecordingConfigurationUpdate(int event,const record_client_info_t * clientInfo,const audio_config_base_t * clientConfig,std::vector<effect_descriptor_t> clientEffects,const audio_config_base_t * deviceConfig,std::vector<effect_descriptor_t> effects,audio_patch_handle_t patchHandle,audio_source_t source)506*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onRecordingConfigurationUpdate(
507*ec779b8eSAndroid Build Coastguard Worker                                                     int event,
508*ec779b8eSAndroid Build Coastguard Worker                                                     const record_client_info_t *clientInfo,
509*ec779b8eSAndroid Build Coastguard Worker                                                     const audio_config_base_t *clientConfig,
510*ec779b8eSAndroid Build Coastguard Worker                                                     std::vector<effect_descriptor_t> clientEffects,
511*ec779b8eSAndroid Build Coastguard Worker                                                     const audio_config_base_t *deviceConfig,
512*ec779b8eSAndroid Build Coastguard Worker                                                     std::vector<effect_descriptor_t> effects,
513*ec779b8eSAndroid Build Coastguard Worker                                                     audio_patch_handle_t patchHandle,
514*ec779b8eSAndroid Build Coastguard Worker                                                     audio_source_t source)
515*ec779b8eSAndroid Build Coastguard Worker {
516*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
517*ec779b8eSAndroid Build Coastguard Worker             clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
518*ec779b8eSAndroid Build Coastguard Worker }
519*ec779b8eSAndroid Build Coastguard Worker 
doOnRecordingConfigurationUpdate(int event,const record_client_info_t * clientInfo,const audio_config_base_t * clientConfig,std::vector<effect_descriptor_t> clientEffects,const audio_config_base_t * deviceConfig,std::vector<effect_descriptor_t> effects,audio_patch_handle_t patchHandle,audio_source_t source)520*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnRecordingConfigurationUpdate(
521*ec779b8eSAndroid Build Coastguard Worker                                                   int event,
522*ec779b8eSAndroid Build Coastguard Worker                                                   const record_client_info_t *clientInfo,
523*ec779b8eSAndroid Build Coastguard Worker                                                   const audio_config_base_t *clientConfig,
524*ec779b8eSAndroid Build Coastguard Worker                                                   std::vector<effect_descriptor_t> clientEffects,
525*ec779b8eSAndroid Build Coastguard Worker                                                   const audio_config_base_t *deviceConfig,
526*ec779b8eSAndroid Build Coastguard Worker                                                   std::vector<effect_descriptor_t> effects,
527*ec779b8eSAndroid Build Coastguard Worker                                                   audio_patch_handle_t patchHandle,
528*ec779b8eSAndroid Build Coastguard Worker                                                   audio_source_t source)
529*ec779b8eSAndroid Build Coastguard Worker {
530*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
531*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
532*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
533*ec779b8eSAndroid Build Coastguard Worker                 clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
534*ec779b8eSAndroid Build Coastguard Worker     }
535*ec779b8eSAndroid Build Coastguard Worker }
536*ec779b8eSAndroid Build Coastguard Worker 
onRoutingUpdated()537*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onRoutingUpdated()
538*ec779b8eSAndroid Build Coastguard Worker {
539*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->routingChangedCommand();
540*ec779b8eSAndroid Build Coastguard Worker }
541*ec779b8eSAndroid Build Coastguard Worker 
doOnRoutingUpdated()542*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnRoutingUpdated()
543*ec779b8eSAndroid Build Coastguard Worker {
544*ec779b8eSAndroid Build Coastguard Worker   audio_utils::lock_guard _l(mNotificationClientsMutex);
545*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
546*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onRoutingUpdated();
547*ec779b8eSAndroid Build Coastguard Worker     }
548*ec779b8eSAndroid Build Coastguard Worker }
549*ec779b8eSAndroid Build Coastguard Worker 
onVolumeRangeInitRequest()550*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onVolumeRangeInitRequest()
551*ec779b8eSAndroid Build Coastguard Worker {
552*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->volRangeInitReqCommand();
553*ec779b8eSAndroid Build Coastguard Worker }
554*ec779b8eSAndroid Build Coastguard Worker 
doOnVolumeRangeInitRequest()555*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnVolumeRangeInitRequest()
556*ec779b8eSAndroid Build Coastguard Worker {
557*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mNotificationClientsMutex);
558*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mNotificationClients.size(); i++) {
559*ec779b8eSAndroid Build Coastguard Worker         mNotificationClients.valueAt(i)->onVolumeRangeInitRequest();
560*ec779b8eSAndroid Build Coastguard Worker     }
561*ec779b8eSAndroid Build Coastguard Worker }
562*ec779b8eSAndroid Build Coastguard Worker 
onCheckSpatializer()563*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onCheckSpatializer()
564*ec779b8eSAndroid Build Coastguard Worker {
565*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mMutex);
566*ec779b8eSAndroid Build Coastguard Worker     onCheckSpatializer_l();
567*ec779b8eSAndroid Build Coastguard Worker }
568*ec779b8eSAndroid Build Coastguard Worker 
onCheckSpatializer_l()569*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onCheckSpatializer_l()
570*ec779b8eSAndroid Build Coastguard Worker {
571*ec779b8eSAndroid Build Coastguard Worker     if (mSpatializer != nullptr) {
572*ec779b8eSAndroid Build Coastguard Worker         mOutputCommandThread->checkSpatializerCommand();
573*ec779b8eSAndroid Build Coastguard Worker     }
574*ec779b8eSAndroid Build Coastguard Worker }
575*ec779b8eSAndroid Build Coastguard Worker 
doOnCheckSpatializer()576*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnCheckSpatializer()
577*ec779b8eSAndroid Build Coastguard Worker {
578*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s mSpatializer %p level %d",
579*ec779b8eSAndroid Build Coastguard Worker         __func__, mSpatializer.get(), (int)mSpatializer->getLevel());
580*ec779b8eSAndroid Build Coastguard Worker 
581*ec779b8eSAndroid Build Coastguard Worker     if (mSpatializer != nullptr) {
582*ec779b8eSAndroid Build Coastguard Worker         // Note: mSpatializer != nullptr =>  mAudioPolicyManager != nullptr
583*ec779b8eSAndroid Build Coastguard Worker         if (mSpatializer->getLevel() != Spatialization::Level::NONE) {
584*ec779b8eSAndroid Build Coastguard Worker             audio_io_handle_t currentOutput = mSpatializer->getOutput();
585*ec779b8eSAndroid Build Coastguard Worker             audio_io_handle_t newOutput;
586*ec779b8eSAndroid Build Coastguard Worker             const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
587*ec779b8eSAndroid Build Coastguard Worker             audio_config_base_t config = mSpatializer->getAudioInConfig();
588*ec779b8eSAndroid Build Coastguard Worker 
589*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _l(mMutex);
590*ec779b8eSAndroid Build Coastguard Worker             status_t status =
591*ec779b8eSAndroid Build Coastguard Worker                     mAudioPolicyManager->getSpatializerOutput(&config, &attr, &newOutput);
592*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s currentOutput %d newOutput %d channel_mask %#x",
593*ec779b8eSAndroid Build Coastguard Worker                     __func__, currentOutput, newOutput, config.channel_mask);
594*ec779b8eSAndroid Build Coastguard Worker             if (status == NO_ERROR && currentOutput == newOutput) {
595*ec779b8eSAndroid Build Coastguard Worker                 return;
596*ec779b8eSAndroid Build Coastguard Worker             }
597*ec779b8eSAndroid Build Coastguard Worker             std::vector<audio_channel_mask_t> activeTracksMasks =
598*ec779b8eSAndroid Build Coastguard Worker                     getActiveTracksMasks_l(newOutput);
599*ec779b8eSAndroid Build Coastguard Worker             mMutex.unlock();
600*ec779b8eSAndroid Build Coastguard Worker             // It is OK to call detachOutput() is none is already attached.
601*ec779b8eSAndroid Build Coastguard Worker             mSpatializer->detachOutput();
602*ec779b8eSAndroid Build Coastguard Worker             if (status == NO_ERROR && newOutput != AUDIO_IO_HANDLE_NONE) {
603*ec779b8eSAndroid Build Coastguard Worker                 status = mSpatializer->attachOutput(newOutput, activeTracksMasks);
604*ec779b8eSAndroid Build Coastguard Worker             }
605*ec779b8eSAndroid Build Coastguard Worker             mMutex.lock();
606*ec779b8eSAndroid Build Coastguard Worker             if (status != NO_ERROR) {
607*ec779b8eSAndroid Build Coastguard Worker                 mAudioPolicyManager->releaseSpatializerOutput(newOutput);
608*ec779b8eSAndroid Build Coastguard Worker             }
609*ec779b8eSAndroid Build Coastguard Worker         } else if (mSpatializer->getLevel() == Spatialization::Level::NONE &&
610*ec779b8eSAndroid Build Coastguard Worker                    mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
611*ec779b8eSAndroid Build Coastguard Worker             audio_io_handle_t output = mSpatializer->detachOutput();
612*ec779b8eSAndroid Build Coastguard Worker 
613*ec779b8eSAndroid Build Coastguard Worker             if (output != AUDIO_IO_HANDLE_NONE) {
614*ec779b8eSAndroid Build Coastguard Worker                 audio_utils::lock_guard _l(mMutex);
615*ec779b8eSAndroid Build Coastguard Worker                 mAudioPolicyManager->releaseSpatializerOutput(output);
616*ec779b8eSAndroid Build Coastguard Worker             }
617*ec779b8eSAndroid Build Coastguard Worker         }
618*ec779b8eSAndroid Build Coastguard Worker     }
619*ec779b8eSAndroid Build Coastguard Worker }
620*ec779b8eSAndroid Build Coastguard Worker 
getActiveTracksMasks_l(audio_io_handle_t output,bool spatializedOnly)621*ec779b8eSAndroid Build Coastguard Worker std::vector<audio_channel_mask_t> AudioPolicyService::getActiveTracksMasks_l(
622*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output, bool spatializedOnly) {
623*ec779b8eSAndroid Build Coastguard Worker     std::vector<audio_channel_mask_t> activeTrackMasks;
624*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioPlaybackClients.size(); i++) {
625*ec779b8eSAndroid Build Coastguard Worker         auto client = mAudioPlaybackClients.valueAt(i);
626*ec779b8eSAndroid Build Coastguard Worker         if (client->io == output && client->active
627*ec779b8eSAndroid Build Coastguard Worker                 && (!spatializedOnly || client->isSpatialized)) {
628*ec779b8eSAndroid Build Coastguard Worker             activeTrackMasks.push_back(client->channelMask);
629*ec779b8eSAndroid Build Coastguard Worker         }
630*ec779b8eSAndroid Build Coastguard Worker     }
631*ec779b8eSAndroid Build Coastguard Worker     return activeTrackMasks;
632*ec779b8eSAndroid Build Coastguard Worker }
633*ec779b8eSAndroid Build Coastguard Worker 
onUpdateActiveSpatializerTracks_l()634*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::onUpdateActiveSpatializerTracks_l() {
635*ec779b8eSAndroid Build Coastguard Worker     if (mSpatializer == nullptr) {
636*ec779b8eSAndroid Build Coastguard Worker         return;
637*ec779b8eSAndroid Build Coastguard Worker     }
638*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->updateActiveSpatializerTracksCommand();
639*ec779b8eSAndroid Build Coastguard Worker }
640*ec779b8eSAndroid Build Coastguard Worker 
doOnUpdateActiveSpatializerTracks()641*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::doOnUpdateActiveSpatializerTracks()
642*ec779b8eSAndroid Build Coastguard Worker {
643*ec779b8eSAndroid Build Coastguard Worker     if (mSpatializer == nullptr) {
644*ec779b8eSAndroid Build Coastguard Worker         return;
645*ec779b8eSAndroid Build Coastguard Worker     }
646*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t output = mSpatializer->getOutput();
647*ec779b8eSAndroid Build Coastguard Worker     std::vector<audio_channel_mask_t> activeTracksMasks;
648*ec779b8eSAndroid Build Coastguard Worker     {
649*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
650*ec779b8eSAndroid Build Coastguard Worker         activeTracksMasks = getActiveTracksMasks_l(output);
651*ec779b8eSAndroid Build Coastguard Worker     }
652*ec779b8eSAndroid Build Coastguard Worker     mSpatializer->updateActiveTracks(activeTracksMasks);
653*ec779b8eSAndroid Build Coastguard Worker }
654*ec779b8eSAndroid Build Coastguard Worker 
clientCreateAudioPatch(const struct audio_patch * patch,audio_patch_handle_t * handle,int delayMs)655*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
656*ec779b8eSAndroid Build Coastguard Worker                                                 audio_patch_handle_t *handle,
657*ec779b8eSAndroid Build Coastguard Worker                                                 int delayMs)
658*ec779b8eSAndroid Build Coastguard Worker {
659*ec779b8eSAndroid Build Coastguard Worker     return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
660*ec779b8eSAndroid Build Coastguard Worker }
661*ec779b8eSAndroid Build Coastguard Worker 
clientReleaseAudioPatch(audio_patch_handle_t handle,int delayMs)662*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
663*ec779b8eSAndroid Build Coastguard Worker                                                  int delayMs)
664*ec779b8eSAndroid Build Coastguard Worker {
665*ec779b8eSAndroid Build Coastguard Worker     return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
666*ec779b8eSAndroid Build Coastguard Worker }
667*ec779b8eSAndroid Build Coastguard Worker 
clientSetAudioPortConfig(const struct audio_port_config * config,int delayMs)668*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
669*ec779b8eSAndroid Build Coastguard Worker                                                       int delayMs)
670*ec779b8eSAndroid Build Coastguard Worker {
671*ec779b8eSAndroid Build Coastguard Worker     return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
672*ec779b8eSAndroid Build Coastguard Worker }
673*ec779b8eSAndroid Build Coastguard Worker 
NotificationClient(const sp<AudioPolicyService> & service,const sp<media::IAudioPolicyServiceClient> & client,uid_t uid,pid_t pid)674*ec779b8eSAndroid Build Coastguard Worker AudioPolicyService::NotificationClient::NotificationClient(
675*ec779b8eSAndroid Build Coastguard Worker         const sp<AudioPolicyService>& service,
676*ec779b8eSAndroid Build Coastguard Worker         const sp<media::IAudioPolicyServiceClient>& client,
677*ec779b8eSAndroid Build Coastguard Worker         uid_t uid,
678*ec779b8eSAndroid Build Coastguard Worker         pid_t pid)
679*ec779b8eSAndroid Build Coastguard Worker     : mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
680*ec779b8eSAndroid Build Coastguard Worker       mAudioPortCallbacksEnabled(false), mAudioVolumeGroupCallbacksEnabled(false)
681*ec779b8eSAndroid Build Coastguard Worker {
682*ec779b8eSAndroid Build Coastguard Worker }
683*ec779b8eSAndroid Build Coastguard Worker 
~NotificationClient()684*ec779b8eSAndroid Build Coastguard Worker AudioPolicyService::NotificationClient::~NotificationClient()
685*ec779b8eSAndroid Build Coastguard Worker {
686*ec779b8eSAndroid Build Coastguard Worker }
687*ec779b8eSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> & who __unused)688*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
689*ec779b8eSAndroid Build Coastguard Worker {
690*ec779b8eSAndroid Build Coastguard Worker     sp<NotificationClient> keep(this);
691*ec779b8eSAndroid Build Coastguard Worker     sp<AudioPolicyService> service = mService.promote();
692*ec779b8eSAndroid Build Coastguard Worker     if (service != 0) {
693*ec779b8eSAndroid Build Coastguard Worker         service->removeNotificationClient(mUid, mPid);
694*ec779b8eSAndroid Build Coastguard Worker     }
695*ec779b8eSAndroid Build Coastguard Worker }
696*ec779b8eSAndroid Build Coastguard Worker 
onAudioPortListUpdate()697*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
698*ec779b8eSAndroid Build Coastguard Worker {
699*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
700*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyServiceClient->onAudioPortListUpdate();
701*ec779b8eSAndroid Build Coastguard Worker     }
702*ec779b8eSAndroid Build Coastguard Worker }
703*ec779b8eSAndroid Build Coastguard Worker 
onAudioPatchListUpdate()704*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
705*ec779b8eSAndroid Build Coastguard Worker {
706*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
707*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyServiceClient->onAudioPatchListUpdate();
708*ec779b8eSAndroid Build Coastguard Worker     }
709*ec779b8eSAndroid Build Coastguard Worker }
710*ec779b8eSAndroid Build Coastguard Worker 
onAudioVolumeGroupChanged(volume_group_t group,int flags)711*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
712*ec779b8eSAndroid Build Coastguard Worker                                                                       int flags)
713*ec779b8eSAndroid Build Coastguard Worker {
714*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
715*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyServiceClient->onAudioVolumeGroupChanged(group, flags);
716*ec779b8eSAndroid Build Coastguard Worker     }
717*ec779b8eSAndroid Build Coastguard Worker }
718*ec779b8eSAndroid Build Coastguard Worker 
719*ec779b8eSAndroid Build Coastguard Worker 
onDynamicPolicyMixStateUpdate(const String8 & regId,int32_t state)720*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
721*ec779b8eSAndroid Build Coastguard Worker         const String8& regId, int32_t state)
722*ec779b8eSAndroid Build Coastguard Worker {
723*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
724*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(
725*ec779b8eSAndroid Build Coastguard Worker                 legacy2aidl_String8_string(regId).value(), state);
726*ec779b8eSAndroid Build Coastguard Worker     }
727*ec779b8eSAndroid Build Coastguard Worker }
728*ec779b8eSAndroid Build Coastguard Worker 
onRecordingConfigurationUpdate(int event,const record_client_info_t * clientInfo,const audio_config_base_t * clientConfig,std::vector<effect_descriptor_t> clientEffects,const audio_config_base_t * deviceConfig,std::vector<effect_descriptor_t> effects,audio_patch_handle_t patchHandle,audio_source_t source)729*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
730*ec779b8eSAndroid Build Coastguard Worker                                             int event,
731*ec779b8eSAndroid Build Coastguard Worker                                             const record_client_info_t *clientInfo,
732*ec779b8eSAndroid Build Coastguard Worker                                             const audio_config_base_t *clientConfig,
733*ec779b8eSAndroid Build Coastguard Worker                                             std::vector<effect_descriptor_t> clientEffects,
734*ec779b8eSAndroid Build Coastguard Worker                                             const audio_config_base_t *deviceConfig,
735*ec779b8eSAndroid Build Coastguard Worker                                             std::vector<effect_descriptor_t> effects,
736*ec779b8eSAndroid Build Coastguard Worker                                             audio_patch_handle_t patchHandle,
737*ec779b8eSAndroid Build Coastguard Worker                                             audio_source_t source)
738*ec779b8eSAndroid Build Coastguard Worker {
739*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
740*ec779b8eSAndroid Build Coastguard Worker         status_t status = [&]() -> status_t {
741*ec779b8eSAndroid Build Coastguard Worker             int32_t eventAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(event));
742*ec779b8eSAndroid Build Coastguard Worker             media::RecordClientInfo clientInfoAidl = VALUE_OR_RETURN_STATUS(
743*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_record_client_info_t_RecordClientInfo(*clientInfo));
744*ec779b8eSAndroid Build Coastguard Worker             AudioConfigBase clientConfigAidl = VALUE_OR_RETURN_STATUS(
745*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_audio_config_base_t_AudioConfigBase(
746*ec779b8eSAndroid Build Coastguard Worker                             *clientConfig, true /*isInput*/));
747*ec779b8eSAndroid Build Coastguard Worker             std::vector<media::EffectDescriptor> clientEffectsAidl = VALUE_OR_RETURN_STATUS(
748*ec779b8eSAndroid Build Coastguard Worker                     convertContainer<std::vector<media::EffectDescriptor>>(
749*ec779b8eSAndroid Build Coastguard Worker                             clientEffects,
750*ec779b8eSAndroid Build Coastguard Worker                             legacy2aidl_effect_descriptor_t_EffectDescriptor));
751*ec779b8eSAndroid Build Coastguard Worker             AudioConfigBase deviceConfigAidl = VALUE_OR_RETURN_STATUS(
752*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_audio_config_base_t_AudioConfigBase(
753*ec779b8eSAndroid Build Coastguard Worker                             *deviceConfig, true /*isInput*/));
754*ec779b8eSAndroid Build Coastguard Worker             std::vector<media::EffectDescriptor> effectsAidl = VALUE_OR_RETURN_STATUS(
755*ec779b8eSAndroid Build Coastguard Worker                     convertContainer<std::vector<media::EffectDescriptor>>(
756*ec779b8eSAndroid Build Coastguard Worker                             effects,
757*ec779b8eSAndroid Build Coastguard Worker                             legacy2aidl_effect_descriptor_t_EffectDescriptor));
758*ec779b8eSAndroid Build Coastguard Worker             int32_t patchHandleAidl = VALUE_OR_RETURN_STATUS(
759*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_audio_patch_handle_t_int32_t(patchHandle));
760*ec779b8eSAndroid Build Coastguard Worker             media::audio::common::AudioSource sourceAidl = VALUE_OR_RETURN_STATUS(
761*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_audio_source_t_AudioSource(source));
762*ec779b8eSAndroid Build Coastguard Worker             return aidl_utils::statusTFromBinderStatus(
763*ec779b8eSAndroid Build Coastguard Worker                     mAudioPolicyServiceClient->onRecordingConfigurationUpdate(eventAidl,
764*ec779b8eSAndroid Build Coastguard Worker                                                                               clientInfoAidl,
765*ec779b8eSAndroid Build Coastguard Worker                                                                               clientConfigAidl,
766*ec779b8eSAndroid Build Coastguard Worker                                                                               clientEffectsAidl,
767*ec779b8eSAndroid Build Coastguard Worker                                                                               deviceConfigAidl,
768*ec779b8eSAndroid Build Coastguard Worker                                                                               effectsAidl,
769*ec779b8eSAndroid Build Coastguard Worker                                                                               patchHandleAidl,
770*ec779b8eSAndroid Build Coastguard Worker                                                                               sourceAidl));
771*ec779b8eSAndroid Build Coastguard Worker         }();
772*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(status != OK, "onRecordingConfigurationUpdate() failed: %d", status);
773*ec779b8eSAndroid Build Coastguard Worker     }
774*ec779b8eSAndroid Build Coastguard Worker }
775*ec779b8eSAndroid Build Coastguard Worker 
setAudioPortCallbacksEnabled(bool enabled)776*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
777*ec779b8eSAndroid Build Coastguard Worker {
778*ec779b8eSAndroid Build Coastguard Worker     mAudioPortCallbacksEnabled = enabled;
779*ec779b8eSAndroid Build Coastguard Worker }
780*ec779b8eSAndroid Build Coastguard Worker 
setAudioVolumeGroupCallbacksEnabled(bool enabled)781*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::setAudioVolumeGroupCallbacksEnabled(bool enabled)
782*ec779b8eSAndroid Build Coastguard Worker {
783*ec779b8eSAndroid Build Coastguard Worker     mAudioVolumeGroupCallbacksEnabled = enabled;
784*ec779b8eSAndroid Build Coastguard Worker }
785*ec779b8eSAndroid Build Coastguard Worker 
onRoutingUpdated()786*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onRoutingUpdated()
787*ec779b8eSAndroid Build Coastguard Worker {
788*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
789*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyServiceClient->onRoutingUpdated();
790*ec779b8eSAndroid Build Coastguard Worker     }
791*ec779b8eSAndroid Build Coastguard Worker }
792*ec779b8eSAndroid Build Coastguard Worker 
onVolumeRangeInitRequest()793*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::NotificationClient::onVolumeRangeInitRequest()
794*ec779b8eSAndroid Build Coastguard Worker {
795*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
796*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyServiceClient->onVolumeRangeInitRequest();
797*ec779b8eSAndroid Build Coastguard Worker     }
798*ec779b8eSAndroid Build Coastguard Worker }
799*ec779b8eSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> & who)800*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::binderDied(const wp<IBinder>& who) {
801*ec779b8eSAndroid Build Coastguard Worker     ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
802*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingPid());
803*ec779b8eSAndroid Build Coastguard Worker }
804*ec779b8eSAndroid Build Coastguard Worker 
dumpReleaseLock(audio_utils::mutex & mutex,bool locked)805*ec779b8eSAndroid Build Coastguard Worker static void dumpReleaseLock(audio_utils::mutex& mutex, bool locked)
806*ec779b8eSAndroid Build Coastguard Worker         RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
807*ec779b8eSAndroid Build Coastguard Worker {
808*ec779b8eSAndroid Build Coastguard Worker     if (locked) mutex.unlock();
809*ec779b8eSAndroid Build Coastguard Worker }
810*ec779b8eSAndroid Build Coastguard Worker 
dumpInternals(int fd)811*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::dumpInternals(int fd)
812*ec779b8eSAndroid Build Coastguard Worker {
813*ec779b8eSAndroid Build Coastguard Worker     const size_t SIZE = 256;
814*ec779b8eSAndroid Build Coastguard Worker     char buffer[SIZE];
815*ec779b8eSAndroid Build Coastguard Worker     String8 result;
816*ec779b8eSAndroid Build Coastguard Worker 
817*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "Supported System Usages:\n  ");
818*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
819*ec779b8eSAndroid Build Coastguard Worker     std::stringstream msg;
820*ec779b8eSAndroid Build Coastguard Worker     size_t i = 0;
821*ec779b8eSAndroid Build Coastguard Worker     for (auto usage : mSupportedSystemUsages) {
822*ec779b8eSAndroid Build Coastguard Worker         if (i++ != 0) msg << ", ";
823*ec779b8eSAndroid Build Coastguard Worker         if (const char* strUsage = audio_usage_to_string(usage); strUsage) {
824*ec779b8eSAndroid Build Coastguard Worker             msg << strUsage;
825*ec779b8eSAndroid Build Coastguard Worker         } else {
826*ec779b8eSAndroid Build Coastguard Worker             msg << usage << " (unknown)";
827*ec779b8eSAndroid Build Coastguard Worker         }
828*ec779b8eSAndroid Build Coastguard Worker     }
829*ec779b8eSAndroid Build Coastguard Worker     if (i == 0) {
830*ec779b8eSAndroid Build Coastguard Worker         msg << "None";
831*ec779b8eSAndroid Build Coastguard Worker     }
832*ec779b8eSAndroid Build Coastguard Worker     msg << std::endl;
833*ec779b8eSAndroid Build Coastguard Worker     result.append(msg.str().c_str());
834*ec779b8eSAndroid Build Coastguard Worker 
835*ec779b8eSAndroid Build Coastguard Worker     write(fd, result.c_str(), result.size());
836*ec779b8eSAndroid Build Coastguard Worker 
837*ec779b8eSAndroid Build Coastguard Worker     mUidPolicy->dumpInternals(fd);
838*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
839*ec779b8eSAndroid Build Coastguard Worker }
840*ec779b8eSAndroid Build Coastguard Worker 
updateUidStates()841*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::updateUidStates()
842*ec779b8eSAndroid Build Coastguard Worker {
843*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mMutex);
844*ec779b8eSAndroid Build Coastguard Worker     updateUidStates_l();
845*ec779b8eSAndroid Build Coastguard Worker }
846*ec779b8eSAndroid Build Coastguard Worker 
updateUidStates_l()847*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::updateUidStates_l()
848*ec779b8eSAndroid Build Coastguard Worker {
849*ec779b8eSAndroid Build Coastguard Worker //    Go over all active clients and allow capture (does not force silence) in the
850*ec779b8eSAndroid Build Coastguard Worker //    following cases:
851*ec779b8eSAndroid Build Coastguard Worker //    The client is in the active assistant list
852*ec779b8eSAndroid Build Coastguard Worker //         AND is TOP
853*ec779b8eSAndroid Build Coastguard Worker //               AND an accessibility service is TOP
854*ec779b8eSAndroid Build Coastguard Worker //                  AND source is either VOICE_RECOGNITION OR HOTWORD
855*ec779b8eSAndroid Build Coastguard Worker //               OR there is no active privacy sensitive capture or call
856*ec779b8eSAndroid Build Coastguard Worker //                          OR client can capture calls
857*ec779b8eSAndroid Build Coastguard Worker //                  AND source is VOICE_RECOGNITION OR HOTWORD
858*ec779b8eSAndroid Build Coastguard Worker //    The client is an assistant AND active assistant is not being used
859*ec779b8eSAndroid Build Coastguard Worker //        AND an accessibility service is on TOP or a RTT call is active
860*ec779b8eSAndroid Build Coastguard Worker //                AND the source is VOICE_RECOGNITION or HOTWORD
861*ec779b8eSAndroid Build Coastguard Worker //        OR there is no active privacy sensitive capture or call
862*ec779b8eSAndroid Build Coastguard Worker //                OR client can capture calls
863*ec779b8eSAndroid Build Coastguard Worker //            AND is TOP most recent assistant and uses VOICE_RECOGNITION or HOTWORD
864*ec779b8eSAndroid Build Coastguard Worker //                OR there is no top recent assistant and source is HOTWORD
865*ec779b8eSAndroid Build Coastguard Worker //    OR The client is an accessibility service
866*ec779b8eSAndroid Build Coastguard Worker //        AND Is on TOP
867*ec779b8eSAndroid Build Coastguard Worker //                AND the source is VOICE_RECOGNITION or HOTWORD
868*ec779b8eSAndroid Build Coastguard Worker //            OR The assistant is not on TOP
869*ec779b8eSAndroid Build Coastguard Worker //                AND there is no active privacy sensitive capture or call
870*ec779b8eSAndroid Build Coastguard Worker //                    OR client can capture calls
871*ec779b8eSAndroid Build Coastguard Worker //        AND is on TOP
872*ec779b8eSAndroid Build Coastguard Worker //        AND the source is VOICE_RECOGNITION or HOTWORD
873*ec779b8eSAndroid Build Coastguard Worker //    OR the client source is virtual (remote submix, call audio TX or RX...)
874*ec779b8eSAndroid Build Coastguard Worker //    OR the client source is HOTWORD
875*ec779b8eSAndroid Build Coastguard Worker //        AND is on TOP
876*ec779b8eSAndroid Build Coastguard Worker //            OR all active clients are using HOTWORD source
877*ec779b8eSAndroid Build Coastguard Worker //        AND no call is active
878*ec779b8eSAndroid Build Coastguard Worker //            OR client can capture calls
879*ec779b8eSAndroid Build Coastguard Worker //    OR the client is the current InputMethodService
880*ec779b8eSAndroid Build Coastguard Worker //        AND a RTT call is active AND the source is VOICE_RECOGNITION
881*ec779b8eSAndroid Build Coastguard Worker //    OR The client is an active communication owner
882*ec779b8eSAndroid Build Coastguard Worker //        AND is on TOP or latest started
883*ec779b8eSAndroid Build Coastguard Worker //    OR Any client
884*ec779b8eSAndroid Build Coastguard Worker //        AND The assistant is not on TOP
885*ec779b8eSAndroid Build Coastguard Worker //        AND is on TOP or latest started
886*ec779b8eSAndroid Build Coastguard Worker //        AND there is no active privacy sensitive capture or call
887*ec779b8eSAndroid Build Coastguard Worker //            OR client can capture calls
888*ec779b8eSAndroid Build Coastguard Worker //    NOTE: a client can capture calls if it either:
889*ec779b8eSAndroid Build Coastguard Worker //       has CAPTURE_AUDIO_OUTPUT privileged permission (temporarily until
890*ec779b8eSAndroid Build Coastguard Worker //            all system apps are updated)
891*ec779b8eSAndroid Build Coastguard Worker //       or has CONCURRENT_AUDIO_RECORD_BYPASS privileged permission
892*ec779b8eSAndroid Build Coastguard Worker 
893*ec779b8eSAndroid Build Coastguard Worker 
894*ec779b8eSAndroid Build Coastguard Worker     sp<AudioRecordClient> topActive;
895*ec779b8eSAndroid Build Coastguard Worker     sp<AudioRecordClient> latestActive;
896*ec779b8eSAndroid Build Coastguard Worker     sp<AudioRecordClient> topSensitiveActive;
897*ec779b8eSAndroid Build Coastguard Worker     sp<AudioRecordClient> latestSensitiveActiveOrComm;
898*ec779b8eSAndroid Build Coastguard Worker     sp<AudioRecordClient> latestActiveAssistant;
899*ec779b8eSAndroid Build Coastguard Worker 
900*ec779b8eSAndroid Build Coastguard Worker     nsecs_t topStartNs = 0;
901*ec779b8eSAndroid Build Coastguard Worker     nsecs_t latestStartNs = 0;
902*ec779b8eSAndroid Build Coastguard Worker     nsecs_t topSensitiveStartNs = 0;
903*ec779b8eSAndroid Build Coastguard Worker     nsecs_t latestSensitiveStartNs = 0;
904*ec779b8eSAndroid Build Coastguard Worker     nsecs_t latestAssistantStartNs = 0;
905*ec779b8eSAndroid Build Coastguard Worker     bool isA11yOnTop = mUidPolicy->isA11yOnTop();
906*ec779b8eSAndroid Build Coastguard Worker     bool isAssistantOnTop = false;
907*ec779b8eSAndroid Build Coastguard Worker     bool useActiveAssistantList = false;
908*ec779b8eSAndroid Build Coastguard Worker     bool isSensitiveActive = false;
909*ec779b8eSAndroid Build Coastguard Worker     bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
910*ec779b8eSAndroid Build Coastguard Worker     bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION;
911*ec779b8eSAndroid Build Coastguard Worker     bool rttCallActive = (isInCall || isInCommunication)
912*ec779b8eSAndroid Build Coastguard Worker             && mUidPolicy->isRttEnabled();
913*ec779b8eSAndroid Build Coastguard Worker     bool onlyHotwordActive = true;
914*ec779b8eSAndroid Build Coastguard Worker     bool isPhoneStateOwnerActive = false;
915*ec779b8eSAndroid Build Coastguard Worker 
916*ec779b8eSAndroid Build Coastguard Worker     // if Sensor Privacy is enabled then all recordings should be silenced.
917*ec779b8eSAndroid Build Coastguard Worker     if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
918*ec779b8eSAndroid Build Coastguard Worker         silenceAllRecordings_l();
919*ec779b8eSAndroid Build Coastguard Worker         return;
920*ec779b8eSAndroid Build Coastguard Worker     }
921*ec779b8eSAndroid Build Coastguard Worker 
922*ec779b8eSAndroid Build Coastguard Worker     for (size_t i =0; i < mAudioRecordClients.size(); i++) {
923*ec779b8eSAndroid Build Coastguard Worker         sp<AudioRecordClient> current = mAudioRecordClients[i];
924*ec779b8eSAndroid Build Coastguard Worker         uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
925*ec779b8eSAndroid Build Coastguard Worker                 current->attributionSource.uid));
926*ec779b8eSAndroid Build Coastguard Worker         if (!current->active) {
927*ec779b8eSAndroid Build Coastguard Worker             continue;
928*ec779b8eSAndroid Build Coastguard Worker         }
929*ec779b8eSAndroid Build Coastguard Worker 
930*ec779b8eSAndroid Build Coastguard Worker         app_state_t appState = apmStatFromAmState(mUidPolicy->getUidState(currentUid));
931*ec779b8eSAndroid Build Coastguard Worker         // clients which app is in IDLE state are not eligible for top active or
932*ec779b8eSAndroid Build Coastguard Worker         // latest active
933*ec779b8eSAndroid Build Coastguard Worker         if (appState == APP_STATE_IDLE) {
934*ec779b8eSAndroid Build Coastguard Worker             continue;
935*ec779b8eSAndroid Build Coastguard Worker         }
936*ec779b8eSAndroid Build Coastguard Worker 
937*ec779b8eSAndroid Build Coastguard Worker         bool isAccessibility = mUidPolicy->isA11yUid(currentUid);
938*ec779b8eSAndroid Build Coastguard Worker         // Clients capturing for Accessibility services or virtual sources are not considered
939*ec779b8eSAndroid Build Coastguard Worker         // for top or latest active to avoid masking regular clients started before
940*ec779b8eSAndroid Build Coastguard Worker         if (!isAccessibility && !isVirtualSource(current->attributes.source)) {
941*ec779b8eSAndroid Build Coastguard Worker             bool isAssistant = mUidPolicy->isAssistantUid(currentUid);
942*ec779b8eSAndroid Build Coastguard Worker             bool isActiveAssistant = mUidPolicy->isActiveAssistantUid(currentUid);
943*ec779b8eSAndroid Build Coastguard Worker             bool isPrivacySensitive =
944*ec779b8eSAndroid Build Coastguard Worker                     (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0;
945*ec779b8eSAndroid Build Coastguard Worker 
946*ec779b8eSAndroid Build Coastguard Worker             if (appState == APP_STATE_TOP) {
947*ec779b8eSAndroid Build Coastguard Worker                 if (isPrivacySensitive) {
948*ec779b8eSAndroid Build Coastguard Worker                     if (current->startTimeNs > topSensitiveStartNs) {
949*ec779b8eSAndroid Build Coastguard Worker                         topSensitiveActive = current;
950*ec779b8eSAndroid Build Coastguard Worker                         topSensitiveStartNs = current->startTimeNs;
951*ec779b8eSAndroid Build Coastguard Worker                     }
952*ec779b8eSAndroid Build Coastguard Worker                 } else {
953*ec779b8eSAndroid Build Coastguard Worker                     if (current->startTimeNs > topStartNs) {
954*ec779b8eSAndroid Build Coastguard Worker                         topActive = current;
955*ec779b8eSAndroid Build Coastguard Worker                         topStartNs = current->startTimeNs;
956*ec779b8eSAndroid Build Coastguard Worker                     }
957*ec779b8eSAndroid Build Coastguard Worker                 }
958*ec779b8eSAndroid Build Coastguard Worker                 if (isAssistant) {
959*ec779b8eSAndroid Build Coastguard Worker                     isAssistantOnTop = true;
960*ec779b8eSAndroid Build Coastguard Worker                     if (isActiveAssistant) {
961*ec779b8eSAndroid Build Coastguard Worker                         useActiveAssistantList = true;
962*ec779b8eSAndroid Build Coastguard Worker                     } else if (!useActiveAssistantList) {
963*ec779b8eSAndroid Build Coastguard Worker                         if (current->startTimeNs > latestAssistantStartNs) {
964*ec779b8eSAndroid Build Coastguard Worker                             latestActiveAssistant = current;
965*ec779b8eSAndroid Build Coastguard Worker                             latestAssistantStartNs = current->startTimeNs;
966*ec779b8eSAndroid Build Coastguard Worker                         }
967*ec779b8eSAndroid Build Coastguard Worker                     }
968*ec779b8eSAndroid Build Coastguard Worker                 }
969*ec779b8eSAndroid Build Coastguard Worker             }
970*ec779b8eSAndroid Build Coastguard Worker             // Clients capturing for HOTWORD are not considered
971*ec779b8eSAndroid Build Coastguard Worker             // for latest active to avoid masking regular clients started before
972*ec779b8eSAndroid Build Coastguard Worker             if (!(current->attributes.source == AUDIO_SOURCE_HOTWORD
973*ec779b8eSAndroid Build Coastguard Worker                     || ((isA11yOnTop || rttCallActive) && isAssistant))) {
974*ec779b8eSAndroid Build Coastguard Worker                 if (isPrivacySensitive) {
975*ec779b8eSAndroid Build Coastguard Worker                     // if audio mode is IN_COMMUNICATION, make sure the audio mode owner
976*ec779b8eSAndroid Build Coastguard Worker                     // is marked latest sensitive active even if another app qualifies.
977*ec779b8eSAndroid Build Coastguard Worker                     if (current->startTimeNs > latestSensitiveStartNs
978*ec779b8eSAndroid Build Coastguard Worker                             || (isInCommunication && currentUid == mPhoneStateOwnerUid)) {
979*ec779b8eSAndroid Build Coastguard Worker                         if (!isInCommunication || latestSensitiveActiveOrComm == nullptr
980*ec779b8eSAndroid Build Coastguard Worker                                 || VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
981*ec779b8eSAndroid Build Coastguard Worker                                     latestSensitiveActiveOrComm->attributionSource.uid))
982*ec779b8eSAndroid Build Coastguard Worker                                         != mPhoneStateOwnerUid) {
983*ec779b8eSAndroid Build Coastguard Worker                             latestSensitiveActiveOrComm = current;
984*ec779b8eSAndroid Build Coastguard Worker                             latestSensitiveStartNs = current->startTimeNs;
985*ec779b8eSAndroid Build Coastguard Worker                         }
986*ec779b8eSAndroid Build Coastguard Worker                     }
987*ec779b8eSAndroid Build Coastguard Worker                     isSensitiveActive = true;
988*ec779b8eSAndroid Build Coastguard Worker                 } else {
989*ec779b8eSAndroid Build Coastguard Worker                     if (current->startTimeNs > latestStartNs) {
990*ec779b8eSAndroid Build Coastguard Worker                         latestActive = current;
991*ec779b8eSAndroid Build Coastguard Worker                         latestStartNs = current->startTimeNs;
992*ec779b8eSAndroid Build Coastguard Worker                     }
993*ec779b8eSAndroid Build Coastguard Worker                 }
994*ec779b8eSAndroid Build Coastguard Worker             }
995*ec779b8eSAndroid Build Coastguard Worker         }
996*ec779b8eSAndroid Build Coastguard Worker         if (current->attributes.source != AUDIO_SOURCE_HOTWORD &&
997*ec779b8eSAndroid Build Coastguard Worker                 !isVirtualSource(current->attributes.source)) {
998*ec779b8eSAndroid Build Coastguard Worker             onlyHotwordActive = false;
999*ec779b8eSAndroid Build Coastguard Worker         }
1000*ec779b8eSAndroid Build Coastguard Worker         if (currentUid == mPhoneStateOwnerUid &&
1001*ec779b8eSAndroid Build Coastguard Worker                 !isVirtualSource(current->attributes.source)) {
1002*ec779b8eSAndroid Build Coastguard Worker             isPhoneStateOwnerActive = true;
1003*ec779b8eSAndroid Build Coastguard Worker         }
1004*ec779b8eSAndroid Build Coastguard Worker     }
1005*ec779b8eSAndroid Build Coastguard Worker 
1006*ec779b8eSAndroid Build Coastguard Worker     // if no active client with UI on Top, consider latest active as top
1007*ec779b8eSAndroid Build Coastguard Worker     if (topActive == nullptr) {
1008*ec779b8eSAndroid Build Coastguard Worker         topActive = latestActive;
1009*ec779b8eSAndroid Build Coastguard Worker         topStartNs = latestStartNs;
1010*ec779b8eSAndroid Build Coastguard Worker     }
1011*ec779b8eSAndroid Build Coastguard Worker     if (topSensitiveActive == nullptr) {
1012*ec779b8eSAndroid Build Coastguard Worker         topSensitiveActive = latestSensitiveActiveOrComm;
1013*ec779b8eSAndroid Build Coastguard Worker         topSensitiveStartNs = latestSensitiveStartNs;
1014*ec779b8eSAndroid Build Coastguard Worker     } else if (latestSensitiveActiveOrComm != nullptr) {
1015*ec779b8eSAndroid Build Coastguard Worker         // if audio mode is IN_COMMUNICATION, favor audio mode owner over an app with
1016*ec779b8eSAndroid Build Coastguard Worker         // foreground UI in case both are capturing with privacy sensitive flag.
1017*ec779b8eSAndroid Build Coastguard Worker         uid_t latestActiveUid = VALUE_OR_FATAL(
1018*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_int32_t_uid_t(latestSensitiveActiveOrComm->attributionSource.uid));
1019*ec779b8eSAndroid Build Coastguard Worker         if (isInCommunication && latestActiveUid == mPhoneStateOwnerUid) {
1020*ec779b8eSAndroid Build Coastguard Worker             topSensitiveActive = latestSensitiveActiveOrComm;
1021*ec779b8eSAndroid Build Coastguard Worker             topSensitiveStartNs = latestSensitiveStartNs;
1022*ec779b8eSAndroid Build Coastguard Worker         }
1023*ec779b8eSAndroid Build Coastguard Worker     }
1024*ec779b8eSAndroid Build Coastguard Worker 
1025*ec779b8eSAndroid Build Coastguard Worker     // If both privacy sensitive and regular capture are active:
1026*ec779b8eSAndroid Build Coastguard Worker     //  if the regular capture is privileged
1027*ec779b8eSAndroid Build Coastguard Worker     //    allow concurrency
1028*ec779b8eSAndroid Build Coastguard Worker     //  else
1029*ec779b8eSAndroid Build Coastguard Worker     //    favor the privacy sensitive case
1030*ec779b8eSAndroid Build Coastguard Worker     if (topActive != nullptr && topSensitiveActive != nullptr
1031*ec779b8eSAndroid Build Coastguard Worker             && !topActive->canBypassConcurrentPolicy) {
1032*ec779b8eSAndroid Build Coastguard Worker         topActive = nullptr;
1033*ec779b8eSAndroid Build Coastguard Worker     }
1034*ec779b8eSAndroid Build Coastguard Worker 
1035*ec779b8eSAndroid Build Coastguard Worker     for (size_t i =0; i < mAudioRecordClients.size(); i++) {
1036*ec779b8eSAndroid Build Coastguard Worker         sp<AudioRecordClient> current = mAudioRecordClients[i];
1037*ec779b8eSAndroid Build Coastguard Worker         uid_t currentUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
1038*ec779b8eSAndroid Build Coastguard Worker             current->attributionSource.uid));
1039*ec779b8eSAndroid Build Coastguard Worker         if (!current->active) {
1040*ec779b8eSAndroid Build Coastguard Worker             continue;
1041*ec779b8eSAndroid Build Coastguard Worker         }
1042*ec779b8eSAndroid Build Coastguard Worker 
1043*ec779b8eSAndroid Build Coastguard Worker         audio_source_t source = current->attributes.source;
1044*ec779b8eSAndroid Build Coastguard Worker         bool isTopOrLatestActive = topActive == nullptr ? false :
1045*ec779b8eSAndroid Build Coastguard Worker             current->attributionSource.uid == topActive->attributionSource.uid;
1046*ec779b8eSAndroid Build Coastguard Worker         bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false :
1047*ec779b8eSAndroid Build Coastguard Worker             current->attributionSource.uid == topSensitiveActive->attributionSource.uid;
1048*ec779b8eSAndroid Build Coastguard Worker         bool isTopOrLatestAssistant = latestActiveAssistant == nullptr ? false :
1049*ec779b8eSAndroid Build Coastguard Worker             current->attributionSource.uid == latestActiveAssistant->attributionSource.uid;
1050*ec779b8eSAndroid Build Coastguard Worker         bool isActiveAssistant =
1051*ec779b8eSAndroid Build Coastguard Worker                 (useActiveAssistantList && mUidPolicy->isActiveAssistantUid(currentUid))
1052*ec779b8eSAndroid Build Coastguard Worker                     || mUidPolicy->isAssistantUid(currentUid);
1053*ec779b8eSAndroid Build Coastguard Worker 
1054*ec779b8eSAndroid Build Coastguard Worker         // TODO: b/339112720
1055*ec779b8eSAndroid Build Coastguard Worker         // Refine this logic when we have the correct phone state owner UID. The current issue is
1056*ec779b8eSAndroid Build Coastguard Worker         // when a VOIP APP use Telecom API to manage calls, the mPhoneStateOwnerUid is AID_SYSTEM
1057*ec779b8eSAndroid Build Coastguard Worker         // instead of the actual VOIP APP UID, so isPhoneStateOwnerActive here is not accurate.
1058*ec779b8eSAndroid Build Coastguard Worker         const bool canCaptureIfInCallOrCommunication = [&](const auto& recordClient) REQUIRES(
1059*ec779b8eSAndroid Build Coastguard Worker                                                                mMutex) {
1060*ec779b8eSAndroid Build Coastguard Worker             uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
1061*ec779b8eSAndroid Build Coastguard Worker                 recordClient->attributionSource.uid));
1062*ec779b8eSAndroid Build Coastguard Worker             bool canCaptureCall = recordClient->canBypassConcurrentPolicy;
1063*ec779b8eSAndroid Build Coastguard Worker             bool canCaptureCommunication = recordClient->canBypassConcurrentPolicy
1064*ec779b8eSAndroid Build Coastguard Worker                 || !isPhoneStateOwnerActive
1065*ec779b8eSAndroid Build Coastguard Worker                 || recordUid == mPhoneStateOwnerUid;
1066*ec779b8eSAndroid Build Coastguard Worker             return !(isInCall && !canCaptureCall)
1067*ec779b8eSAndroid Build Coastguard Worker                 && !(isInCommunication && !canCaptureCommunication);
1068*ec779b8eSAndroid Build Coastguard Worker         }(current);
1069*ec779b8eSAndroid Build Coastguard Worker 
1070*ec779b8eSAndroid Build Coastguard Worker         // By default allow capture if:
1071*ec779b8eSAndroid Build Coastguard Worker         //     The assistant is not on TOP
1072*ec779b8eSAndroid Build Coastguard Worker         //         AND is on TOP or latest started
1073*ec779b8eSAndroid Build Coastguard Worker         //         AND there is no active privacy sensitive capture or call
1074*ec779b8eSAndroid Build Coastguard Worker         //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1075*ec779b8eSAndroid Build Coastguard Worker         //     The assistant is on TOP
1076*ec779b8eSAndroid Build Coastguard Worker         //         AND is ongoing communication owner
1077*ec779b8eSAndroid Build Coastguard Worker         //         AND is on TOP or latest started
1078*ec779b8eSAndroid Build Coastguard Worker         const bool allowSensitiveCapture =
1079*ec779b8eSAndroid Build Coastguard Worker             !isSensitiveActive || isTopOrLatestSensitive || current->canBypassConcurrentPolicy;
1080*ec779b8eSAndroid Build Coastguard Worker         bool allowCapture = false;
1081*ec779b8eSAndroid Build Coastguard Worker         if (!isAssistantOnTop || isActiveAssistant) {
1082*ec779b8eSAndroid Build Coastguard Worker             allowCapture = (isTopOrLatestActive || isTopOrLatestSensitive) &&
1083*ec779b8eSAndroid Build Coastguard Worker                            allowSensitiveCapture && canCaptureIfInCallOrCommunication;
1084*ec779b8eSAndroid Build Coastguard Worker         } else {
1085*ec779b8eSAndroid Build Coastguard Worker             allowCapture = isInCommunication && isTopOrLatestSensitive &&
1086*ec779b8eSAndroid Build Coastguard Worker                            canCaptureIfInCallOrCommunication;
1087*ec779b8eSAndroid Build Coastguard Worker         }
1088*ec779b8eSAndroid Build Coastguard Worker 
1089*ec779b8eSAndroid Build Coastguard Worker         if (!current->hasOp()) {
1090*ec779b8eSAndroid Build Coastguard Worker             // Never allow capture if app op is denied
1091*ec779b8eSAndroid Build Coastguard Worker             allowCapture = false;
1092*ec779b8eSAndroid Build Coastguard Worker         } else if (isVirtualSource(source)) {
1093*ec779b8eSAndroid Build Coastguard Worker             // Allow capture for virtual (remote submix, call audio TX or RX...) sources
1094*ec779b8eSAndroid Build Coastguard Worker             allowCapture = true;
1095*ec779b8eSAndroid Build Coastguard Worker         } else if (!useActiveAssistantList && mUidPolicy->isAssistantUid(currentUid)) {
1096*ec779b8eSAndroid Build Coastguard Worker             // For assistant allow capture if:
1097*ec779b8eSAndroid Build Coastguard Worker             //     Active assistant list is not being used
1098*ec779b8eSAndroid Build Coastguard Worker             //     AND accessibility service is on TOP or a RTT call is active
1099*ec779b8eSAndroid Build Coastguard Worker             //            AND the source is VOICE_RECOGNITION or HOTWORD
1100*ec779b8eSAndroid Build Coastguard Worker             //     OR there is no active privacy sensitive capture or call
1101*ec779b8eSAndroid Build Coastguard Worker             //          OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1102*ec779b8eSAndroid Build Coastguard Worker             //            AND is latest TOP assistant AND
1103*ec779b8eSAndroid Build Coastguard Worker             //               uses VOICE_RECOGNITION OR uses HOTWORD
1104*ec779b8eSAndroid Build Coastguard Worker             //            OR there is no TOP assistant and uses HOTWORD
1105*ec779b8eSAndroid Build Coastguard Worker             if (isA11yOnTop || rttCallActive) {
1106*ec779b8eSAndroid Build Coastguard Worker                 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1107*ec779b8eSAndroid Build Coastguard Worker                     allowCapture = true;
1108*ec779b8eSAndroid Build Coastguard Worker                 }
1109*ec779b8eSAndroid Build Coastguard Worker             } else if (allowSensitiveCapture
1110*ec779b8eSAndroid Build Coastguard Worker                     && canCaptureIfInCallOrCommunication) {
1111*ec779b8eSAndroid Build Coastguard Worker                 if (isTopOrLatestAssistant
1112*ec779b8eSAndroid Build Coastguard Worker                     && (source == AUDIO_SOURCE_VOICE_RECOGNITION
1113*ec779b8eSAndroid Build Coastguard Worker                         || source == AUDIO_SOURCE_HOTWORD)) {
1114*ec779b8eSAndroid Build Coastguard Worker                         allowCapture = true;
1115*ec779b8eSAndroid Build Coastguard Worker                 } else if (!isAssistantOnTop && (source == AUDIO_SOURCE_HOTWORD)) {
1116*ec779b8eSAndroid Build Coastguard Worker                     allowCapture = true;
1117*ec779b8eSAndroid Build Coastguard Worker                 }
1118*ec779b8eSAndroid Build Coastguard Worker             }
1119*ec779b8eSAndroid Build Coastguard Worker         } else if (useActiveAssistantList && mUidPolicy->isActiveAssistantUid(currentUid)) {
1120*ec779b8eSAndroid Build Coastguard Worker             // For assistant on active list and on top allow capture if:
1121*ec779b8eSAndroid Build Coastguard Worker             //     An accessibility service is on TOP
1122*ec779b8eSAndroid Build Coastguard Worker             //         AND the source is VOICE_RECOGNITION or HOTWORD
1123*ec779b8eSAndroid Build Coastguard Worker             //     OR there is no active privacy sensitive capture or call
1124*ec779b8eSAndroid Build Coastguard Worker             //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1125*ec779b8eSAndroid Build Coastguard Worker             //         AND uses VOICE_RECOGNITION OR uses HOTWORD
1126*ec779b8eSAndroid Build Coastguard Worker             if (isA11yOnTop) {
1127*ec779b8eSAndroid Build Coastguard Worker                 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1128*ec779b8eSAndroid Build Coastguard Worker                     allowCapture = true;
1129*ec779b8eSAndroid Build Coastguard Worker                 }
1130*ec779b8eSAndroid Build Coastguard Worker             } else if (allowSensitiveCapture
1131*ec779b8eSAndroid Build Coastguard Worker                         && canCaptureIfInCallOrCommunication) {
1132*ec779b8eSAndroid Build Coastguard Worker                 if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) || (source == AUDIO_SOURCE_HOTWORD))
1133*ec779b8eSAndroid Build Coastguard Worker                 {
1134*ec779b8eSAndroid Build Coastguard Worker                     allowCapture = true;
1135*ec779b8eSAndroid Build Coastguard Worker                 }
1136*ec779b8eSAndroid Build Coastguard Worker             }
1137*ec779b8eSAndroid Build Coastguard Worker         } else if (mUidPolicy->isA11yUid(currentUid)) {
1138*ec779b8eSAndroid Build Coastguard Worker             // For accessibility service allow capture if:
1139*ec779b8eSAndroid Build Coastguard Worker             //     The assistant is not on TOP
1140*ec779b8eSAndroid Build Coastguard Worker             //         AND there is no active privacy sensitive capture or call
1141*ec779b8eSAndroid Build Coastguard Worker             //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1142*ec779b8eSAndroid Build Coastguard Worker             //     OR
1143*ec779b8eSAndroid Build Coastguard Worker             //         Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
1144*ec779b8eSAndroid Build Coastguard Worker             if (!isAssistantOnTop
1145*ec779b8eSAndroid Build Coastguard Worker                     && allowSensitiveCapture
1146*ec779b8eSAndroid Build Coastguard Worker                     && canCaptureIfInCallOrCommunication) {
1147*ec779b8eSAndroid Build Coastguard Worker                 allowCapture = true;
1148*ec779b8eSAndroid Build Coastguard Worker             }
1149*ec779b8eSAndroid Build Coastguard Worker             if (isA11yOnTop) {
1150*ec779b8eSAndroid Build Coastguard Worker                 if (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD) {
1151*ec779b8eSAndroid Build Coastguard Worker                     allowCapture = true;
1152*ec779b8eSAndroid Build Coastguard Worker                 }
1153*ec779b8eSAndroid Build Coastguard Worker             }
1154*ec779b8eSAndroid Build Coastguard Worker         } else if (source == AUDIO_SOURCE_HOTWORD) {
1155*ec779b8eSAndroid Build Coastguard Worker             // For HOTWORD source allow capture when not on TOP if:
1156*ec779b8eSAndroid Build Coastguard Worker             //     All active clients are using HOTWORD source
1157*ec779b8eSAndroid Build Coastguard Worker             //     AND no call is active
1158*ec779b8eSAndroid Build Coastguard Worker             //         OR client has CAPTURE_AUDIO_OUTPUT privileged permission
1159*ec779b8eSAndroid Build Coastguard Worker             if (onlyHotwordActive
1160*ec779b8eSAndroid Build Coastguard Worker                     && canCaptureIfInCallOrCommunication) {
1161*ec779b8eSAndroid Build Coastguard Worker                 allowCapture = true;
1162*ec779b8eSAndroid Build Coastguard Worker             }
1163*ec779b8eSAndroid Build Coastguard Worker         } else if (mUidPolicy->isCurrentImeUid(currentUid)) {
1164*ec779b8eSAndroid Build Coastguard Worker             // For current InputMethodService allow capture if:
1165*ec779b8eSAndroid Build Coastguard Worker             //     A RTT call is active AND the source is VOICE_RECOGNITION
1166*ec779b8eSAndroid Build Coastguard Worker             if (rttCallActive && source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1167*ec779b8eSAndroid Build Coastguard Worker                 allowCapture = true;
1168*ec779b8eSAndroid Build Coastguard Worker             }
1169*ec779b8eSAndroid Build Coastguard Worker         }
1170*ec779b8eSAndroid Build Coastguard Worker         setAppState_l(current,
1171*ec779b8eSAndroid Build Coastguard Worker                       allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(currentUid)) :
1172*ec779b8eSAndroid Build Coastguard Worker                                 APP_STATE_IDLE);
1173*ec779b8eSAndroid Build Coastguard Worker     }
1174*ec779b8eSAndroid Build Coastguard Worker }
1175*ec779b8eSAndroid Build Coastguard Worker 
silenceAllRecordings_l()1176*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::silenceAllRecordings_l() {
1177*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
1178*ec779b8eSAndroid Build Coastguard Worker         sp<AudioRecordClient> current = mAudioRecordClients[i];
1179*ec779b8eSAndroid Build Coastguard Worker         if (!isVirtualSource(current->attributes.source)) {
1180*ec779b8eSAndroid Build Coastguard Worker             setAppState_l(current, APP_STATE_IDLE);
1181*ec779b8eSAndroid Build Coastguard Worker         }
1182*ec779b8eSAndroid Build Coastguard Worker     }
1183*ec779b8eSAndroid Build Coastguard Worker }
1184*ec779b8eSAndroid Build Coastguard Worker 
1185*ec779b8eSAndroid Build Coastguard Worker /* static */
apmStatFromAmState(int amState)1186*ec779b8eSAndroid Build Coastguard Worker app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
1187*ec779b8eSAndroid Build Coastguard Worker 
1188*ec779b8eSAndroid Build Coastguard Worker     if (amState == ActivityManager::PROCESS_STATE_UNKNOWN) {
1189*ec779b8eSAndroid Build Coastguard Worker         return APP_STATE_IDLE;
1190*ec779b8eSAndroid Build Coastguard Worker     } else if (amState <= ActivityManager::PROCESS_STATE_TOP) {
1191*ec779b8eSAndroid Build Coastguard Worker       // include persistent services
1192*ec779b8eSAndroid Build Coastguard Worker       return APP_STATE_TOP;
1193*ec779b8eSAndroid Build Coastguard Worker     }
1194*ec779b8eSAndroid Build Coastguard Worker     return APP_STATE_FOREGROUND;
1195*ec779b8eSAndroid Build Coastguard Worker }
1196*ec779b8eSAndroid Build Coastguard Worker 
1197*ec779b8eSAndroid Build Coastguard Worker /* static */
isVirtualSource(audio_source_t source)1198*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::isVirtualSource(audio_source_t source)
1199*ec779b8eSAndroid Build Coastguard Worker {
1200*ec779b8eSAndroid Build Coastguard Worker     switch (source) {
1201*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_SOURCE_VOICE_UPLINK:
1202*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_SOURCE_VOICE_DOWNLINK:
1203*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_SOURCE_VOICE_CALL:
1204*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_SOURCE_REMOTE_SUBMIX:
1205*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_SOURCE_FM_TUNER:
1206*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_SOURCE_ECHO_REFERENCE:
1207*ec779b8eSAndroid Build Coastguard Worker             return true;
1208*ec779b8eSAndroid Build Coastguard Worker         default:
1209*ec779b8eSAndroid Build Coastguard Worker             break;
1210*ec779b8eSAndroid Build Coastguard Worker     }
1211*ec779b8eSAndroid Build Coastguard Worker     return false;
1212*ec779b8eSAndroid Build Coastguard Worker }
1213*ec779b8eSAndroid Build Coastguard Worker 
setAppState_l(sp<AudioRecordClient> client,app_state_t state)1214*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::setAppState_l(sp<AudioRecordClient> client, app_state_t state)
1215*ec779b8eSAndroid Build Coastguard Worker {
1216*ec779b8eSAndroid Build Coastguard Worker     AutoCallerClear acc;
1217*ec779b8eSAndroid Build Coastguard Worker 
1218*ec779b8eSAndroid Build Coastguard Worker     if (mAudioPolicyManager) {
1219*ec779b8eSAndroid Build Coastguard Worker         mAudioPolicyManager->setAppState(client->portId, state);
1220*ec779b8eSAndroid Build Coastguard Worker     }
1221*ec779b8eSAndroid Build Coastguard Worker     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1222*ec779b8eSAndroid Build Coastguard Worker     if (af) {
1223*ec779b8eSAndroid Build Coastguard Worker         bool silenced = state == APP_STATE_IDLE;
1224*ec779b8eSAndroid Build Coastguard Worker         if (client->silenced != silenced) {
1225*ec779b8eSAndroid Build Coastguard Worker             if (client->active) {
1226*ec779b8eSAndroid Build Coastguard Worker                 if (silenced) {
1227*ec779b8eSAndroid Build Coastguard Worker                     finishRecording(client->attributionSource, client->virtualDeviceId,
1228*ec779b8eSAndroid Build Coastguard Worker                                     client->attributes.source);
1229*ec779b8eSAndroid Build Coastguard Worker                 } else {
1230*ec779b8eSAndroid Build Coastguard Worker                     std::stringstream msg;
1231*ec779b8eSAndroid Build Coastguard Worker                     msg << "Audio recording un-silenced on session " << client->session;
1232*ec779b8eSAndroid Build Coastguard Worker                     if (startRecording(client->attributionSource, client->virtualDeviceId,
1233*ec779b8eSAndroid Build Coastguard Worker                                 String16(msg.str().c_str()), client->attributes.source)
1234*ec779b8eSAndroid Build Coastguard Worker                                 != PERMISSION_GRANTED) {
1235*ec779b8eSAndroid Build Coastguard Worker                         return;
1236*ec779b8eSAndroid Build Coastguard Worker                     }
1237*ec779b8eSAndroid Build Coastguard Worker                 }
1238*ec779b8eSAndroid Build Coastguard Worker             }
1239*ec779b8eSAndroid Build Coastguard Worker             af->setRecordSilenced(client->portId, silenced);
1240*ec779b8eSAndroid Build Coastguard Worker             client->silenced = silenced;
1241*ec779b8eSAndroid Build Coastguard Worker         }
1242*ec779b8eSAndroid Build Coastguard Worker     }
1243*ec779b8eSAndroid Build Coastguard Worker }
1244*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd,const Vector<String16> & args __unused)1245*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
1246*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS  // update for trylock.
1247*ec779b8eSAndroid Build Coastguard Worker {
1248*ec779b8eSAndroid Build Coastguard Worker     if (!dumpAllowed()) {
1249*ec779b8eSAndroid Build Coastguard Worker         dumpPermissionDenial(fd);
1250*ec779b8eSAndroid Build Coastguard Worker     } else {
1251*ec779b8eSAndroid Build Coastguard Worker         const bool locked = mMutex.try_lock(kDumpLockTimeoutNs);
1252*ec779b8eSAndroid Build Coastguard Worker         if (!locked) {
1253*ec779b8eSAndroid Build Coastguard Worker             String8 result(kDeadlockedString);
1254*ec779b8eSAndroid Build Coastguard Worker             write(fd, result.c_str(), result.size());
1255*ec779b8eSAndroid Build Coastguard Worker         }
1256*ec779b8eSAndroid Build Coastguard Worker 
1257*ec779b8eSAndroid Build Coastguard Worker         dumpInternals(fd);
1258*ec779b8eSAndroid Build Coastguard Worker 
1259*ec779b8eSAndroid Build Coastguard Worker         String8 actPtr = String8::format("AudioCommandThread: %p\n", mAudioCommandThread.get());
1260*ec779b8eSAndroid Build Coastguard Worker         write(fd, actPtr.c_str(), actPtr.size());
1261*ec779b8eSAndroid Build Coastguard Worker         if (mAudioCommandThread != 0) {
1262*ec779b8eSAndroid Build Coastguard Worker             mAudioCommandThread->dump(fd);
1263*ec779b8eSAndroid Build Coastguard Worker         }
1264*ec779b8eSAndroid Build Coastguard Worker 
1265*ec779b8eSAndroid Build Coastguard Worker         String8 octPtr = String8::format("OutputCommandThread: %p\n", mOutputCommandThread.get());
1266*ec779b8eSAndroid Build Coastguard Worker         write(fd, octPtr.c_str(), octPtr.size());
1267*ec779b8eSAndroid Build Coastguard Worker         if (mOutputCommandThread != 0) {
1268*ec779b8eSAndroid Build Coastguard Worker             mOutputCommandThread->dump(fd);
1269*ec779b8eSAndroid Build Coastguard Worker         }
1270*ec779b8eSAndroid Build Coastguard Worker 
1271*ec779b8eSAndroid Build Coastguard Worker         if (mAudioPolicyManager) {
1272*ec779b8eSAndroid Build Coastguard Worker             mAudioPolicyManager->dump(fd);
1273*ec779b8eSAndroid Build Coastguard Worker         } else {
1274*ec779b8eSAndroid Build Coastguard Worker             String8 apmPtr = String8::format("AudioPolicyManager: %p\n", mAudioPolicyManager);
1275*ec779b8eSAndroid Build Coastguard Worker             write(fd, apmPtr.c_str(), apmPtr.size());
1276*ec779b8eSAndroid Build Coastguard Worker         }
1277*ec779b8eSAndroid Build Coastguard Worker 
1278*ec779b8eSAndroid Build Coastguard Worker         mPackageManager.dump(fd);
1279*ec779b8eSAndroid Build Coastguard Worker 
1280*ec779b8eSAndroid Build Coastguard Worker         dumpReleaseLock(mMutex, locked);
1281*ec779b8eSAndroid Build Coastguard Worker 
1282*ec779b8eSAndroid Build Coastguard Worker         if (mSpatializer != nullptr) {
1283*ec779b8eSAndroid Build Coastguard Worker             std::string dumpString = mSpatializer->toString(1 /* level */);
1284*ec779b8eSAndroid Build Coastguard Worker             write(fd, dumpString.c_str(), dumpString.size());
1285*ec779b8eSAndroid Build Coastguard Worker         } else {
1286*ec779b8eSAndroid Build Coastguard Worker             String8 spatializerPtr = String8::format("Spatializer no supportted on this device\n");
1287*ec779b8eSAndroid Build Coastguard Worker             write(fd, spatializerPtr.c_str(), spatializerPtr.size());
1288*ec779b8eSAndroid Build Coastguard Worker         }
1289*ec779b8eSAndroid Build Coastguard Worker 
1290*ec779b8eSAndroid Build Coastguard Worker         {
1291*ec779b8eSAndroid Build Coastguard Worker             std::string timeCheckStats = getIAudioPolicyServiceStatistics().dump();
1292*ec779b8eSAndroid Build Coastguard Worker             dprintf(fd, "\nIAudioPolicyService binder call profile\n");
1293*ec779b8eSAndroid Build Coastguard Worker             write(fd, timeCheckStats.c_str(), timeCheckStats.size());
1294*ec779b8eSAndroid Build Coastguard Worker         }
1295*ec779b8eSAndroid Build Coastguard Worker     }
1296*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1297*ec779b8eSAndroid Build Coastguard Worker }
1298*ec779b8eSAndroid Build Coastguard Worker 
dumpPermissionDenial(int fd)1299*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::dumpPermissionDenial(int fd)
1300*ec779b8eSAndroid Build Coastguard Worker {
1301*ec779b8eSAndroid Build Coastguard Worker     const size_t SIZE = 256;
1302*ec779b8eSAndroid Build Coastguard Worker     char buffer[SIZE];
1303*ec779b8eSAndroid Build Coastguard Worker     String8 result;
1304*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "Permission Denial: "
1305*ec779b8eSAndroid Build Coastguard Worker             "can't dump AudioPolicyService from pid=%d, uid=%d\n",
1306*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingPid(),
1307*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingUid());
1308*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
1309*ec779b8eSAndroid Build Coastguard Worker     write(fd, result.c_str(), result.size());
1310*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1311*ec779b8eSAndroid Build Coastguard Worker }
1312*ec779b8eSAndroid Build Coastguard Worker 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)1313*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::onTransact(
1314*ec779b8eSAndroid Build Coastguard Worker         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1315*ec779b8eSAndroid Build Coastguard Worker     // make sure transactions reserved to AudioFlinger do not come from other processes
1316*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
1317*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_startOutput:
1318*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_stopOutput:
1319*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_releaseOutput:
1320*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getInputForAttr:
1321*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_startInput:
1322*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_stopInput:
1323*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_releaseInput:
1324*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getOutputForEffect:
1325*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_registerEffect:
1326*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_unregisterEffect:
1327*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setEffectEnabled:
1328*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getStrategyForStream:
1329*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getOutputForAttr:
1330*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_moveEffectsToIo:
1331*ec779b8eSAndroid Build Coastguard Worker             ALOGW("%s: transaction %d received from PID %d",
1332*ec779b8eSAndroid Build Coastguard Worker                   __func__, code, IPCThreadState::self()->getCallingPid());
1333*ec779b8eSAndroid Build Coastguard Worker             return INVALID_OPERATION;
1334*ec779b8eSAndroid Build Coastguard Worker         default:
1335*ec779b8eSAndroid Build Coastguard Worker             break;
1336*ec779b8eSAndroid Build Coastguard Worker     }
1337*ec779b8eSAndroid Build Coastguard Worker 
1338*ec779b8eSAndroid Build Coastguard Worker     // make sure the following transactions come from system components
1339*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
1340*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setDeviceConnectionState:
1341*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_handleDeviceConfigChange:
1342*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setPhoneState:
1343*ec779b8eSAndroid Build Coastguard Worker //FIXME: Allow setForceUse calls from system apps until a better use case routing API is available
1344*ec779b8eSAndroid Build Coastguard Worker //      case TRANSACTION_setForceUse:
1345*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setDeviceAbsoluteVolumeEnabled:
1346*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_initStreamVolume:
1347*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setStreamVolumeIndex:
1348*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setVolumeIndexForAttributes:
1349*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getStreamVolumeIndex:
1350*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getVolumeIndexForAttributes:
1351*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getMinVolumeIndexForAttributes:
1352*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getMaxVolumeIndexForAttributes:
1353*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_isStreamActive:
1354*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_isStreamActiveRemotely:
1355*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_isSourceActive:
1356*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_registerPolicyMixes:
1357*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_updatePolicyMixes:
1358*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setMasterMono:
1359*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getSurroundFormats:
1360*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getReportedSurroundFormats:
1361*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setSurroundFormatEnabled:
1362*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setAssistantServicesUids:
1363*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setActiveAssistantServicesUids:
1364*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setA11yServicesUids:
1365*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setUidDeviceAffinities:
1366*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_removeUidDeviceAffinities:
1367*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setUserIdDeviceAffinities:
1368*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_removeUserIdDeviceAffinities:
1369*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getHwOffloadFormatsSupportedForBluetoothMedia:
1370*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_listAudioVolumeGroups:
1371*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getVolumeGroupFromAudioAttributes:
1372*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_acquireSoundTriggerSession:
1373*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_releaseSoundTriggerSession:
1374*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_isHotwordStreamSupported:
1375*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setRttEnabled:
1376*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_isCallScreenModeSupported:
1377*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setDevicesRoleForStrategy:
1378*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setSupportedSystemUsages:
1379*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_removeDevicesRoleForStrategy:
1380*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_clearDevicesRoleForStrategy:
1381*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getDevicesForRoleAndStrategy:
1382*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getDevicesForAttributes:
1383*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setAllowedCapturePolicy:
1384*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_onNewAudioModulesAvailable:
1385*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setCurrentImeUid:
1386*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_registerSoundTriggerCaptureStateListener:
1387*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setDevicesRoleForCapturePreset:
1388*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_addDevicesRoleForCapturePreset:
1389*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_removeDevicesRoleForCapturePreset:
1390*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_clearDevicesRoleForCapturePreset:
1391*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getDevicesForRoleAndCapturePreset:
1392*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getSpatializer:
1393*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_setPreferredMixerAttributes:
1394*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_clearPreferredMixerAttributes:
1395*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getRegisteredPolicyMixes: {
1396*ec779b8eSAndroid Build Coastguard Worker             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
1397*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
1398*ec779b8eSAndroid Build Coastguard Worker                       __func__, code, IPCThreadState::self()->getCallingPid(),
1399*ec779b8eSAndroid Build Coastguard Worker                       IPCThreadState::self()->getCallingUid());
1400*ec779b8eSAndroid Build Coastguard Worker                 return INVALID_OPERATION;
1401*ec779b8eSAndroid Build Coastguard Worker             }
1402*ec779b8eSAndroid Build Coastguard Worker         } break;
1403*ec779b8eSAndroid Build Coastguard Worker         default:
1404*ec779b8eSAndroid Build Coastguard Worker             break;
1405*ec779b8eSAndroid Build Coastguard Worker     }
1406*ec779b8eSAndroid Build Coastguard Worker 
1407*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
1408*ec779b8eSAndroid Build Coastguard Worker         case TRANSACTION_getPermissionController: {
1409*ec779b8eSAndroid Build Coastguard Worker             if (!isAudioServerOrSystemServerUid(IPCThreadState::self()->getCallingUid())) {
1410*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
1411*ec779b8eSAndroid Build Coastguard Worker                       __func__, code, IPCThreadState::self()->getCallingPid(),
1412*ec779b8eSAndroid Build Coastguard Worker                       IPCThreadState::self()->getCallingUid());
1413*ec779b8eSAndroid Build Coastguard Worker                 return INVALID_OPERATION;
1414*ec779b8eSAndroid Build Coastguard Worker             }
1415*ec779b8eSAndroid Build Coastguard Worker         }
1416*ec779b8eSAndroid Build Coastguard Worker     }
1417*ec779b8eSAndroid Build Coastguard Worker 
1418*ec779b8eSAndroid Build Coastguard Worker     const std::string methodName = getIAudioPolicyServiceStatistics().getMethodForCode(code);
1419*ec779b8eSAndroid Build Coastguard Worker     mediautils::TimeCheck check(
1420*ec779b8eSAndroid Build Coastguard Worker             std::string("IAudioPolicyService::").append(methodName),
1421*ec779b8eSAndroid Build Coastguard Worker             [code, methodName](bool timeout, float elapsedMs) { // don't move methodName.
1422*ec779b8eSAndroid Build Coastguard Worker         if (timeout) {
1423*ec779b8eSAndroid Build Coastguard Worker             mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_POLICY)
1424*ec779b8eSAndroid Build Coastguard Worker                 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_TIMEOUT)
1425*ec779b8eSAndroid Build Coastguard Worker                 .set(AMEDIAMETRICS_PROP_METHODCODE, int64_t(code))
1426*ec779b8eSAndroid Build Coastguard Worker                 .set(AMEDIAMETRICS_PROP_METHODNAME, methodName.c_str())
1427*ec779b8eSAndroid Build Coastguard Worker                 .record();
1428*ec779b8eSAndroid Build Coastguard Worker         } else {
1429*ec779b8eSAndroid Build Coastguard Worker             getIAudioPolicyServiceStatistics().event(code, elapsedMs);
1430*ec779b8eSAndroid Build Coastguard Worker         }
1431*ec779b8eSAndroid Build Coastguard Worker     }, mediautils::TimeCheck::getDefaultTimeoutDuration(),
1432*ec779b8eSAndroid Build Coastguard Worker     mediautils::TimeCheck::getDefaultSecondChanceDuration(),
1433*ec779b8eSAndroid Build Coastguard Worker     !property_get_bool("audio.timecheck.disabled", false) /* crashOnTimeout */);
1434*ec779b8eSAndroid Build Coastguard Worker 
1435*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
1436*ec779b8eSAndroid Build Coastguard Worker         case SHELL_COMMAND_TRANSACTION: {
1437*ec779b8eSAndroid Build Coastguard Worker             int in = data.readFileDescriptor();
1438*ec779b8eSAndroid Build Coastguard Worker             int out = data.readFileDescriptor();
1439*ec779b8eSAndroid Build Coastguard Worker             int err = data.readFileDescriptor();
1440*ec779b8eSAndroid Build Coastguard Worker             int argc = data.readInt32();
1441*ec779b8eSAndroid Build Coastguard Worker             Vector<String16> args;
1442*ec779b8eSAndroid Build Coastguard Worker             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
1443*ec779b8eSAndroid Build Coastguard Worker                args.add(data.readString16());
1444*ec779b8eSAndroid Build Coastguard Worker             }
1445*ec779b8eSAndroid Build Coastguard Worker             sp<IBinder> unusedCallback;
1446*ec779b8eSAndroid Build Coastguard Worker             sp<IResultReceiver> resultReceiver;
1447*ec779b8eSAndroid Build Coastguard Worker             status_t status;
1448*ec779b8eSAndroid Build Coastguard Worker             if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
1449*ec779b8eSAndroid Build Coastguard Worker                 return status;
1450*ec779b8eSAndroid Build Coastguard Worker             }
1451*ec779b8eSAndroid Build Coastguard Worker             if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
1452*ec779b8eSAndroid Build Coastguard Worker                 return status;
1453*ec779b8eSAndroid Build Coastguard Worker             }
1454*ec779b8eSAndroid Build Coastguard Worker             status = shellCommand(in, out, err, args);
1455*ec779b8eSAndroid Build Coastguard Worker             if (resultReceiver != nullptr) {
1456*ec779b8eSAndroid Build Coastguard Worker                 resultReceiver->send(status);
1457*ec779b8eSAndroid Build Coastguard Worker             }
1458*ec779b8eSAndroid Build Coastguard Worker             return NO_ERROR;
1459*ec779b8eSAndroid Build Coastguard Worker         }
1460*ec779b8eSAndroid Build Coastguard Worker     }
1461*ec779b8eSAndroid Build Coastguard Worker 
1462*ec779b8eSAndroid Build Coastguard Worker     return BnAudioPolicyService::onTransact(code, data, reply, flags);
1463*ec779b8eSAndroid Build Coastguard Worker }
1464*ec779b8eSAndroid Build Coastguard Worker 
1465*ec779b8eSAndroid Build Coastguard Worker // ------------------- Shell command implementation -------------------
1466*ec779b8eSAndroid Build Coastguard Worker 
1467*ec779b8eSAndroid Build Coastguard Worker // NOTE: This is a remote API - make sure all args are validated
shellCommand(int in,int out,int err,Vector<String16> & args)1468*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
1469*ec779b8eSAndroid Build Coastguard Worker     if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
1470*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1471*ec779b8eSAndroid Build Coastguard Worker     }
1472*ec779b8eSAndroid Build Coastguard Worker     if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
1473*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1474*ec779b8eSAndroid Build Coastguard Worker     }
1475*ec779b8eSAndroid Build Coastguard Worker     if (args.size() >= 1 && args[0] == String16("purge_permission-cache")) {
1476*ec779b8eSAndroid Build Coastguard Worker         purgePermissionCache();
1477*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
1478*ec779b8eSAndroid Build Coastguard Worker     }
1479*ec779b8eSAndroid Build Coastguard Worker     return BAD_VALUE;
1480*ec779b8eSAndroid Build Coastguard Worker }
1481*ec779b8eSAndroid Build Coastguard Worker 
registerOutput(audio_io_handle_t output,const audio_config_base_t & config,const audio_output_flags_t flags)1482*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::registerOutput(audio_io_handle_t output,
1483*ec779b8eSAndroid Build Coastguard Worker                         const audio_config_base_t& config,
1484*ec779b8eSAndroid Build Coastguard Worker                         const audio_output_flags_t flags) {
1485*ec779b8eSAndroid Build Coastguard Worker     return mUsecaseValidator->registerStream(output, config, flags);
1486*ec779b8eSAndroid Build Coastguard Worker }
1487*ec779b8eSAndroid Build Coastguard Worker 
unregisterOutput(audio_io_handle_t output)1488*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::unregisterOutput(audio_io_handle_t output) {
1489*ec779b8eSAndroid Build Coastguard Worker     return mUsecaseValidator->unregisterStream(output);
1490*ec779b8eSAndroid Build Coastguard Worker }
1491*ec779b8eSAndroid Build Coastguard Worker 
1492*ec779b8eSAndroid Build Coastguard Worker // -----------  AudioPolicyService::UidPolicy implementation ----------
1493*ec779b8eSAndroid Build Coastguard Worker 
registerSelf()1494*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::registerSelf() {
1495*ec779b8eSAndroid Build Coastguard Worker     status_t res = mAm.linkToDeath(this);
1496*ec779b8eSAndroid Build Coastguard Worker     mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
1497*ec779b8eSAndroid Build Coastguard Worker             | ActivityManager::UID_OBSERVER_IDLE
1498*ec779b8eSAndroid Build Coastguard Worker             | ActivityManager::UID_OBSERVER_ACTIVE
1499*ec779b8eSAndroid Build Coastguard Worker             | ActivityManager::UID_OBSERVER_PROCSTATE,
1500*ec779b8eSAndroid Build Coastguard Worker             ActivityManager::PROCESS_STATE_UNKNOWN,
1501*ec779b8eSAndroid Build Coastguard Worker             String16("audioserver"));
1502*ec779b8eSAndroid Build Coastguard Worker     if (!res) {
1503*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1504*ec779b8eSAndroid Build Coastguard Worker         mObserverRegistered = true;
1505*ec779b8eSAndroid Build Coastguard Worker     } else {
1506*ec779b8eSAndroid Build Coastguard Worker         ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
1507*ec779b8eSAndroid Build Coastguard Worker 
1508*ec779b8eSAndroid Build Coastguard Worker         mAm.unregisterUidObserver(this);
1509*ec779b8eSAndroid Build Coastguard Worker     }
1510*ec779b8eSAndroid Build Coastguard Worker }
1511*ec779b8eSAndroid Build Coastguard Worker 
unregisterSelf()1512*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::unregisterSelf() {
1513*ec779b8eSAndroid Build Coastguard Worker     mAm.unlinkToDeath(this);
1514*ec779b8eSAndroid Build Coastguard Worker     mAm.unregisterUidObserver(this);
1515*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mMutex);
1516*ec779b8eSAndroid Build Coastguard Worker     mObserverRegistered = false;
1517*ec779b8eSAndroid Build Coastguard Worker }
1518*ec779b8eSAndroid Build Coastguard Worker 
binderDied(__unused const wp<IBinder> & who)1519*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
1520*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mMutex);
1521*ec779b8eSAndroid Build Coastguard Worker     mCachedUids.clear();
1522*ec779b8eSAndroid Build Coastguard Worker     mObserverRegistered = false;
1523*ec779b8eSAndroid Build Coastguard Worker }
1524*ec779b8eSAndroid Build Coastguard Worker 
checkRegistered()1525*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::checkRegistered() {
1526*ec779b8eSAndroid Build Coastguard Worker     bool needToReregister = false;
1527*ec779b8eSAndroid Build Coastguard Worker     {
1528*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1529*ec779b8eSAndroid Build Coastguard Worker         needToReregister = !mObserverRegistered;
1530*ec779b8eSAndroid Build Coastguard Worker     }
1531*ec779b8eSAndroid Build Coastguard Worker     if (needToReregister) {
1532*ec779b8eSAndroid Build Coastguard Worker         // Looks like ActivityManager has died previously, attempt to re-register.
1533*ec779b8eSAndroid Build Coastguard Worker         registerSelf();
1534*ec779b8eSAndroid Build Coastguard Worker     }
1535*ec779b8eSAndroid Build Coastguard Worker }
1536*ec779b8eSAndroid Build Coastguard Worker 
isUidActive(uid_t uid)1537*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
1538*ec779b8eSAndroid Build Coastguard Worker     if (isServiceUid(uid)) return true;
1539*ec779b8eSAndroid Build Coastguard Worker     checkRegistered();
1540*ec779b8eSAndroid Build Coastguard Worker     {
1541*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1542*ec779b8eSAndroid Build Coastguard Worker         // In an absense of the ActivityManager, assume everything to be active.
1543*ec779b8eSAndroid Build Coastguard Worker         if (!mObserverRegistered) return true;
1544*ec779b8eSAndroid Build Coastguard Worker         auto cacheIter = mCachedUids.find(uid);
1545*ec779b8eSAndroid Build Coastguard Worker         if (cacheIter != mCachedUids.end()) {
1546*ec779b8eSAndroid Build Coastguard Worker             return cacheIter->second.first;
1547*ec779b8eSAndroid Build Coastguard Worker         }
1548*ec779b8eSAndroid Build Coastguard Worker     }
1549*ec779b8eSAndroid Build Coastguard Worker     ActivityManager am;
1550*ec779b8eSAndroid Build Coastguard Worker     bool active = am.isUidActive(uid, String16("audioserver"));
1551*ec779b8eSAndroid Build Coastguard Worker     {
1552*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1553*ec779b8eSAndroid Build Coastguard Worker         mCachedUids.insert(std::pair<uid_t,
1554*ec779b8eSAndroid Build Coastguard Worker                            std::pair<bool, int>>(uid, std::pair<bool, int>(active,
1555*ec779b8eSAndroid Build Coastguard Worker                                                       ActivityManager::PROCESS_STATE_UNKNOWN)));
1556*ec779b8eSAndroid Build Coastguard Worker     }
1557*ec779b8eSAndroid Build Coastguard Worker     return active;
1558*ec779b8eSAndroid Build Coastguard Worker }
1559*ec779b8eSAndroid Build Coastguard Worker 
getUidState(uid_t uid)1560*ec779b8eSAndroid Build Coastguard Worker int AudioPolicyService::UidPolicy::getUidState(uid_t uid) {
1561*ec779b8eSAndroid Build Coastguard Worker     if (isServiceUid(uid)) {
1562*ec779b8eSAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_TOP;
1563*ec779b8eSAndroid Build Coastguard Worker     }
1564*ec779b8eSAndroid Build Coastguard Worker     checkRegistered();
1565*ec779b8eSAndroid Build Coastguard Worker     {
1566*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1567*ec779b8eSAndroid Build Coastguard Worker         // In an absense of the ActivityManager, assume everything to be active.
1568*ec779b8eSAndroid Build Coastguard Worker         if (!mObserverRegistered) {
1569*ec779b8eSAndroid Build Coastguard Worker             return ActivityManager::PROCESS_STATE_TOP;
1570*ec779b8eSAndroid Build Coastguard Worker         }
1571*ec779b8eSAndroid Build Coastguard Worker         auto cacheIter = mCachedUids.find(uid);
1572*ec779b8eSAndroid Build Coastguard Worker         if (cacheIter != mCachedUids.end()) {
1573*ec779b8eSAndroid Build Coastguard Worker             if (cacheIter->second.first) {
1574*ec779b8eSAndroid Build Coastguard Worker                 return cacheIter->second.second;
1575*ec779b8eSAndroid Build Coastguard Worker             } else {
1576*ec779b8eSAndroid Build Coastguard Worker                 return ActivityManager::PROCESS_STATE_UNKNOWN;
1577*ec779b8eSAndroid Build Coastguard Worker             }
1578*ec779b8eSAndroid Build Coastguard Worker         }
1579*ec779b8eSAndroid Build Coastguard Worker     }
1580*ec779b8eSAndroid Build Coastguard Worker     ActivityManager am;
1581*ec779b8eSAndroid Build Coastguard Worker     bool active = am.isUidActive(uid, String16("audioserver"));
1582*ec779b8eSAndroid Build Coastguard Worker     int state = ActivityManager::PROCESS_STATE_UNKNOWN;
1583*ec779b8eSAndroid Build Coastguard Worker     if (active) {
1584*ec779b8eSAndroid Build Coastguard Worker         state = am.getUidProcessState(uid, String16("audioserver"));
1585*ec779b8eSAndroid Build Coastguard Worker     }
1586*ec779b8eSAndroid Build Coastguard Worker     {
1587*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1588*ec779b8eSAndroid Build Coastguard Worker         mCachedUids.insert(std::pair<uid_t,
1589*ec779b8eSAndroid Build Coastguard Worker                            std::pair<bool, int>>(uid, std::pair<bool, int>(active, state)));
1590*ec779b8eSAndroid Build Coastguard Worker     }
1591*ec779b8eSAndroid Build Coastguard Worker 
1592*ec779b8eSAndroid Build Coastguard Worker     return state;
1593*ec779b8eSAndroid Build Coastguard Worker }
1594*ec779b8eSAndroid Build Coastguard Worker 
onUidActive(uid_t uid)1595*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
1596*ec779b8eSAndroid Build Coastguard Worker     updateUid(&mCachedUids, uid, true, ActivityManager::PROCESS_STATE_UNKNOWN, true);
1597*ec779b8eSAndroid Build Coastguard Worker }
1598*ec779b8eSAndroid Build Coastguard Worker 
onUidGone(uid_t uid,__unused bool disabled)1599*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
1600*ec779b8eSAndroid Build Coastguard Worker     updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, false);
1601*ec779b8eSAndroid Build Coastguard Worker }
1602*ec779b8eSAndroid Build Coastguard Worker 
onUidIdle(uid_t uid,__unused bool disabled)1603*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
1604*ec779b8eSAndroid Build Coastguard Worker     updateUid(&mCachedUids, uid, false, ActivityManager::PROCESS_STATE_UNKNOWN, true);
1605*ec779b8eSAndroid Build Coastguard Worker }
1606*ec779b8eSAndroid Build Coastguard Worker 
onUidStateChanged(uid_t uid,int32_t procState,int64_t procStateSeq __unused,int32_t capability __unused)1607*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::onUidStateChanged(uid_t uid,
1608*ec779b8eSAndroid Build Coastguard Worker                                                       int32_t procState,
1609*ec779b8eSAndroid Build Coastguard Worker                                                       int64_t procStateSeq __unused,
1610*ec779b8eSAndroid Build Coastguard Worker                                                       int32_t capability __unused) {
1611*ec779b8eSAndroid Build Coastguard Worker     if (procState != ActivityManager::PROCESS_STATE_UNKNOWN) {
1612*ec779b8eSAndroid Build Coastguard Worker         updateUid(&mCachedUids, uid, true, procState, true);
1613*ec779b8eSAndroid Build Coastguard Worker     }
1614*ec779b8eSAndroid Build Coastguard Worker }
1615*ec779b8eSAndroid Build Coastguard Worker 
onUidProcAdjChanged(uid_t uid __unused,int32_t adj __unused)1616*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {
1617*ec779b8eSAndroid Build Coastguard Worker }
1618*ec779b8eSAndroid Build Coastguard Worker 
notifyService()1619*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::notifyService() {
1620*ec779b8eSAndroid Build Coastguard Worker     sp<AudioPolicyService> service = mService.promote();
1621*ec779b8eSAndroid Build Coastguard Worker     if (service != nullptr) {
1622*ec779b8eSAndroid Build Coastguard Worker         service->updateUidStates();
1623*ec779b8eSAndroid Build Coastguard Worker     }
1624*ec779b8eSAndroid Build Coastguard Worker }
1625*ec779b8eSAndroid Build Coastguard Worker 
updateUid(std::unordered_map<uid_t,std::pair<bool,int>> * uids,uid_t uid,bool active,int state,bool insert)1626*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::updateUid(std::unordered_map<uid_t,
1627*ec779b8eSAndroid Build Coastguard Worker                                               std::pair<bool, int>> *uids,
1628*ec779b8eSAndroid Build Coastguard Worker                                               uid_t uid,
1629*ec779b8eSAndroid Build Coastguard Worker                                               bool active,
1630*ec779b8eSAndroid Build Coastguard Worker                                               int state,
1631*ec779b8eSAndroid Build Coastguard Worker                                               bool insert) {
1632*ec779b8eSAndroid Build Coastguard Worker     if (isServiceUid(uid)) {
1633*ec779b8eSAndroid Build Coastguard Worker         return;
1634*ec779b8eSAndroid Build Coastguard Worker     }
1635*ec779b8eSAndroid Build Coastguard Worker     bool wasActive = isUidActive(uid);
1636*ec779b8eSAndroid Build Coastguard Worker     int previousState = getUidState(uid);
1637*ec779b8eSAndroid Build Coastguard Worker     {
1638*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
1639*ec779b8eSAndroid Build Coastguard Worker         updateUidLocked(uids, uid, active, state, insert);
1640*ec779b8eSAndroid Build Coastguard Worker     }
1641*ec779b8eSAndroid Build Coastguard Worker     if (wasActive != isUidActive(uid) || state != previousState) {
1642*ec779b8eSAndroid Build Coastguard Worker         notifyService();
1643*ec779b8eSAndroid Build Coastguard Worker     }
1644*ec779b8eSAndroid Build Coastguard Worker }
1645*ec779b8eSAndroid Build Coastguard Worker 
updateUidLocked(std::unordered_map<uid_t,std::pair<bool,int>> * uids,uid_t uid,bool active,int state,bool insert)1646*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t,
1647*ec779b8eSAndroid Build Coastguard Worker                                                     std::pair<bool, int>> *uids,
1648*ec779b8eSAndroid Build Coastguard Worker                                                     uid_t uid,
1649*ec779b8eSAndroid Build Coastguard Worker                                                     bool active,
1650*ec779b8eSAndroid Build Coastguard Worker                                                     int state,
1651*ec779b8eSAndroid Build Coastguard Worker                                                     bool insert) {
1652*ec779b8eSAndroid Build Coastguard Worker     auto it = uids->find(uid);
1653*ec779b8eSAndroid Build Coastguard Worker     if (it != uids->end()) {
1654*ec779b8eSAndroid Build Coastguard Worker         if (insert) {
1655*ec779b8eSAndroid Build Coastguard Worker             if (state == ActivityManager::PROCESS_STATE_UNKNOWN) {
1656*ec779b8eSAndroid Build Coastguard Worker                 it->second.first = active;
1657*ec779b8eSAndroid Build Coastguard Worker             }
1658*ec779b8eSAndroid Build Coastguard Worker             if (it->second.first) {
1659*ec779b8eSAndroid Build Coastguard Worker                 it->second.second = state;
1660*ec779b8eSAndroid Build Coastguard Worker             } else {
1661*ec779b8eSAndroid Build Coastguard Worker                 it->second.second = ActivityManager::PROCESS_STATE_UNKNOWN;
1662*ec779b8eSAndroid Build Coastguard Worker             }
1663*ec779b8eSAndroid Build Coastguard Worker         } else {
1664*ec779b8eSAndroid Build Coastguard Worker             uids->erase(it);
1665*ec779b8eSAndroid Build Coastguard Worker         }
1666*ec779b8eSAndroid Build Coastguard Worker     } else if (insert && (state == ActivityManager::PROCESS_STATE_UNKNOWN)) {
1667*ec779b8eSAndroid Build Coastguard Worker         uids->insert(std::pair<uid_t, std::pair<bool, int>>(uid,
1668*ec779b8eSAndroid Build Coastguard Worker                                       std::pair<bool, int>(active, state)));
1669*ec779b8eSAndroid Build Coastguard Worker     }
1670*ec779b8eSAndroid Build Coastguard Worker }
1671*ec779b8eSAndroid Build Coastguard Worker 
isA11yOnTop()1672*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::UidPolicy::isA11yOnTop() {
1673*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mMutex);
1674*ec779b8eSAndroid Build Coastguard Worker     for (const auto &uid : mCachedUids) {
1675*ec779b8eSAndroid Build Coastguard Worker         if (!isA11yUid(uid.first)) {
1676*ec779b8eSAndroid Build Coastguard Worker             continue;
1677*ec779b8eSAndroid Build Coastguard Worker         }
1678*ec779b8eSAndroid Build Coastguard Worker         if (uid.second.second >= ActivityManager::PROCESS_STATE_TOP
1679*ec779b8eSAndroid Build Coastguard Worker                 && uid.second.second <= ActivityManager::PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
1680*ec779b8eSAndroid Build Coastguard Worker             return true;
1681*ec779b8eSAndroid Build Coastguard Worker         }
1682*ec779b8eSAndroid Build Coastguard Worker     }
1683*ec779b8eSAndroid Build Coastguard Worker     return false;
1684*ec779b8eSAndroid Build Coastguard Worker }
1685*ec779b8eSAndroid Build Coastguard Worker 
isA11yUid(uid_t uid)1686*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
1687*ec779b8eSAndroid Build Coastguard Worker {
1688*ec779b8eSAndroid Build Coastguard Worker     std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid);
1689*ec779b8eSAndroid Build Coastguard Worker     return it != mA11yUids.end();
1690*ec779b8eSAndroid Build Coastguard Worker }
1691*ec779b8eSAndroid Build Coastguard Worker 
setAssistantUids(const std::vector<uid_t> & uids)1692*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::setAssistantUids(const std::vector<uid_t>& uids) {
1693*ec779b8eSAndroid Build Coastguard Worker     mAssistantUids.clear();
1694*ec779b8eSAndroid Build Coastguard Worker     mAssistantUids = uids;
1695*ec779b8eSAndroid Build Coastguard Worker }
1696*ec779b8eSAndroid Build Coastguard Worker 
isAssistantUid(uid_t uid)1697*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::UidPolicy::isAssistantUid(uid_t uid)
1698*ec779b8eSAndroid Build Coastguard Worker {
1699*ec779b8eSAndroid Build Coastguard Worker     std::vector<uid_t>::iterator it = find(mAssistantUids.begin(), mAssistantUids.end(), uid);
1700*ec779b8eSAndroid Build Coastguard Worker     return it != mAssistantUids.end();
1701*ec779b8eSAndroid Build Coastguard Worker }
1702*ec779b8eSAndroid Build Coastguard Worker 
setActiveAssistantUids(const std::vector<uid_t> & activeUids)1703*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::setActiveAssistantUids(const std::vector<uid_t>& activeUids) {
1704*ec779b8eSAndroid Build Coastguard Worker     mActiveAssistantUids = activeUids;
1705*ec779b8eSAndroid Build Coastguard Worker }
1706*ec779b8eSAndroid Build Coastguard Worker 
isActiveAssistantUid(uid_t uid)1707*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::UidPolicy::isActiveAssistantUid(uid_t uid)
1708*ec779b8eSAndroid Build Coastguard Worker {
1709*ec779b8eSAndroid Build Coastguard Worker     std::vector<uid_t>::iterator it = find(mActiveAssistantUids.begin(),
1710*ec779b8eSAndroid Build Coastguard Worker             mActiveAssistantUids.end(), uid);
1711*ec779b8eSAndroid Build Coastguard Worker     return it != mActiveAssistantUids.end();
1712*ec779b8eSAndroid Build Coastguard Worker }
1713*ec779b8eSAndroid Build Coastguard Worker 
dumpInternals(int fd)1714*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::UidPolicy::dumpInternals(int fd) {
1715*ec779b8eSAndroid Build Coastguard Worker     const size_t SIZE = 256;
1716*ec779b8eSAndroid Build Coastguard Worker     char buffer[SIZE];
1717*ec779b8eSAndroid Build Coastguard Worker     String8 result;
1718*ec779b8eSAndroid Build Coastguard Worker     auto appendUidsToResult = [&](const char* title, const std::vector<uid_t> &uids) {
1719*ec779b8eSAndroid Build Coastguard Worker         snprintf(buffer, SIZE, "\t%s: \n", title);
1720*ec779b8eSAndroid Build Coastguard Worker         result.append(buffer);
1721*ec779b8eSAndroid Build Coastguard Worker         int counter = 0;
1722*ec779b8eSAndroid Build Coastguard Worker         if (uids.empty()) {
1723*ec779b8eSAndroid Build Coastguard Worker             snprintf(buffer, SIZE, "\t\tNo UIDs present.\n");
1724*ec779b8eSAndroid Build Coastguard Worker             result.append(buffer);
1725*ec779b8eSAndroid Build Coastguard Worker             return;
1726*ec779b8eSAndroid Build Coastguard Worker         }
1727*ec779b8eSAndroid Build Coastguard Worker         for (const auto &uid : uids) {
1728*ec779b8eSAndroid Build Coastguard Worker             snprintf(buffer, SIZE, "\t\tUID[%d]=%d\n", counter++, uid);
1729*ec779b8eSAndroid Build Coastguard Worker             result.append(buffer);
1730*ec779b8eSAndroid Build Coastguard Worker         }
1731*ec779b8eSAndroid Build Coastguard Worker     };
1732*ec779b8eSAndroid Build Coastguard Worker 
1733*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "UID Policy:\n");
1734*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
1735*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "\tmObserverRegistered=%s\n",(mObserverRegistered ? "True":"False"));
1736*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
1737*ec779b8eSAndroid Build Coastguard Worker 
1738*ec779b8eSAndroid Build Coastguard Worker     appendUidsToResult("Assistants UIDs", mAssistantUids);
1739*ec779b8eSAndroid Build Coastguard Worker     appendUidsToResult("Active Assistants UIDs", mActiveAssistantUids);
1740*ec779b8eSAndroid Build Coastguard Worker 
1741*ec779b8eSAndroid Build Coastguard Worker     appendUidsToResult("Accessibility UIDs", mA11yUids);
1742*ec779b8eSAndroid Build Coastguard Worker 
1743*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "\tInput Method Service UID=%d\n", mCurrentImeUid);
1744*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
1745*ec779b8eSAndroid Build Coastguard Worker 
1746*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "\tIs RTT Enabled: %s\n", (mRttEnabled ? "True":"False"));
1747*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
1748*ec779b8eSAndroid Build Coastguard Worker 
1749*ec779b8eSAndroid Build Coastguard Worker     write(fd, result.c_str(), result.size());
1750*ec779b8eSAndroid Build Coastguard Worker }
1751*ec779b8eSAndroid Build Coastguard Worker 
1752*ec779b8eSAndroid Build Coastguard Worker // -----------  AudioPolicyService::SensorPrivacyService implementation ----------
registerSelf()1753*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
1754*ec779b8eSAndroid Build Coastguard Worker     SensorPrivacyManager spm;
1755*ec779b8eSAndroid Build Coastguard Worker     mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
1756*ec779b8eSAndroid Build Coastguard Worker     spm.addSensorPrivacyListener(this);
1757*ec779b8eSAndroid Build Coastguard Worker }
1758*ec779b8eSAndroid Build Coastguard Worker 
unregisterSelf()1759*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
1760*ec779b8eSAndroid Build Coastguard Worker     SensorPrivacyManager spm;
1761*ec779b8eSAndroid Build Coastguard Worker     spm.removeSensorPrivacyListener(this);
1762*ec779b8eSAndroid Build Coastguard Worker }
1763*ec779b8eSAndroid Build Coastguard Worker 
isSensorPrivacyEnabled()1764*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
1765*ec779b8eSAndroid Build Coastguard Worker     return mSensorPrivacyEnabled;
1766*ec779b8eSAndroid Build Coastguard Worker }
1767*ec779b8eSAndroid Build Coastguard Worker 
onSensorPrivacyChanged(int toggleType __unused,int sensor __unused,bool enabled)1768*ec779b8eSAndroid Build Coastguard Worker binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(
1769*ec779b8eSAndroid Build Coastguard Worker     int toggleType __unused, int sensor __unused, bool enabled) {
1770*ec779b8eSAndroid Build Coastguard Worker     mSensorPrivacyEnabled = enabled;
1771*ec779b8eSAndroid Build Coastguard Worker     sp<AudioPolicyService> service = mService.promote();
1772*ec779b8eSAndroid Build Coastguard Worker     if (service != nullptr) {
1773*ec779b8eSAndroid Build Coastguard Worker         service->updateUidStates();
1774*ec779b8eSAndroid Build Coastguard Worker     }
1775*ec779b8eSAndroid Build Coastguard Worker     return binder::Status::ok();
1776*ec779b8eSAndroid Build Coastguard Worker }
1777*ec779b8eSAndroid Build Coastguard Worker 
1778*ec779b8eSAndroid Build Coastguard Worker // -----------  AudioPolicyService::AudioCommandThread implementation ----------
1779*ec779b8eSAndroid Build Coastguard Worker 
AudioCommandThread(String8 name,const wp<AudioPolicyService> & service)1780*ec779b8eSAndroid Build Coastguard Worker AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
1781*ec779b8eSAndroid Build Coastguard Worker                                                            const wp<AudioPolicyService>& service)
1782*ec779b8eSAndroid Build Coastguard Worker     : Thread(false), mName(name), mService(service)
1783*ec779b8eSAndroid Build Coastguard Worker {
1784*ec779b8eSAndroid Build Coastguard Worker }
1785*ec779b8eSAndroid Build Coastguard Worker 
1786*ec779b8eSAndroid Build Coastguard Worker 
~AudioCommandThread()1787*ec779b8eSAndroid Build Coastguard Worker AudioPolicyService::AudioCommandThread::~AudioCommandThread()
1788*ec779b8eSAndroid Build Coastguard Worker {
1789*ec779b8eSAndroid Build Coastguard Worker     if (!mAudioCommands.isEmpty()) {
1790*ec779b8eSAndroid Build Coastguard Worker         release_wake_lock(mName.c_str());
1791*ec779b8eSAndroid Build Coastguard Worker     }
1792*ec779b8eSAndroid Build Coastguard Worker     mAudioCommands.clear();
1793*ec779b8eSAndroid Build Coastguard Worker }
1794*ec779b8eSAndroid Build Coastguard Worker 
onFirstRef()1795*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::onFirstRef()
1796*ec779b8eSAndroid Build Coastguard Worker {
1797*ec779b8eSAndroid Build Coastguard Worker     run(mName.c_str(), ANDROID_PRIORITY_AUDIO);
1798*ec779b8eSAndroid Build Coastguard Worker }
1799*ec779b8eSAndroid Build Coastguard Worker 
threadLoop()1800*ec779b8eSAndroid Build Coastguard Worker bool AudioPolicyService::AudioCommandThread::threadLoop()
1801*ec779b8eSAndroid Build Coastguard Worker {
1802*ec779b8eSAndroid Build Coastguard Worker     nsecs_t waitTime = -1;
1803*ec779b8eSAndroid Build Coastguard Worker 
1804*ec779b8eSAndroid Build Coastguard Worker     audio_utils::unique_lock ul(mMutex);
1805*ec779b8eSAndroid Build Coastguard Worker     while (!exitPending())
1806*ec779b8eSAndroid Build Coastguard Worker     {
1807*ec779b8eSAndroid Build Coastguard Worker         sp<AudioPolicyService> svc;
1808*ec779b8eSAndroid Build Coastguard Worker         int numTimesBecameEmpty = 0;
1809*ec779b8eSAndroid Build Coastguard Worker         while (!mAudioCommands.isEmpty() && !exitPending()) {
1810*ec779b8eSAndroid Build Coastguard Worker             nsecs_t curTime = systemTime();
1811*ec779b8eSAndroid Build Coastguard Worker             // commands are sorted by increasing time stamp: execute them from index 0 and up
1812*ec779b8eSAndroid Build Coastguard Worker             if (mAudioCommands[0]->mTime <= curTime) {
1813*ec779b8eSAndroid Build Coastguard Worker                 sp<AudioCommand> command = mAudioCommands[0];
1814*ec779b8eSAndroid Build Coastguard Worker                 mAudioCommands.removeAt(0);
1815*ec779b8eSAndroid Build Coastguard Worker                 if (mAudioCommands.isEmpty()) {
1816*ec779b8eSAndroid Build Coastguard Worker                   ++numTimesBecameEmpty;
1817*ec779b8eSAndroid Build Coastguard Worker                 }
1818*ec779b8eSAndroid Build Coastguard Worker                 mLastCommand = command;
1819*ec779b8eSAndroid Build Coastguard Worker                 status_t createAudioPatchStatus;
1820*ec779b8eSAndroid Build Coastguard Worker 
1821*ec779b8eSAndroid Build Coastguard Worker                 switch (command->mCommand) {
1822*ec779b8eSAndroid Build Coastguard Worker                 case SET_VOLUME: {
1823*ec779b8eSAndroid Build Coastguard Worker                     VolumeData *data = (VolumeData *)command->mParam.get();
1824*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing set volume stream %d, \
1825*ec779b8eSAndroid Build Coastguard Worker                             volume %f, output %d", data->mStream, data->mVolume, data->mIO);
1826*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1827*ec779b8eSAndroid Build Coastguard Worker                     command->mStatus = AudioSystem::setStreamVolume(data->mStream,
1828*ec779b8eSAndroid Build Coastguard Worker                                                                     data->mVolume,
1829*ec779b8eSAndroid Build Coastguard Worker                                                                     data->mIsMuted,
1830*ec779b8eSAndroid Build Coastguard Worker                                                                     data->mIO);
1831*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1832*ec779b8eSAndroid Build Coastguard Worker                     }break;
1833*ec779b8eSAndroid Build Coastguard Worker                 case SET_PORTS_VOLUME: {
1834*ec779b8eSAndroid Build Coastguard Worker                     VolumePortsData *data = (VolumePortsData *)command->mParam.get();
1835*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing set volume Ports %s volume %f, \
1836*ec779b8eSAndroid Build Coastguard Worker                             output %d", data->dumpPorts().c_str(), data->mVolume, data->mIO);
1837*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1838*ec779b8eSAndroid Build Coastguard Worker                     command->mStatus = AudioSystem::setPortsVolume(data->mPorts,
1839*ec779b8eSAndroid Build Coastguard Worker                                                                    data->mVolume,
1840*ec779b8eSAndroid Build Coastguard Worker                                                                    data->mMuted,
1841*ec779b8eSAndroid Build Coastguard Worker                                                                    data->mIO);
1842*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1843*ec779b8eSAndroid Build Coastguard Worker                     } break;
1844*ec779b8eSAndroid Build Coastguard Worker                 case SET_PARAMETERS: {
1845*ec779b8eSAndroid Build Coastguard Worker                     ParametersData *data = (ParametersData *)command->mParam.get();
1846*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
1847*ec779b8eSAndroid Build Coastguard Worker                             data->mKeyValuePairs.c_str(), data->mIO);
1848*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1849*ec779b8eSAndroid Build Coastguard Worker                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
1850*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1851*ec779b8eSAndroid Build Coastguard Worker                     }break;
1852*ec779b8eSAndroid Build Coastguard Worker                 case SET_VOICE_VOLUME: {
1853*ec779b8eSAndroid Build Coastguard Worker                     VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
1854*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing set voice volume volume %f",
1855*ec779b8eSAndroid Build Coastguard Worker                             data->mVolume);
1856*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1857*ec779b8eSAndroid Build Coastguard Worker                     command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
1858*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1859*ec779b8eSAndroid Build Coastguard Worker                     }break;
1860*ec779b8eSAndroid Build Coastguard Worker                 case STOP_OUTPUT: {
1861*ec779b8eSAndroid Build Coastguard Worker                     StopOutputData *data = (StopOutputData *)command->mParam.get();
1862*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing stop output portId %d",
1863*ec779b8eSAndroid Build Coastguard Worker                             data->mPortId);
1864*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1865*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1866*ec779b8eSAndroid Build Coastguard Worker                         break;
1867*ec779b8eSAndroid Build Coastguard Worker                     }
1868*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1869*ec779b8eSAndroid Build Coastguard Worker                     svc->doStopOutput(data->mPortId);
1870*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1871*ec779b8eSAndroid Build Coastguard Worker                     }break;
1872*ec779b8eSAndroid Build Coastguard Worker                 case RELEASE_OUTPUT: {
1873*ec779b8eSAndroid Build Coastguard Worker                     ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
1874*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing release output portId %d",
1875*ec779b8eSAndroid Build Coastguard Worker                             data->mPortId);
1876*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1877*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1878*ec779b8eSAndroid Build Coastguard Worker                         break;
1879*ec779b8eSAndroid Build Coastguard Worker                     }
1880*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1881*ec779b8eSAndroid Build Coastguard Worker                     svc->doReleaseOutput(data->mPortId);
1882*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1883*ec779b8eSAndroid Build Coastguard Worker                     }break;
1884*ec779b8eSAndroid Build Coastguard Worker                 case CREATE_AUDIO_PATCH: {
1885*ec779b8eSAndroid Build Coastguard Worker                     CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
1886*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing create audio patch");
1887*ec779b8eSAndroid Build Coastguard Worker                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1888*ec779b8eSAndroid Build Coastguard Worker                     if (af == 0) {
1889*ec779b8eSAndroid Build Coastguard Worker                         createAudioPatchStatus = PERMISSION_DENIED;
1890*ec779b8eSAndroid Build Coastguard Worker                     } else {
1891*ec779b8eSAndroid Build Coastguard Worker                         ul.unlock();
1892*ec779b8eSAndroid Build Coastguard Worker                         createAudioPatchStatus = af->createAudioPatch(&data->mPatch,
1893*ec779b8eSAndroid Build Coastguard Worker                                                                       &data->mHandle);
1894*ec779b8eSAndroid Build Coastguard Worker                         ul.lock();
1895*ec779b8eSAndroid Build Coastguard Worker                     }
1896*ec779b8eSAndroid Build Coastguard Worker                     } break;
1897*ec779b8eSAndroid Build Coastguard Worker                 case RELEASE_AUDIO_PATCH: {
1898*ec779b8eSAndroid Build Coastguard Worker                     ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
1899*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing release audio patch");
1900*ec779b8eSAndroid Build Coastguard Worker                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1901*ec779b8eSAndroid Build Coastguard Worker                     if (af == 0) {
1902*ec779b8eSAndroid Build Coastguard Worker                         command->mStatus = PERMISSION_DENIED;
1903*ec779b8eSAndroid Build Coastguard Worker                     } else {
1904*ec779b8eSAndroid Build Coastguard Worker                         ul.unlock();
1905*ec779b8eSAndroid Build Coastguard Worker                         command->mStatus = af->releaseAudioPatch(data->mHandle);
1906*ec779b8eSAndroid Build Coastguard Worker                         ul.lock();
1907*ec779b8eSAndroid Build Coastguard Worker                     }
1908*ec779b8eSAndroid Build Coastguard Worker                     } break;
1909*ec779b8eSAndroid Build Coastguard Worker                 case UPDATE_AUDIOPORT_LIST: {
1910*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing update audio port list");
1911*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1912*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1913*ec779b8eSAndroid Build Coastguard Worker                         break;
1914*ec779b8eSAndroid Build Coastguard Worker                     }
1915*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1916*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnAudioPortListUpdate();
1917*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1918*ec779b8eSAndroid Build Coastguard Worker                     }break;
1919*ec779b8eSAndroid Build Coastguard Worker                 case UPDATE_AUDIOPATCH_LIST: {
1920*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing update audio patch list");
1921*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1922*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1923*ec779b8eSAndroid Build Coastguard Worker                         break;
1924*ec779b8eSAndroid Build Coastguard Worker                     }
1925*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1926*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnAudioPatchListUpdate();
1927*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1928*ec779b8eSAndroid Build Coastguard Worker                     }break;
1929*ec779b8eSAndroid Build Coastguard Worker                 case CHANGED_AUDIOVOLUMEGROUP: {
1930*ec779b8eSAndroid Build Coastguard Worker                     AudioVolumeGroupData *data =
1931*ec779b8eSAndroid Build Coastguard Worker                             static_cast<AudioVolumeGroupData *>(command->mParam.get());
1932*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing update audio volume group");
1933*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1934*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1935*ec779b8eSAndroid Build Coastguard Worker                         break;
1936*ec779b8eSAndroid Build Coastguard Worker                     }
1937*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1938*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnAudioVolumeGroupChanged(data->mGroup, data->mFlags);
1939*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1940*ec779b8eSAndroid Build Coastguard Worker                     }break;
1941*ec779b8eSAndroid Build Coastguard Worker                 case SET_AUDIOPORT_CONFIG: {
1942*ec779b8eSAndroid Build Coastguard Worker                     SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
1943*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing set port config");
1944*ec779b8eSAndroid Build Coastguard Worker                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1945*ec779b8eSAndroid Build Coastguard Worker                     if (af == 0) {
1946*ec779b8eSAndroid Build Coastguard Worker                         command->mStatus = PERMISSION_DENIED;
1947*ec779b8eSAndroid Build Coastguard Worker                     } else {
1948*ec779b8eSAndroid Build Coastguard Worker                         ul.unlock();
1949*ec779b8eSAndroid Build Coastguard Worker                         command->mStatus = af->setAudioPortConfig(&data->mConfig);
1950*ec779b8eSAndroid Build Coastguard Worker                         ul.lock();
1951*ec779b8eSAndroid Build Coastguard Worker                     }
1952*ec779b8eSAndroid Build Coastguard Worker                     } break;
1953*ec779b8eSAndroid Build Coastguard Worker                 case DYN_POLICY_MIX_STATE_UPDATE: {
1954*ec779b8eSAndroid Build Coastguard Worker                     DynPolicyMixStateUpdateData *data =
1955*ec779b8eSAndroid Build Coastguard Worker                             (DynPolicyMixStateUpdateData *)command->mParam.get();
1956*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
1957*ec779b8eSAndroid Build Coastguard Worker                             data->mRegId.c_str(), data->mState);
1958*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1959*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1960*ec779b8eSAndroid Build Coastguard Worker                         break;
1961*ec779b8eSAndroid Build Coastguard Worker                     }
1962*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1963*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
1964*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1965*ec779b8eSAndroid Build Coastguard Worker                     } break;
1966*ec779b8eSAndroid Build Coastguard Worker                 case RECORDING_CONFIGURATION_UPDATE: {
1967*ec779b8eSAndroid Build Coastguard Worker                     RecordingConfigurationUpdateData *data =
1968*ec779b8eSAndroid Build Coastguard Worker                             (RecordingConfigurationUpdateData *)command->mParam.get();
1969*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing recording configuration update");
1970*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1971*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1972*ec779b8eSAndroid Build Coastguard Worker                         break;
1973*ec779b8eSAndroid Build Coastguard Worker                     }
1974*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1975*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
1976*ec779b8eSAndroid Build Coastguard Worker                             &data->mClientConfig, data->mClientEffects,
1977*ec779b8eSAndroid Build Coastguard Worker                             &data->mDeviceConfig, data->mEffects,
1978*ec779b8eSAndroid Build Coastguard Worker                             data->mPatchHandle, data->mSource);
1979*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
1980*ec779b8eSAndroid Build Coastguard Worker                     } break;
1981*ec779b8eSAndroid Build Coastguard Worker                 case SET_EFFECT_SUSPENDED: {
1982*ec779b8eSAndroid Build Coastguard Worker                     SetEffectSuspendedData *data = (SetEffectSuspendedData *)command->mParam.get();
1983*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing set effect suspended");
1984*ec779b8eSAndroid Build Coastguard Worker                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1985*ec779b8eSAndroid Build Coastguard Worker                     if (af != 0) {
1986*ec779b8eSAndroid Build Coastguard Worker                         ul.unlock();
1987*ec779b8eSAndroid Build Coastguard Worker                         af->setEffectSuspended(data->mEffectId, data->mSessionId, data->mSuspended);
1988*ec779b8eSAndroid Build Coastguard Worker                         ul.lock();
1989*ec779b8eSAndroid Build Coastguard Worker                     }
1990*ec779b8eSAndroid Build Coastguard Worker                     } break;
1991*ec779b8eSAndroid Build Coastguard Worker                 case AUDIO_MODULES_UPDATE: {
1992*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing audio modules update");
1993*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
1994*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
1995*ec779b8eSAndroid Build Coastguard Worker                         break;
1996*ec779b8eSAndroid Build Coastguard Worker                     }
1997*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
1998*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnNewAudioModulesAvailable();
1999*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
2000*ec779b8eSAndroid Build Coastguard Worker                     } break;
2001*ec779b8eSAndroid Build Coastguard Worker                 case ROUTING_UPDATED: {
2002*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing routing update");
2003*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
2004*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
2005*ec779b8eSAndroid Build Coastguard Worker                         break;
2006*ec779b8eSAndroid Build Coastguard Worker                     }
2007*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
2008*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnRoutingUpdated();
2009*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
2010*ec779b8eSAndroid Build Coastguard Worker                     } break;
2011*ec779b8eSAndroid Build Coastguard Worker 
2012*ec779b8eSAndroid Build Coastguard Worker                 case UPDATE_UID_STATES: {
2013*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing updateUID states");
2014*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
2015*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
2016*ec779b8eSAndroid Build Coastguard Worker                         break;
2017*ec779b8eSAndroid Build Coastguard Worker                     }
2018*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
2019*ec779b8eSAndroid Build Coastguard Worker                     svc->updateUidStates();
2020*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
2021*ec779b8eSAndroid Build Coastguard Worker                     } break;
2022*ec779b8eSAndroid Build Coastguard Worker 
2023*ec779b8eSAndroid Build Coastguard Worker                 case CHECK_SPATIALIZER_OUTPUT: {
2024*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing check spatializer");
2025*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
2026*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
2027*ec779b8eSAndroid Build Coastguard Worker                         break;
2028*ec779b8eSAndroid Build Coastguard Worker                     }
2029*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
2030*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnCheckSpatializer();
2031*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
2032*ec779b8eSAndroid Build Coastguard Worker                     } break;
2033*ec779b8eSAndroid Build Coastguard Worker 
2034*ec779b8eSAndroid Build Coastguard Worker                 case UPDATE_ACTIVE_SPATIALIZER_TRACKS: {
2035*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing update spatializer tracks");
2036*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
2037*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
2038*ec779b8eSAndroid Build Coastguard Worker                         break;
2039*ec779b8eSAndroid Build Coastguard Worker                     }
2040*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
2041*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnUpdateActiveSpatializerTracks();
2042*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
2043*ec779b8eSAndroid Build Coastguard Worker                     } break;
2044*ec779b8eSAndroid Build Coastguard Worker 
2045*ec779b8eSAndroid Build Coastguard Worker                 case VOL_RANGE_INIT_REQUEST: {
2046*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("AudioCommandThread() processing volume range init request");
2047*ec779b8eSAndroid Build Coastguard Worker                     svc = mService.promote();
2048*ec779b8eSAndroid Build Coastguard Worker                     if (svc == 0) {
2049*ec779b8eSAndroid Build Coastguard Worker                         break;
2050*ec779b8eSAndroid Build Coastguard Worker                     }
2051*ec779b8eSAndroid Build Coastguard Worker                     ul.unlock();
2052*ec779b8eSAndroid Build Coastguard Worker                     svc->doOnVolumeRangeInitRequest();
2053*ec779b8eSAndroid Build Coastguard Worker                     ul.lock();
2054*ec779b8eSAndroid Build Coastguard Worker                     } break;
2055*ec779b8eSAndroid Build Coastguard Worker 
2056*ec779b8eSAndroid Build Coastguard Worker                 default:
2057*ec779b8eSAndroid Build Coastguard Worker                     ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
2058*ec779b8eSAndroid Build Coastguard Worker                 }
2059*ec779b8eSAndroid Build Coastguard Worker                 {
2060*ec779b8eSAndroid Build Coastguard Worker                     audio_utils::lock_guard _l(command->mMutex);
2061*ec779b8eSAndroid Build Coastguard Worker                     if (command->mWaitStatus) {
2062*ec779b8eSAndroid Build Coastguard Worker                         if (command->mCommand == CREATE_AUDIO_PATCH) {
2063*ec779b8eSAndroid Build Coastguard Worker                             command->mStatus = createAudioPatchStatus;
2064*ec779b8eSAndroid Build Coastguard Worker                         }
2065*ec779b8eSAndroid Build Coastguard Worker                         command->mWaitStatus = false;
2066*ec779b8eSAndroid Build Coastguard Worker                         command->mCond.notify_one();
2067*ec779b8eSAndroid Build Coastguard Worker                     } else if (command->mCommand == CREATE_AUDIO_PATCH &&
2068*ec779b8eSAndroid Build Coastguard Worker                                command->mStatus == TIMED_OUT &&
2069*ec779b8eSAndroid Build Coastguard Worker                                createAudioPatchStatus == NO_ERROR) {
2070*ec779b8eSAndroid Build Coastguard Worker                         // Because of special handling in insertCommand_l() the CREATE_AUDIO_PATCH
2071*ec779b8eSAndroid Build Coastguard Worker                         // command wait status can be only false in case timeout (see TIMED_OUT)
2072*ec779b8eSAndroid Build Coastguard Worker                         // happened.
2073*ec779b8eSAndroid Build Coastguard Worker                         CreateAudioPatchData *createData =
2074*ec779b8eSAndroid Build Coastguard Worker                                 (CreateAudioPatchData *)command->mParam.get();
2075*ec779b8eSAndroid Build Coastguard Worker                         ALOGW("AudioCommandThread() no caller awaiting for handle(%d) after \
2076*ec779b8eSAndroid Build Coastguard Worker                                 processing create audio patch, going to release it",
2077*ec779b8eSAndroid Build Coastguard Worker                                 createData->mHandle);
2078*ec779b8eSAndroid Build Coastguard Worker                         sp<AudioCommand> releaseCommand = new AudioCommand();
2079*ec779b8eSAndroid Build Coastguard Worker                         releaseCommand->mCommand = RELEASE_AUDIO_PATCH;
2080*ec779b8eSAndroid Build Coastguard Worker                         ReleaseAudioPatchData *releaseData = new ReleaseAudioPatchData();
2081*ec779b8eSAndroid Build Coastguard Worker                         releaseData->mHandle = createData->mHandle;
2082*ec779b8eSAndroid Build Coastguard Worker                         releaseCommand->mParam = releaseData;
2083*ec779b8eSAndroid Build Coastguard Worker                         insertCommand_l(releaseCommand, 0);
2084*ec779b8eSAndroid Build Coastguard Worker                     }
2085*ec779b8eSAndroid Build Coastguard Worker                 }
2086*ec779b8eSAndroid Build Coastguard Worker                 waitTime = -1;
2087*ec779b8eSAndroid Build Coastguard Worker                 // release ul before releasing strong reference on the service as
2088*ec779b8eSAndroid Build Coastguard Worker                 // AudioPolicyService destructor calls AudioCommandThread::exit() which
2089*ec779b8eSAndroid Build Coastguard Worker                 // acquires ul.
2090*ec779b8eSAndroid Build Coastguard Worker                 ul.unlock();
2091*ec779b8eSAndroid Build Coastguard Worker                 svc.clear();
2092*ec779b8eSAndroid Build Coastguard Worker                 ul.lock();
2093*ec779b8eSAndroid Build Coastguard Worker             } else {
2094*ec779b8eSAndroid Build Coastguard Worker                 waitTime = mAudioCommands[0]->mTime - curTime;
2095*ec779b8eSAndroid Build Coastguard Worker                 break;
2096*ec779b8eSAndroid Build Coastguard Worker             }
2097*ec779b8eSAndroid Build Coastguard Worker         }
2098*ec779b8eSAndroid Build Coastguard Worker 
2099*ec779b8eSAndroid Build Coastguard Worker         // release delayed commands wake lock as many times as we made the  queue is
2100*ec779b8eSAndroid Build Coastguard Worker         // empty during popping.
2101*ec779b8eSAndroid Build Coastguard Worker         while (numTimesBecameEmpty--) {
2102*ec779b8eSAndroid Build Coastguard Worker             release_wake_lock(mName.c_str());
2103*ec779b8eSAndroid Build Coastguard Worker         }
2104*ec779b8eSAndroid Build Coastguard Worker 
2105*ec779b8eSAndroid Build Coastguard Worker         // At this stage we have either an empty command queue or the first command in the queue
2106*ec779b8eSAndroid Build Coastguard Worker         // has a finite delay. So unless we are exiting it is safe to wait.
2107*ec779b8eSAndroid Build Coastguard Worker         if (!exitPending()) {
2108*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AudioCommandThread() going to sleep");
2109*ec779b8eSAndroid Build Coastguard Worker             if (waitTime == -1) {
2110*ec779b8eSAndroid Build Coastguard Worker                 mWaitWorkCV.wait(ul);
2111*ec779b8eSAndroid Build Coastguard Worker             } else {
2112*ec779b8eSAndroid Build Coastguard Worker                 // discard return value.
2113*ec779b8eSAndroid Build Coastguard Worker                 mWaitWorkCV.wait_for(ul, std::chrono::nanoseconds(waitTime));
2114*ec779b8eSAndroid Build Coastguard Worker             }
2115*ec779b8eSAndroid Build Coastguard Worker         }
2116*ec779b8eSAndroid Build Coastguard Worker     }
2117*ec779b8eSAndroid Build Coastguard Worker     // release delayed commands wake lock before quitting
2118*ec779b8eSAndroid Build Coastguard Worker     if (!mAudioCommands.isEmpty()) {
2119*ec779b8eSAndroid Build Coastguard Worker         release_wake_lock(mName.c_str());
2120*ec779b8eSAndroid Build Coastguard Worker     }
2121*ec779b8eSAndroid Build Coastguard Worker     return false;
2122*ec779b8eSAndroid Build Coastguard Worker }
2123*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd)2124*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::dump(int fd)
2125*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS  // trylock
2126*ec779b8eSAndroid Build Coastguard Worker {
2127*ec779b8eSAndroid Build Coastguard Worker     const size_t SIZE = 256;
2128*ec779b8eSAndroid Build Coastguard Worker     char buffer[SIZE];
2129*ec779b8eSAndroid Build Coastguard Worker     String8 result;
2130*ec779b8eSAndroid Build Coastguard Worker 
2131*ec779b8eSAndroid Build Coastguard Worker     const bool locked = mMutex.try_lock(kDumpLockTimeoutNs);
2132*ec779b8eSAndroid Build Coastguard Worker     if (!locked) {
2133*ec779b8eSAndroid Build Coastguard Worker         String8 result2(kCmdDeadlockedString);
2134*ec779b8eSAndroid Build Coastguard Worker         write(fd, result2.c_str(), result2.size());
2135*ec779b8eSAndroid Build Coastguard Worker     }
2136*ec779b8eSAndroid Build Coastguard Worker 
2137*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "- Commands:\n");
2138*ec779b8eSAndroid Build Coastguard Worker     result = String8(buffer);
2139*ec779b8eSAndroid Build Coastguard Worker     result.append("   Command Time        Wait pParam\n");
2140*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioCommands.size(); i++) {
2141*ec779b8eSAndroid Build Coastguard Worker         mAudioCommands[i]->dump(buffer, SIZE);
2142*ec779b8eSAndroid Build Coastguard Worker         result.append(buffer);
2143*ec779b8eSAndroid Build Coastguard Worker     }
2144*ec779b8eSAndroid Build Coastguard Worker     result.append("  Last Command\n");
2145*ec779b8eSAndroid Build Coastguard Worker     if (mLastCommand != 0) {
2146*ec779b8eSAndroid Build Coastguard Worker         mLastCommand->dump(buffer, SIZE);
2147*ec779b8eSAndroid Build Coastguard Worker         result.append(buffer);
2148*ec779b8eSAndroid Build Coastguard Worker     } else {
2149*ec779b8eSAndroid Build Coastguard Worker         result.append("     none\n");
2150*ec779b8eSAndroid Build Coastguard Worker     }
2151*ec779b8eSAndroid Build Coastguard Worker 
2152*ec779b8eSAndroid Build Coastguard Worker     write(fd, result.c_str(), result.size());
2153*ec779b8eSAndroid Build Coastguard Worker 
2154*ec779b8eSAndroid Build Coastguard Worker     dumpReleaseLock(mMutex, locked);
2155*ec779b8eSAndroid Build Coastguard Worker 
2156*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
2157*ec779b8eSAndroid Build Coastguard Worker }
2158*ec779b8eSAndroid Build Coastguard Worker 
volumeCommand(audio_stream_type_t stream,float volume,bool muted,audio_io_handle_t output,int delayMs)2159*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
2160*ec779b8eSAndroid Build Coastguard Worker                                                                float volume,
2161*ec779b8eSAndroid Build Coastguard Worker                                                                bool muted,
2162*ec779b8eSAndroid Build Coastguard Worker                                                                audio_io_handle_t output,
2163*ec779b8eSAndroid Build Coastguard Worker                                                                int delayMs)
2164*ec779b8eSAndroid Build Coastguard Worker {
2165*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2166*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = SET_VOLUME;
2167*ec779b8eSAndroid Build Coastguard Worker     sp<VolumeData> data = new VolumeData();
2168*ec779b8eSAndroid Build Coastguard Worker     data->mStream = stream;
2169*ec779b8eSAndroid Build Coastguard Worker     data->mVolume = volume;
2170*ec779b8eSAndroid Build Coastguard Worker     data->mIsMuted = muted;
2171*ec779b8eSAndroid Build Coastguard Worker     data->mIO = output;
2172*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2173*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2174*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
2175*ec779b8eSAndroid Build Coastguard Worker             stream, volume, output);
2176*ec779b8eSAndroid Build Coastguard Worker     return sendCommand(command, delayMs);
2177*ec779b8eSAndroid Build Coastguard Worker }
2178*ec779b8eSAndroid Build Coastguard Worker 
volumePortsCommand(const std::vector<audio_port_handle_t> & ports,float volume,bool muted,audio_io_handle_t output,int delayMs)2179*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::volumePortsCommand(
2180*ec779b8eSAndroid Build Coastguard Worker         const std::vector<audio_port_handle_t> &ports, float volume, bool muted,
2181*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output, int delayMs)
2182*ec779b8eSAndroid Build Coastguard Worker {
2183*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2184*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = SET_PORTS_VOLUME;
2185*ec779b8eSAndroid Build Coastguard Worker     sp<VolumePortsData> data = new VolumePortsData();
2186*ec779b8eSAndroid Build Coastguard Worker     data->mPorts = ports;
2187*ec779b8eSAndroid Build Coastguard Worker     data->mVolume = volume;
2188*ec779b8eSAndroid Build Coastguard Worker     data->mMuted = muted;
2189*ec779b8eSAndroid Build Coastguard Worker     data->mIO = output;
2190*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2191*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2192*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding set volume ports %s, volume %f, output %d",
2193*ec779b8eSAndroid Build Coastguard Worker             data->dumpPorts().c_str(), volume, output);
2194*ec779b8eSAndroid Build Coastguard Worker     return sendCommand(command, delayMs);
2195*ec779b8eSAndroid Build Coastguard Worker }
2196*ec779b8eSAndroid Build Coastguard Worker 
parametersCommand(audio_io_handle_t ioHandle,const char * keyValuePairs,int delayMs)2197*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
2198*ec779b8eSAndroid Build Coastguard Worker                                                                    const char *keyValuePairs,
2199*ec779b8eSAndroid Build Coastguard Worker                                                                    int delayMs)
2200*ec779b8eSAndroid Build Coastguard Worker {
2201*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2202*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = SET_PARAMETERS;
2203*ec779b8eSAndroid Build Coastguard Worker     sp<ParametersData> data = new ParametersData();
2204*ec779b8eSAndroid Build Coastguard Worker     data->mIO = ioHandle;
2205*ec779b8eSAndroid Build Coastguard Worker     data->mKeyValuePairs = String8(keyValuePairs);
2206*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2207*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2208*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
2209*ec779b8eSAndroid Build Coastguard Worker             keyValuePairs, ioHandle, delayMs);
2210*ec779b8eSAndroid Build Coastguard Worker     return sendCommand(command, delayMs);
2211*ec779b8eSAndroid Build Coastguard Worker }
2212*ec779b8eSAndroid Build Coastguard Worker 
voiceVolumeCommand(float volume,int delayMs)2213*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
2214*ec779b8eSAndroid Build Coastguard Worker {
2215*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2216*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = SET_VOICE_VOLUME;
2217*ec779b8eSAndroid Build Coastguard Worker     sp<VoiceVolumeData> data = new VoiceVolumeData();
2218*ec779b8eSAndroid Build Coastguard Worker     data->mVolume = volume;
2219*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2220*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2221*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
2222*ec779b8eSAndroid Build Coastguard Worker     return sendCommand(command, delayMs);
2223*ec779b8eSAndroid Build Coastguard Worker }
2224*ec779b8eSAndroid Build Coastguard Worker 
setEffectSuspendedCommand(int effectId,audio_session_t sessionId,bool suspended)2225*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::setEffectSuspendedCommand(int effectId,
2226*ec779b8eSAndroid Build Coastguard Worker                                                                        audio_session_t sessionId,
2227*ec779b8eSAndroid Build Coastguard Worker                                                                        bool suspended)
2228*ec779b8eSAndroid Build Coastguard Worker {
2229*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2230*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = SET_EFFECT_SUSPENDED;
2231*ec779b8eSAndroid Build Coastguard Worker     sp<SetEffectSuspendedData> data = new SetEffectSuspendedData();
2232*ec779b8eSAndroid Build Coastguard Worker     data->mEffectId = effectId;
2233*ec779b8eSAndroid Build Coastguard Worker     data->mSessionId = sessionId;
2234*ec779b8eSAndroid Build Coastguard Worker     data->mSuspended = suspended;
2235*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2236*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding set suspended effectId %d sessionId %d suspended %d",
2237*ec779b8eSAndroid Build Coastguard Worker         effectId, sessionId, suspended);
2238*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2239*ec779b8eSAndroid Build Coastguard Worker }
2240*ec779b8eSAndroid Build Coastguard Worker 
2241*ec779b8eSAndroid Build Coastguard Worker 
stopOutputCommand(audio_port_handle_t portId)2242*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_port_handle_t portId)
2243*ec779b8eSAndroid Build Coastguard Worker {
2244*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2245*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = STOP_OUTPUT;
2246*ec779b8eSAndroid Build Coastguard Worker     sp<StopOutputData> data = new StopOutputData();
2247*ec779b8eSAndroid Build Coastguard Worker     data->mPortId = portId;
2248*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2249*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding stop output portId %d", portId);
2250*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2251*ec779b8eSAndroid Build Coastguard Worker }
2252*ec779b8eSAndroid Build Coastguard Worker 
releaseOutputCommand(audio_port_handle_t portId)2253*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_port_handle_t portId)
2254*ec779b8eSAndroid Build Coastguard Worker {
2255*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2256*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = RELEASE_OUTPUT;
2257*ec779b8eSAndroid Build Coastguard Worker     sp<ReleaseOutputData> data = new ReleaseOutputData();
2258*ec779b8eSAndroid Build Coastguard Worker     data->mPortId = portId;
2259*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2260*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding release output portId %d", portId);
2261*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2262*ec779b8eSAndroid Build Coastguard Worker }
2263*ec779b8eSAndroid Build Coastguard Worker 
createAudioPatchCommand(const struct audio_patch * patch,audio_patch_handle_t * handle,int delayMs)2264*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
2265*ec779b8eSAndroid Build Coastguard Worker                                                 const struct audio_patch *patch,
2266*ec779b8eSAndroid Build Coastguard Worker                                                 audio_patch_handle_t *handle,
2267*ec779b8eSAndroid Build Coastguard Worker                                                 int delayMs)
2268*ec779b8eSAndroid Build Coastguard Worker {
2269*ec779b8eSAndroid Build Coastguard Worker     status_t status = NO_ERROR;
2270*ec779b8eSAndroid Build Coastguard Worker 
2271*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2272*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = CREATE_AUDIO_PATCH;
2273*ec779b8eSAndroid Build Coastguard Worker     CreateAudioPatchData *data = new CreateAudioPatchData();
2274*ec779b8eSAndroid Build Coastguard Worker     data->mPatch = *patch;
2275*ec779b8eSAndroid Build Coastguard Worker     data->mHandle = *handle;
2276*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2277*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2278*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
2279*ec779b8eSAndroid Build Coastguard Worker     status = sendCommand(command, delayMs);
2280*ec779b8eSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
2281*ec779b8eSAndroid Build Coastguard Worker         *handle = data->mHandle;
2282*ec779b8eSAndroid Build Coastguard Worker     }
2283*ec779b8eSAndroid Build Coastguard Worker     return status;
2284*ec779b8eSAndroid Build Coastguard Worker }
2285*ec779b8eSAndroid Build Coastguard Worker 
releaseAudioPatchCommand(audio_patch_handle_t handle,int delayMs)2286*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
2287*ec779b8eSAndroid Build Coastguard Worker                                                  int delayMs)
2288*ec779b8eSAndroid Build Coastguard Worker {
2289*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2290*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = RELEASE_AUDIO_PATCH;
2291*ec779b8eSAndroid Build Coastguard Worker     ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
2292*ec779b8eSAndroid Build Coastguard Worker     data->mHandle = handle;
2293*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2294*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2295*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
2296*ec779b8eSAndroid Build Coastguard Worker     return sendCommand(command, delayMs);
2297*ec779b8eSAndroid Build Coastguard Worker }
2298*ec779b8eSAndroid Build Coastguard Worker 
updateAudioPortListCommand()2299*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
2300*ec779b8eSAndroid Build Coastguard Worker {
2301*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2302*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = UPDATE_AUDIOPORT_LIST;
2303*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding update audio port list");
2304*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2305*ec779b8eSAndroid Build Coastguard Worker }
2306*ec779b8eSAndroid Build Coastguard Worker 
updateUidStatesCommand()2307*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::updateUidStatesCommand()
2308*ec779b8eSAndroid Build Coastguard Worker {
2309*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2310*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = UPDATE_UID_STATES;
2311*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding update UID states");
2312*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2313*ec779b8eSAndroid Build Coastguard Worker }
2314*ec779b8eSAndroid Build Coastguard Worker 
updateAudioPatchListCommand()2315*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
2316*ec779b8eSAndroid Build Coastguard Worker {
2317*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2318*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = UPDATE_AUDIOPATCH_LIST;
2319*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding update audio patch list");
2320*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2321*ec779b8eSAndroid Build Coastguard Worker }
2322*ec779b8eSAndroid Build Coastguard Worker 
changeAudioVolumeGroupCommand(volume_group_t group,int flags)2323*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::changeAudioVolumeGroupCommand(volume_group_t group,
2324*ec779b8eSAndroid Build Coastguard Worker                                                                            int flags)
2325*ec779b8eSAndroid Build Coastguard Worker {
2326*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2327*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = CHANGED_AUDIOVOLUMEGROUP;
2328*ec779b8eSAndroid Build Coastguard Worker     AudioVolumeGroupData *data= new AudioVolumeGroupData();
2329*ec779b8eSAndroid Build Coastguard Worker     data->mGroup = group;
2330*ec779b8eSAndroid Build Coastguard Worker     data->mFlags = flags;
2331*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2332*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding audio volume group changed");
2333*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2334*ec779b8eSAndroid Build Coastguard Worker }
2335*ec779b8eSAndroid Build Coastguard Worker 
setAudioPortConfigCommand(const struct audio_port_config * config,int delayMs)2336*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
2337*ec779b8eSAndroid Build Coastguard Worker                                             const struct audio_port_config *config, int delayMs)
2338*ec779b8eSAndroid Build Coastguard Worker {
2339*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2340*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = SET_AUDIOPORT_CONFIG;
2341*ec779b8eSAndroid Build Coastguard Worker     SetAudioPortConfigData *data = new SetAudioPortConfigData();
2342*ec779b8eSAndroid Build Coastguard Worker     data->mConfig = *config;
2343*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2344*ec779b8eSAndroid Build Coastguard Worker     command->mWaitStatus = true;
2345*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
2346*ec779b8eSAndroid Build Coastguard Worker     return sendCommand(command, delayMs);
2347*ec779b8eSAndroid Build Coastguard Worker }
2348*ec779b8eSAndroid Build Coastguard Worker 
dynamicPolicyMixStateUpdateCommand(const String8 & regId,int32_t state)2349*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
2350*ec779b8eSAndroid Build Coastguard Worker         const String8& regId, int32_t state)
2351*ec779b8eSAndroid Build Coastguard Worker {
2352*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2353*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
2354*ec779b8eSAndroid Build Coastguard Worker     DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
2355*ec779b8eSAndroid Build Coastguard Worker     data->mRegId = regId;
2356*ec779b8eSAndroid Build Coastguard Worker     data->mState = state;
2357*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2358*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
2359*ec779b8eSAndroid Build Coastguard Worker             regId.c_str(), state);
2360*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2361*ec779b8eSAndroid Build Coastguard Worker }
2362*ec779b8eSAndroid Build Coastguard Worker 
recordingConfigurationUpdateCommand(int event,const record_client_info_t * clientInfo,const audio_config_base_t * clientConfig,std::vector<effect_descriptor_t> clientEffects,const audio_config_base_t * deviceConfig,std::vector<effect_descriptor_t> effects,audio_patch_handle_t patchHandle,audio_source_t source)2363*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
2364*ec779b8eSAndroid Build Coastguard Worker                                                 int event,
2365*ec779b8eSAndroid Build Coastguard Worker                                                 const record_client_info_t *clientInfo,
2366*ec779b8eSAndroid Build Coastguard Worker                                                 const audio_config_base_t *clientConfig,
2367*ec779b8eSAndroid Build Coastguard Worker                                                 std::vector<effect_descriptor_t> clientEffects,
2368*ec779b8eSAndroid Build Coastguard Worker                                                 const audio_config_base_t *deviceConfig,
2369*ec779b8eSAndroid Build Coastguard Worker                                                 std::vector<effect_descriptor_t> effects,
2370*ec779b8eSAndroid Build Coastguard Worker                                                 audio_patch_handle_t patchHandle,
2371*ec779b8eSAndroid Build Coastguard Worker                                                 audio_source_t source)
2372*ec779b8eSAndroid Build Coastguard Worker {
2373*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2374*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = RECORDING_CONFIGURATION_UPDATE;
2375*ec779b8eSAndroid Build Coastguard Worker     RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
2376*ec779b8eSAndroid Build Coastguard Worker     data->mEvent = event;
2377*ec779b8eSAndroid Build Coastguard Worker     data->mClientInfo = *clientInfo;
2378*ec779b8eSAndroid Build Coastguard Worker     data->mClientConfig = *clientConfig;
2379*ec779b8eSAndroid Build Coastguard Worker     data->mClientEffects = clientEffects;
2380*ec779b8eSAndroid Build Coastguard Worker     data->mDeviceConfig = *deviceConfig;
2381*ec779b8eSAndroid Build Coastguard Worker     data->mEffects = effects;
2382*ec779b8eSAndroid Build Coastguard Worker     data->mPatchHandle = patchHandle;
2383*ec779b8eSAndroid Build Coastguard Worker     data->mSource = source;
2384*ec779b8eSAndroid Build Coastguard Worker     command->mParam = data;
2385*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
2386*ec779b8eSAndroid Build Coastguard Worker             event, clientInfo->source, clientInfo->uid);
2387*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2388*ec779b8eSAndroid Build Coastguard Worker }
2389*ec779b8eSAndroid Build Coastguard Worker 
audioModulesUpdateCommand()2390*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::audioModulesUpdateCommand()
2391*ec779b8eSAndroid Build Coastguard Worker {
2392*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand> command = new AudioCommand();
2393*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = AUDIO_MODULES_UPDATE;
2394*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2395*ec779b8eSAndroid Build Coastguard Worker }
2396*ec779b8eSAndroid Build Coastguard Worker 
routingChangedCommand()2397*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::routingChangedCommand()
2398*ec779b8eSAndroid Build Coastguard Worker {
2399*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2400*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = ROUTING_UPDATED;
2401*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding routing update");
2402*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2403*ec779b8eSAndroid Build Coastguard Worker }
2404*ec779b8eSAndroid Build Coastguard Worker 
checkSpatializerCommand()2405*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
2406*ec779b8eSAndroid Build Coastguard Worker {
2407*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2408*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = CHECK_SPATIALIZER_OUTPUT;
2409*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding check spatializer");
2410*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2411*ec779b8eSAndroid Build Coastguard Worker }
2412*ec779b8eSAndroid Build Coastguard Worker 
updateActiveSpatializerTracksCommand()2413*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::updateActiveSpatializerTracksCommand()
2414*ec779b8eSAndroid Build Coastguard Worker {
2415*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2416*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = UPDATE_ACTIVE_SPATIALIZER_TRACKS;
2417*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding update active spatializer tracks");
2418*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2419*ec779b8eSAndroid Build Coastguard Worker }
2420*ec779b8eSAndroid Build Coastguard Worker 
volRangeInitReqCommand()2421*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::volRangeInitReqCommand()
2422*ec779b8eSAndroid Build Coastguard Worker {
2423*ec779b8eSAndroid Build Coastguard Worker     sp<AudioCommand>command = new AudioCommand();
2424*ec779b8eSAndroid Build Coastguard Worker     command->mCommand = VOL_RANGE_INIT_REQUEST;
2425*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread() adding volume range init request");
2426*ec779b8eSAndroid Build Coastguard Worker     sendCommand(command);
2427*ec779b8eSAndroid Build Coastguard Worker }
2428*ec779b8eSAndroid Build Coastguard Worker 
sendCommand(sp<AudioCommand> & command,int delayMs)2429*ec779b8eSAndroid Build Coastguard Worker status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
2430*ec779b8eSAndroid Build Coastguard Worker {
2431*ec779b8eSAndroid Build Coastguard Worker     {
2432*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
2433*ec779b8eSAndroid Build Coastguard Worker         insertCommand_l(command, delayMs);
2434*ec779b8eSAndroid Build Coastguard Worker         mWaitWorkCV.notify_one();
2435*ec779b8eSAndroid Build Coastguard Worker     }
2436*ec779b8eSAndroid Build Coastguard Worker     audio_utils::unique_lock ul(command->mMutex);
2437*ec779b8eSAndroid Build Coastguard Worker     while (command->mWaitStatus) {
2438*ec779b8eSAndroid Build Coastguard Worker         nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
2439*ec779b8eSAndroid Build Coastguard Worker         if (command->mCond.wait_for(
2440*ec779b8eSAndroid Build Coastguard Worker                 ul, std::chrono::nanoseconds(timeOutNs), getTid()) == std::cv_status::timeout) {
2441*ec779b8eSAndroid Build Coastguard Worker             command->mStatus = TIMED_OUT;
2442*ec779b8eSAndroid Build Coastguard Worker             command->mWaitStatus = false;
2443*ec779b8eSAndroid Build Coastguard Worker         }
2444*ec779b8eSAndroid Build Coastguard Worker     }
2445*ec779b8eSAndroid Build Coastguard Worker     return command->mStatus;
2446*ec779b8eSAndroid Build Coastguard Worker }
2447*ec779b8eSAndroid Build Coastguard Worker 
2448*ec779b8eSAndroid Build Coastguard Worker // insertCommand_l() must be called with mMutex held
insertCommand_l(sp<AudioCommand> & command,int delayMs)2449*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
2450*ec779b8eSAndroid Build Coastguard Worker {
2451*ec779b8eSAndroid Build Coastguard Worker     ssize_t i;  // not size_t because i will count down to -1
2452*ec779b8eSAndroid Build Coastguard Worker     Vector < sp<AudioCommand> > removedCommands;
2453*ec779b8eSAndroid Build Coastguard Worker     command->mTime = systemTime() + milliseconds(delayMs);
2454*ec779b8eSAndroid Build Coastguard Worker 
2455*ec779b8eSAndroid Build Coastguard Worker     // acquire wake lock to make sure delayed commands are processed
2456*ec779b8eSAndroid Build Coastguard Worker     if (mAudioCommands.isEmpty()) {
2457*ec779b8eSAndroid Build Coastguard Worker         acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.c_str());
2458*ec779b8eSAndroid Build Coastguard Worker     }
2459*ec779b8eSAndroid Build Coastguard Worker 
2460*ec779b8eSAndroid Build Coastguard Worker     // check same pending commands with later time stamps and eliminate them
2461*ec779b8eSAndroid Build Coastguard Worker     for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
2462*ec779b8eSAndroid Build Coastguard Worker         sp<AudioCommand> command2 = mAudioCommands[i];
2463*ec779b8eSAndroid Build Coastguard Worker         // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
2464*ec779b8eSAndroid Build Coastguard Worker         if (command2->mTime <= command->mTime) break;
2465*ec779b8eSAndroid Build Coastguard Worker 
2466*ec779b8eSAndroid Build Coastguard Worker         // create audio patch or release audio patch commands are equivalent
2467*ec779b8eSAndroid Build Coastguard Worker         // with regard to filtering
2468*ec779b8eSAndroid Build Coastguard Worker         if ((command->mCommand == CREATE_AUDIO_PATCH) ||
2469*ec779b8eSAndroid Build Coastguard Worker                 (command->mCommand == RELEASE_AUDIO_PATCH)) {
2470*ec779b8eSAndroid Build Coastguard Worker             if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
2471*ec779b8eSAndroid Build Coastguard Worker                     (command2->mCommand != RELEASE_AUDIO_PATCH)) {
2472*ec779b8eSAndroid Build Coastguard Worker                 continue;
2473*ec779b8eSAndroid Build Coastguard Worker             }
2474*ec779b8eSAndroid Build Coastguard Worker         } else if (command2->mCommand != command->mCommand) continue;
2475*ec779b8eSAndroid Build Coastguard Worker 
2476*ec779b8eSAndroid Build Coastguard Worker         switch (command->mCommand) {
2477*ec779b8eSAndroid Build Coastguard Worker         case SET_PARAMETERS: {
2478*ec779b8eSAndroid Build Coastguard Worker             ParametersData *data = (ParametersData *)command->mParam.get();
2479*ec779b8eSAndroid Build Coastguard Worker             ParametersData *data2 = (ParametersData *)command2->mParam.get();
2480*ec779b8eSAndroid Build Coastguard Worker             if (data->mIO != data2->mIO) break;
2481*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Comparing parameter command %s to new command %s",
2482*ec779b8eSAndroid Build Coastguard Worker                     data2->mKeyValuePairs.c_str(), data->mKeyValuePairs.c_str());
2483*ec779b8eSAndroid Build Coastguard Worker             AudioParameter param = AudioParameter(data->mKeyValuePairs);
2484*ec779b8eSAndroid Build Coastguard Worker             AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
2485*ec779b8eSAndroid Build Coastguard Worker             for (size_t j = 0; j < param.size(); j++) {
2486*ec779b8eSAndroid Build Coastguard Worker                 String8 key;
2487*ec779b8eSAndroid Build Coastguard Worker                 String8 value;
2488*ec779b8eSAndroid Build Coastguard Worker                 param.getAt(j, key, value);
2489*ec779b8eSAndroid Build Coastguard Worker                 for (size_t k = 0; k < param2.size(); k++) {
2490*ec779b8eSAndroid Build Coastguard Worker                     String8 key2;
2491*ec779b8eSAndroid Build Coastguard Worker                     String8 value2;
2492*ec779b8eSAndroid Build Coastguard Worker                     param2.getAt(k, key2, value2);
2493*ec779b8eSAndroid Build Coastguard Worker                     if (key2 == key) {
2494*ec779b8eSAndroid Build Coastguard Worker                         param2.remove(key2);
2495*ec779b8eSAndroid Build Coastguard Worker                         ALOGV("Filtering out parameter %s", key2.c_str());
2496*ec779b8eSAndroid Build Coastguard Worker                         break;
2497*ec779b8eSAndroid Build Coastguard Worker                     }
2498*ec779b8eSAndroid Build Coastguard Worker                 }
2499*ec779b8eSAndroid Build Coastguard Worker             }
2500*ec779b8eSAndroid Build Coastguard Worker             // if all keys have been filtered out, remove the command.
2501*ec779b8eSAndroid Build Coastguard Worker             // otherwise, update the key value pairs
2502*ec779b8eSAndroid Build Coastguard Worker             if (param2.size() == 0) {
2503*ec779b8eSAndroid Build Coastguard Worker                 removedCommands.add(command2);
2504*ec779b8eSAndroid Build Coastguard Worker             } else {
2505*ec779b8eSAndroid Build Coastguard Worker                 data2->mKeyValuePairs = param2.toString();
2506*ec779b8eSAndroid Build Coastguard Worker             }
2507*ec779b8eSAndroid Build Coastguard Worker             command->mTime = command2->mTime;
2508*ec779b8eSAndroid Build Coastguard Worker             // force delayMs to non 0 so that code below does not request to wait for
2509*ec779b8eSAndroid Build Coastguard Worker             // command status as the command is now delayed
2510*ec779b8eSAndroid Build Coastguard Worker             delayMs = 1;
2511*ec779b8eSAndroid Build Coastguard Worker         } break;
2512*ec779b8eSAndroid Build Coastguard Worker 
2513*ec779b8eSAndroid Build Coastguard Worker         case SET_VOLUME: {
2514*ec779b8eSAndroid Build Coastguard Worker             VolumeData *data = (VolumeData *)command->mParam.get();
2515*ec779b8eSAndroid Build Coastguard Worker             VolumeData *data2 = (VolumeData *)command2->mParam.get();
2516*ec779b8eSAndroid Build Coastguard Worker             if (data->mIO != data2->mIO) break;
2517*ec779b8eSAndroid Build Coastguard Worker             if (data->mStream != data2->mStream) break;
2518*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Filtering out volume command on output %d for stream %d",
2519*ec779b8eSAndroid Build Coastguard Worker                     data->mIO, data->mStream);
2520*ec779b8eSAndroid Build Coastguard Worker             removedCommands.add(command2);
2521*ec779b8eSAndroid Build Coastguard Worker             command->mTime = command2->mTime;
2522*ec779b8eSAndroid Build Coastguard Worker             // force delayMs to non 0 so that code below does not request to wait for
2523*ec779b8eSAndroid Build Coastguard Worker             // command status as the command is now delayed
2524*ec779b8eSAndroid Build Coastguard Worker             delayMs = 1;
2525*ec779b8eSAndroid Build Coastguard Worker         } break;
2526*ec779b8eSAndroid Build Coastguard Worker 
2527*ec779b8eSAndroid Build Coastguard Worker         case SET_PORTS_VOLUME: {
2528*ec779b8eSAndroid Build Coastguard Worker             VolumePortsData *data = (VolumePortsData *)command->mParam.get();
2529*ec779b8eSAndroid Build Coastguard Worker             VolumePortsData *data2 = (VolumePortsData *)command2->mParam.get();
2530*ec779b8eSAndroid Build Coastguard Worker             if (data->mIO != data2->mIO) break;
2531*ec779b8eSAndroid Build Coastguard Worker             // Can remove command only if port ids list is the same, otherwise, remove from
2532*ec779b8eSAndroid Build Coastguard Worker             // command 2 all port whose volume will be replaced with command 1 volume.
2533*ec779b8eSAndroid Build Coastguard Worker             std::vector<audio_port_handle_t> portsOnlyInCommand2{};
2534*ec779b8eSAndroid Build Coastguard Worker             std::copy_if(data2->mPorts.begin(), data2->mPorts.end(),
2535*ec779b8eSAndroid Build Coastguard Worker                     std::back_inserter(portsOnlyInCommand2), [&](const auto &portId) {
2536*ec779b8eSAndroid Build Coastguard Worker                 return std::find(data->mPorts.begin(), data->mPorts.end(), portId) ==
2537*ec779b8eSAndroid Build Coastguard Worker                         data->mPorts.end();
2538*ec779b8eSAndroid Build Coastguard Worker             });
2539*ec779b8eSAndroid Build Coastguard Worker             if (!portsOnlyInCommand2.empty()) {
2540*ec779b8eSAndroid Build Coastguard Worker                 data2->mPorts = portsOnlyInCommand2;
2541*ec779b8eSAndroid Build Coastguard Worker                 break;
2542*ec779b8eSAndroid Build Coastguard Worker             }
2543*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Filtering out volume command on output %d for ports %s",
2544*ec779b8eSAndroid Build Coastguard Worker                     data->mIO, data->dumpPorts().c_str());
2545*ec779b8eSAndroid Build Coastguard Worker             removedCommands.add(command2);
2546*ec779b8eSAndroid Build Coastguard Worker             command->mTime = command2->mTime;
2547*ec779b8eSAndroid Build Coastguard Worker             // force delayMs to non 0 so that code below does not request to wait for
2548*ec779b8eSAndroid Build Coastguard Worker             // command status as the command is now delayed
2549*ec779b8eSAndroid Build Coastguard Worker             delayMs = 1;
2550*ec779b8eSAndroid Build Coastguard Worker         } break;
2551*ec779b8eSAndroid Build Coastguard Worker 
2552*ec779b8eSAndroid Build Coastguard Worker         case SET_VOICE_VOLUME: {
2553*ec779b8eSAndroid Build Coastguard Worker             VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
2554*ec779b8eSAndroid Build Coastguard Worker             VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
2555*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Filtering out voice volume command value %f replaced by %f",
2556*ec779b8eSAndroid Build Coastguard Worker                   data2->mVolume, data->mVolume);
2557*ec779b8eSAndroid Build Coastguard Worker             removedCommands.add(command2);
2558*ec779b8eSAndroid Build Coastguard Worker             command->mTime = command2->mTime;
2559*ec779b8eSAndroid Build Coastguard Worker             // force delayMs to non 0 so that code below does not request to wait for
2560*ec779b8eSAndroid Build Coastguard Worker             // command status as the command is now delayed
2561*ec779b8eSAndroid Build Coastguard Worker             delayMs = 1;
2562*ec779b8eSAndroid Build Coastguard Worker         } break;
2563*ec779b8eSAndroid Build Coastguard Worker 
2564*ec779b8eSAndroid Build Coastguard Worker         case CREATE_AUDIO_PATCH:
2565*ec779b8eSAndroid Build Coastguard Worker         case RELEASE_AUDIO_PATCH: {
2566*ec779b8eSAndroid Build Coastguard Worker             audio_patch_handle_t handle;
2567*ec779b8eSAndroid Build Coastguard Worker             struct audio_patch patch;
2568*ec779b8eSAndroid Build Coastguard Worker             if (command->mCommand == CREATE_AUDIO_PATCH) {
2569*ec779b8eSAndroid Build Coastguard Worker                 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
2570*ec779b8eSAndroid Build Coastguard Worker                 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
2571*ec779b8eSAndroid Build Coastguard Worker             } else {
2572*ec779b8eSAndroid Build Coastguard Worker                 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
2573*ec779b8eSAndroid Build Coastguard Worker                 memset(&patch, 0, sizeof(patch));
2574*ec779b8eSAndroid Build Coastguard Worker             }
2575*ec779b8eSAndroid Build Coastguard Worker             audio_patch_handle_t handle2;
2576*ec779b8eSAndroid Build Coastguard Worker             struct audio_patch patch2;
2577*ec779b8eSAndroid Build Coastguard Worker             if (command2->mCommand == CREATE_AUDIO_PATCH) {
2578*ec779b8eSAndroid Build Coastguard Worker                 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
2579*ec779b8eSAndroid Build Coastguard Worker                 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
2580*ec779b8eSAndroid Build Coastguard Worker             } else {
2581*ec779b8eSAndroid Build Coastguard Worker                 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
2582*ec779b8eSAndroid Build Coastguard Worker                 memset(&patch2, 0, sizeof(patch2));
2583*ec779b8eSAndroid Build Coastguard Worker             }
2584*ec779b8eSAndroid Build Coastguard Worker             if (handle != handle2) break;
2585*ec779b8eSAndroid Build Coastguard Worker             /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
2586*ec779b8eSAndroid Build Coastguard Worker                same output. */
2587*ec779b8eSAndroid Build Coastguard Worker             if( (command->mCommand == CREATE_AUDIO_PATCH) &&
2588*ec779b8eSAndroid Build Coastguard Worker                 (command2->mCommand == CREATE_AUDIO_PATCH) ) {
2589*ec779b8eSAndroid Build Coastguard Worker                 bool isOutputDiff = false;
2590*ec779b8eSAndroid Build Coastguard Worker                 if (patch.num_sources == patch2.num_sources) {
2591*ec779b8eSAndroid Build Coastguard Worker                     for (unsigned count = 0; count < patch.num_sources; count++) {
2592*ec779b8eSAndroid Build Coastguard Worker                         if (patch.sources[count].id != patch2.sources[count].id) {
2593*ec779b8eSAndroid Build Coastguard Worker                             isOutputDiff = true;
2594*ec779b8eSAndroid Build Coastguard Worker                             break;
2595*ec779b8eSAndroid Build Coastguard Worker                         }
2596*ec779b8eSAndroid Build Coastguard Worker                     }
2597*ec779b8eSAndroid Build Coastguard Worker                     if (isOutputDiff)
2598*ec779b8eSAndroid Build Coastguard Worker                        break;
2599*ec779b8eSAndroid Build Coastguard Worker                 }
2600*ec779b8eSAndroid Build Coastguard Worker             }
2601*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Filtering out %s audio patch command for handle %d",
2602*ec779b8eSAndroid Build Coastguard Worker                   (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
2603*ec779b8eSAndroid Build Coastguard Worker             removedCommands.add(command2);
2604*ec779b8eSAndroid Build Coastguard Worker             command->mTime = command2->mTime;
2605*ec779b8eSAndroid Build Coastguard Worker             // force delayMs to non 0 so that code below does not request to wait for
2606*ec779b8eSAndroid Build Coastguard Worker             // command status as the command is now delayed
2607*ec779b8eSAndroid Build Coastguard Worker             delayMs = 1;
2608*ec779b8eSAndroid Build Coastguard Worker         } break;
2609*ec779b8eSAndroid Build Coastguard Worker 
2610*ec779b8eSAndroid Build Coastguard Worker         case DYN_POLICY_MIX_STATE_UPDATE: {
2611*ec779b8eSAndroid Build Coastguard Worker 
2612*ec779b8eSAndroid Build Coastguard Worker         } break;
2613*ec779b8eSAndroid Build Coastguard Worker 
2614*ec779b8eSAndroid Build Coastguard Worker         case RECORDING_CONFIGURATION_UPDATE: {
2615*ec779b8eSAndroid Build Coastguard Worker 
2616*ec779b8eSAndroid Build Coastguard Worker         } break;
2617*ec779b8eSAndroid Build Coastguard Worker 
2618*ec779b8eSAndroid Build Coastguard Worker         case ROUTING_UPDATED: {
2619*ec779b8eSAndroid Build Coastguard Worker 
2620*ec779b8eSAndroid Build Coastguard Worker         } break;
2621*ec779b8eSAndroid Build Coastguard Worker 
2622*ec779b8eSAndroid Build Coastguard Worker         case VOL_RANGE_INIT_REQUEST: {
2623*ec779b8eSAndroid Build Coastguard Worker             // command may come from different requests, do not filter
2624*ec779b8eSAndroid Build Coastguard Worker         } break;
2625*ec779b8eSAndroid Build Coastguard Worker 
2626*ec779b8eSAndroid Build Coastguard Worker         default:
2627*ec779b8eSAndroid Build Coastguard Worker             break;
2628*ec779b8eSAndroid Build Coastguard Worker         }
2629*ec779b8eSAndroid Build Coastguard Worker     }
2630*ec779b8eSAndroid Build Coastguard Worker 
2631*ec779b8eSAndroid Build Coastguard Worker     // remove filtered commands
2632*ec779b8eSAndroid Build Coastguard Worker     for (size_t j = 0; j < removedCommands.size(); j++) {
2633*ec779b8eSAndroid Build Coastguard Worker         // removed commands always have time stamps greater than current command
2634*ec779b8eSAndroid Build Coastguard Worker         for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
2635*ec779b8eSAndroid Build Coastguard Worker             if (mAudioCommands[k].get() == removedCommands[j].get()) {
2636*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
2637*ec779b8eSAndroid Build Coastguard Worker                 mAudioCommands.removeAt(k);
2638*ec779b8eSAndroid Build Coastguard Worker                 break;
2639*ec779b8eSAndroid Build Coastguard Worker             }
2640*ec779b8eSAndroid Build Coastguard Worker         }
2641*ec779b8eSAndroid Build Coastguard Worker     }
2642*ec779b8eSAndroid Build Coastguard Worker     removedCommands.clear();
2643*ec779b8eSAndroid Build Coastguard Worker 
2644*ec779b8eSAndroid Build Coastguard Worker     // Disable wait for status if delay is not 0.
2645*ec779b8eSAndroid Build Coastguard Worker     // Except for create audio patch command because the returned patch handle
2646*ec779b8eSAndroid Build Coastguard Worker     // is needed by audio policy manager. Audio patch created after timeout
2647*ec779b8eSAndroid Build Coastguard Worker     // (see TIMED_OUT) will be released from threadLoop().
2648*ec779b8eSAndroid Build Coastguard Worker     if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
2649*ec779b8eSAndroid Build Coastguard Worker         command->mWaitStatus = false;
2650*ec779b8eSAndroid Build Coastguard Worker     }
2651*ec779b8eSAndroid Build Coastguard Worker 
2652*ec779b8eSAndroid Build Coastguard Worker     // insert command at the right place according to its time stamp
2653*ec779b8eSAndroid Build Coastguard Worker     ALOGV("inserting command: %d at index %zd, num commands %zu",
2654*ec779b8eSAndroid Build Coastguard Worker             command->mCommand, i+1, mAudioCommands.size());
2655*ec779b8eSAndroid Build Coastguard Worker     mAudioCommands.insertAt(command, i + 1);
2656*ec779b8eSAndroid Build Coastguard Worker }
2657*ec779b8eSAndroid Build Coastguard Worker 
exit()2658*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::exit()
2659*ec779b8eSAndroid Build Coastguard Worker {
2660*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioCommandThread::exit");
2661*ec779b8eSAndroid Build Coastguard Worker     {
2662*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mMutex);
2663*ec779b8eSAndroid Build Coastguard Worker         requestExit();
2664*ec779b8eSAndroid Build Coastguard Worker         mWaitWorkCV.notify_one();
2665*ec779b8eSAndroid Build Coastguard Worker     }
2666*ec779b8eSAndroid Build Coastguard Worker     // Note that we can call it from the thread loop if all other references have been released
2667*ec779b8eSAndroid Build Coastguard Worker     // but it will safely return WOULD_BLOCK in this case
2668*ec779b8eSAndroid Build Coastguard Worker     requestExitAndWait();
2669*ec779b8eSAndroid Build Coastguard Worker }
2670*ec779b8eSAndroid Build Coastguard Worker 
dump(char * buffer,size_t size)2671*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
2672*ec779b8eSAndroid Build Coastguard Worker {
2673*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
2674*ec779b8eSAndroid Build Coastguard Worker             mCommand,
2675*ec779b8eSAndroid Build Coastguard Worker             (int)ns2s(mTime),
2676*ec779b8eSAndroid Build Coastguard Worker             (int)ns2ms(mTime)%1000,
2677*ec779b8eSAndroid Build Coastguard Worker             mWaitStatus,
2678*ec779b8eSAndroid Build Coastguard Worker             mParam.get());
2679*ec779b8eSAndroid Build Coastguard Worker }
2680*ec779b8eSAndroid Build Coastguard Worker 
2681*ec779b8eSAndroid Build Coastguard Worker /******* helpers for the service_ops callbacks defined below *********/
setParameters(audio_io_handle_t ioHandle,const char * keyValuePairs,int delayMs)2682*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
2683*ec779b8eSAndroid Build Coastguard Worker                                        const char *keyValuePairs,
2684*ec779b8eSAndroid Build Coastguard Worker                                        int delayMs)
2685*ec779b8eSAndroid Build Coastguard Worker {
2686*ec779b8eSAndroid Build Coastguard Worker     mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
2687*ec779b8eSAndroid Build Coastguard Worker                                            delayMs);
2688*ec779b8eSAndroid Build Coastguard Worker }
2689*ec779b8eSAndroid Build Coastguard Worker 
setStreamVolume(audio_stream_type_t stream,float volume,bool muted,audio_io_handle_t output,int delayMs)2690*ec779b8eSAndroid Build Coastguard Worker int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
2691*ec779b8eSAndroid Build Coastguard Worker                                         float volume,
2692*ec779b8eSAndroid Build Coastguard Worker                                         bool muted,
2693*ec779b8eSAndroid Build Coastguard Worker                                         audio_io_handle_t output,
2694*ec779b8eSAndroid Build Coastguard Worker                                         int delayMs)
2695*ec779b8eSAndroid Build Coastguard Worker {
2696*ec779b8eSAndroid Build Coastguard Worker     return (int)mAudioCommandThread->volumeCommand(stream, volume, muted,
2697*ec779b8eSAndroid Build Coastguard Worker                                                    output, delayMs);
2698*ec779b8eSAndroid Build Coastguard Worker }
2699*ec779b8eSAndroid Build Coastguard Worker 
setPortsVolume(const std::vector<audio_port_handle_t> & ports,float volume,bool muted,audio_io_handle_t output,int delayMs)2700*ec779b8eSAndroid Build Coastguard Worker int AudioPolicyService::setPortsVolume(const std::vector<audio_port_handle_t> &ports, float volume,
2701*ec779b8eSAndroid Build Coastguard Worker                                        bool muted, audio_io_handle_t output, int delayMs)
2702*ec779b8eSAndroid Build Coastguard Worker {
2703*ec779b8eSAndroid Build Coastguard Worker     return (int)mAudioCommandThread->volumePortsCommand(ports, volume, muted, output, delayMs);
2704*ec779b8eSAndroid Build Coastguard Worker }
2705*ec779b8eSAndroid Build Coastguard Worker 
setVoiceVolume(float volume,int delayMs)2706*ec779b8eSAndroid Build Coastguard Worker int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
2707*ec779b8eSAndroid Build Coastguard Worker {
2708*ec779b8eSAndroid Build Coastguard Worker     return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
2709*ec779b8eSAndroid Build Coastguard Worker }
2710*ec779b8eSAndroid Build Coastguard Worker 
setEffectSuspended(int effectId,audio_session_t sessionId,bool suspended)2711*ec779b8eSAndroid Build Coastguard Worker void AudioPolicyService::setEffectSuspended(int effectId,
2712*ec779b8eSAndroid Build Coastguard Worker                                             audio_session_t sessionId,
2713*ec779b8eSAndroid Build Coastguard Worker                                             bool suspended)
2714*ec779b8eSAndroid Build Coastguard Worker {
2715*ec779b8eSAndroid Build Coastguard Worker     mAudioCommandThread->setEffectSuspendedCommand(effectId, sessionId, suspended);
2716*ec779b8eSAndroid Build Coastguard Worker }
2717*ec779b8eSAndroid Build Coastguard Worker 
onNewAudioModulesAvailable()2718*ec779b8eSAndroid Build Coastguard Worker Status AudioPolicyService::onNewAudioModulesAvailable()
2719*ec779b8eSAndroid Build Coastguard Worker {
2720*ec779b8eSAndroid Build Coastguard Worker     mOutputCommandThread->audioModulesUpdateCommand();
2721*ec779b8eSAndroid Build Coastguard Worker     return Status::ok();
2722*ec779b8eSAndroid Build Coastguard Worker }
2723*ec779b8eSAndroid Build Coastguard Worker 
2724*ec779b8eSAndroid Build Coastguard Worker 
2725*ec779b8eSAndroid Build Coastguard Worker extern "C" {
2726*ec779b8eSAndroid Build Coastguard Worker audio_module_handle_t aps_load_hw_module(void *service __unused,
2727*ec779b8eSAndroid Build Coastguard Worker                                              const char *name);
2728*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t aps_open_output(void *service __unused,
2729*ec779b8eSAndroid Build Coastguard Worker                                          audio_devices_t *pDevices,
2730*ec779b8eSAndroid Build Coastguard Worker                                          uint32_t *pSamplingRate,
2731*ec779b8eSAndroid Build Coastguard Worker                                          audio_format_t *pFormat,
2732*ec779b8eSAndroid Build Coastguard Worker                                          audio_channel_mask_t *pChannelMask,
2733*ec779b8eSAndroid Build Coastguard Worker                                          uint32_t *pLatencyMs,
2734*ec779b8eSAndroid Build Coastguard Worker                                          audio_output_flags_t flags);
2735*ec779b8eSAndroid Build Coastguard Worker 
2736*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t aps_open_output_on_module(void *service __unused,
2737*ec779b8eSAndroid Build Coastguard Worker                                                    audio_module_handle_t module,
2738*ec779b8eSAndroid Build Coastguard Worker                                                    audio_devices_t *pDevices,
2739*ec779b8eSAndroid Build Coastguard Worker                                                    uint32_t *pSamplingRate,
2740*ec779b8eSAndroid Build Coastguard Worker                                                    audio_format_t *pFormat,
2741*ec779b8eSAndroid Build Coastguard Worker                                                    audio_channel_mask_t *pChannelMask,
2742*ec779b8eSAndroid Build Coastguard Worker                                                    uint32_t *pLatencyMs,
2743*ec779b8eSAndroid Build Coastguard Worker                                                    audio_output_flags_t flags,
2744*ec779b8eSAndroid Build Coastguard Worker                                                    const audio_offload_info_t *offloadInfo);
2745*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t aps_open_dup_output(void *service __unused,
2746*ec779b8eSAndroid Build Coastguard Worker                                                  audio_io_handle_t output1,
2747*ec779b8eSAndroid Build Coastguard Worker                                                  audio_io_handle_t output2);
2748*ec779b8eSAndroid Build Coastguard Worker int aps_close_output(void *service __unused, audio_io_handle_t output);
2749*ec779b8eSAndroid Build Coastguard Worker int aps_suspend_output(void *service __unused, audio_io_handle_t output);
2750*ec779b8eSAndroid Build Coastguard Worker int aps_restore_output(void *service __unused, audio_io_handle_t output);
2751*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t aps_open_input(void *service __unused,
2752*ec779b8eSAndroid Build Coastguard Worker                                         audio_devices_t *pDevices,
2753*ec779b8eSAndroid Build Coastguard Worker                                         uint32_t *pSamplingRate,
2754*ec779b8eSAndroid Build Coastguard Worker                                         audio_format_t *pFormat,
2755*ec779b8eSAndroid Build Coastguard Worker                                         audio_channel_mask_t *pChannelMask,
2756*ec779b8eSAndroid Build Coastguard Worker                                         audio_in_acoustics_t acoustics __unused);
2757*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t aps_open_input_on_module(void *service __unused,
2758*ec779b8eSAndroid Build Coastguard Worker                                                   audio_module_handle_t module,
2759*ec779b8eSAndroid Build Coastguard Worker                                                   audio_devices_t *pDevices,
2760*ec779b8eSAndroid Build Coastguard Worker                                                   uint32_t *pSamplingRate,
2761*ec779b8eSAndroid Build Coastguard Worker                                                   audio_format_t *pFormat,
2762*ec779b8eSAndroid Build Coastguard Worker                                                   audio_channel_mask_t *pChannelMask);
2763*ec779b8eSAndroid Build Coastguard Worker int aps_close_input(void *service __unused, audio_io_handle_t input);
2764*ec779b8eSAndroid Build Coastguard Worker int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
2765*ec779b8eSAndroid Build Coastguard Worker int aps_move_effects(void *service __unused, audio_session_t session,
2766*ec779b8eSAndroid Build Coastguard Worker                                 audio_io_handle_t src_output,
2767*ec779b8eSAndroid Build Coastguard Worker                                 audio_io_handle_t dst_output);
2768*ec779b8eSAndroid Build Coastguard Worker char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
2769*ec779b8eSAndroid Build Coastguard Worker                                      const char *keys);
2770*ec779b8eSAndroid Build Coastguard Worker void aps_set_parameters(void *service, audio_io_handle_t io_handle,
2771*ec779b8eSAndroid Build Coastguard Worker                                    const char *kv_pairs, int delay_ms);
2772*ec779b8eSAndroid Build Coastguard Worker int aps_set_stream_volume(void *service, audio_stream_type_t stream,
2773*ec779b8eSAndroid Build Coastguard Worker                                      float volume, audio_io_handle_t output,
2774*ec779b8eSAndroid Build Coastguard Worker                                      int delay_ms);
2775*ec779b8eSAndroid Build Coastguard Worker int aps_set_voice_volume(void *service, float volume, int delay_ms);
2776*ec779b8eSAndroid Build Coastguard Worker };
2777*ec779b8eSAndroid Build Coastguard Worker 
2778*ec779b8eSAndroid Build Coastguard Worker } // namespace android
2779