xref: /aosp_15_r20/frameworks/av/services/audioflinger/AudioFlinger.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2007, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker **     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioFlinger"
19*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*ec779b8eSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_AUDIO
21*ec779b8eSAndroid Build Coastguard Worker #include <utils/Trace.h>
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker // Define AUDIO_ARRAYS_STATIC_CHECK to check all audio arrays are correct
24*ec779b8eSAndroid Build Coastguard Worker #define AUDIO_ARRAYS_STATIC_CHECK 1
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker #include "Configuration.h"
27*ec779b8eSAndroid Build Coastguard Worker #include "AudioFlinger.h"
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker #include <afutils/FallibleLockGuard.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <afutils/NBAIO_Tee.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <afutils/Permission.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <afutils/PropertyUtils.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <afutils/TypedLogger.h>
34*ec779b8eSAndroid Build Coastguard Worker #include <android-base/errors.h>
35*ec779b8eSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <android/media/IAudioPolicyService.h>
37*ec779b8eSAndroid Build Coastguard Worker #include <audiomanager/IAudioManager.h>
38*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
40*ec779b8eSAndroid Build Coastguard Worker #include <binder/Parcel.h>
41*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
42*ec779b8eSAndroid Build Coastguard Worker #include <com_android_media_audio.h>
43*ec779b8eSAndroid Build Coastguard Worker #include <com_android_media_audioserver.h>
44*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversion.h>
45*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioParameter.h>
46*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioValidator.h>
47*ec779b8eSAndroid Build Coastguard Worker #include <media/IMediaLogService.h>
48*ec779b8eSAndroid Build Coastguard Worker #include <media/IPermissionProvider.h>
49*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaMetricsItem.h>
50*ec779b8eSAndroid Build Coastguard Worker #include <media/NativePermissionController.h>
51*ec779b8eSAndroid Build Coastguard Worker #include <media/TypeConverter.h>
52*ec779b8eSAndroid Build Coastguard Worker #include <media/ValidatedAttributionSourceState.h>
53*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/BatteryNotifier.h>
54*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/MemoryLeakTrackUtil.h>
55*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/MethodStatistics.h>
56*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/ServiceUtilities.h>
57*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/TimeCheck.h>
58*ec779b8eSAndroid Build Coastguard Worker #include <memunreachable/memunreachable.h>
59*ec779b8eSAndroid Build Coastguard Worker // required for effect matching
60*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_effects/effect_aec.h>
61*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_effects/effect_ns.h>
62*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_effects/effect_spatializer.h>
63*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_effects/effect_visualizer.h>
64*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
65*ec779b8eSAndroid Build Coastguard Worker 
66*ec779b8eSAndroid Build Coastguard Worker // not needed with the includes above, added to prevent transitive include dependency.
67*ec779b8eSAndroid Build Coastguard Worker #include <chrono>
68*ec779b8eSAndroid Build Coastguard Worker #include <thread>
69*ec779b8eSAndroid Build Coastguard Worker #include <string_view>
70*ec779b8eSAndroid Build Coastguard Worker 
71*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
72*ec779b8eSAndroid Build Coastguard Worker 
73*ec779b8eSAndroid Build Coastguard Worker // Note: the following macro is used for extremely verbose logging message.  In
74*ec779b8eSAndroid Build Coastguard Worker // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
75*ec779b8eSAndroid Build Coastguard Worker // 0; but one side effect of this is to turn all LOGV's as well.  Some messages
76*ec779b8eSAndroid Build Coastguard Worker // are so verbose that we want to suppress them even when we have ALOG_ASSERT
77*ec779b8eSAndroid Build Coastguard Worker // turned on.  Do not uncomment the #def below unless you really know what you
78*ec779b8eSAndroid Build Coastguard Worker // are doing and want to see all of the extremely verbose messages.
79*ec779b8eSAndroid Build Coastguard Worker //#define VERY_VERY_VERBOSE_LOGGING
80*ec779b8eSAndroid Build Coastguard Worker #ifdef VERY_VERY_VERBOSE_LOGGING
81*ec779b8eSAndroid Build Coastguard Worker #define ALOGVV ALOGV
82*ec779b8eSAndroid Build Coastguard Worker #else
83*ec779b8eSAndroid Build Coastguard Worker #define ALOGVV(a...) do { } while(0)
84*ec779b8eSAndroid Build Coastguard Worker #endif
85*ec779b8eSAndroid Build Coastguard Worker 
86*ec779b8eSAndroid Build Coastguard Worker namespace android {
87*ec779b8eSAndroid Build Coastguard Worker 
88*ec779b8eSAndroid Build Coastguard Worker using namespace std::string_view_literals;
89*ec779b8eSAndroid Build Coastguard Worker 
90*ec779b8eSAndroid Build Coastguard Worker using ::android::base::StringPrintf;
91*ec779b8eSAndroid Build Coastguard Worker using aidl_utils::statusTFromBinderStatus;
92*ec779b8eSAndroid Build Coastguard Worker using media::IEffectClient;
93*ec779b8eSAndroid Build Coastguard Worker using media::audio::common::AudioMMapPolicyInfo;
94*ec779b8eSAndroid Build Coastguard Worker using media::audio::common::AudioMMapPolicyType;
95*ec779b8eSAndroid Build Coastguard Worker using media::audio::common::AudioMode;
96*ec779b8eSAndroid Build Coastguard Worker using android::content::AttributionSourceState;
97*ec779b8eSAndroid Build Coastguard Worker using android::detail::AudioHalVersionInfo;
98*ec779b8eSAndroid Build Coastguard Worker using com::android::media::permission::INativePermissionController;
99*ec779b8eSAndroid Build Coastguard Worker using com::android::media::permission::IPermissionProvider;
100*ec779b8eSAndroid Build Coastguard Worker using com::android::media::permission::NativePermissionController;
101*ec779b8eSAndroid Build Coastguard Worker using com::android::media::permission::ValidatedAttributionSourceState;
102*ec779b8eSAndroid Build Coastguard Worker 
103*ec779b8eSAndroid Build Coastguard Worker static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion =
104*ec779b8eSAndroid Build Coastguard Worker         AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1);
105*ec779b8eSAndroid Build Coastguard Worker 
106*ec779b8eSAndroid Build Coastguard Worker constexpr auto kDeadlockedString = "AudioFlinger may be deadlocked\n"sv;
107*ec779b8eSAndroid Build Coastguard Worker constexpr auto kHardwareLockedString = "Hardware lock is taken\n"sv;
108*ec779b8eSAndroid Build Coastguard Worker constexpr auto kClientLockedString = "Client lock is taken\n"sv;
109*ec779b8eSAndroid Build Coastguard Worker constexpr auto kNoEffectsFactory = "Effects Factory is absent\n"sv;
110*ec779b8eSAndroid Build Coastguard Worker 
111*ec779b8eSAndroid Build Coastguard Worker static constexpr char kAudioServiceName[] = "audio";
112*ec779b8eSAndroid Build Coastguard Worker 
113*ec779b8eSAndroid Build Coastguard Worker // Keep a strong reference to media.log service around forever.
114*ec779b8eSAndroid Build Coastguard Worker // The service is within our parent process so it can never die in a way that we could observe.
115*ec779b8eSAndroid Build Coastguard Worker // These two variables are const after initialization.
116*ec779b8eSAndroid Build Coastguard Worker static sp<IMediaLogService> sMediaLogService;
117*ec779b8eSAndroid Build Coastguard Worker 
118*ec779b8eSAndroid Build Coastguard Worker static pthread_once_t sMediaLogOnce = PTHREAD_ONCE_INIT;
119*ec779b8eSAndroid Build Coastguard Worker 
sMediaLogInit()120*ec779b8eSAndroid Build Coastguard Worker static void sMediaLogInit()
121*ec779b8eSAndroid Build Coastguard Worker {
122*ec779b8eSAndroid Build Coastguard Worker     auto sMediaLogServiceAsBinder = defaultServiceManager()->getService(String16("media.log"));
123*ec779b8eSAndroid Build Coastguard Worker     if (sMediaLogServiceAsBinder != 0) {
124*ec779b8eSAndroid Build Coastguard Worker         sMediaLogService = interface_cast<IMediaLogService>(sMediaLogServiceAsBinder);
125*ec779b8eSAndroid Build Coastguard Worker     }
126*ec779b8eSAndroid Build Coastguard Worker }
127*ec779b8eSAndroid Build Coastguard Worker 
writeStr(int fd,std::string_view s)128*ec779b8eSAndroid Build Coastguard Worker static int writeStr(int fd, std::string_view s) {
129*ec779b8eSAndroid Build Coastguard Worker     return write(fd, s.data(), s.size());
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker 
writeStr(int fd,const String8 & s)132*ec779b8eSAndroid Build Coastguard Worker static int writeStr(int fd, const String8& s) {
133*ec779b8eSAndroid Build Coastguard Worker     return write(fd, s.c_str(), s.size());
134*ec779b8eSAndroid Build Coastguard Worker }
135*ec779b8eSAndroid Build Coastguard Worker 
136*ec779b8eSAndroid Build Coastguard Worker static error::BinderResult<ValidatedAttributionSourceState>
validateAttributionFromContextOrTrustedCaller(AttributionSourceState attr,const IPermissionProvider & provider)137*ec779b8eSAndroid Build Coastguard Worker validateAttributionFromContextOrTrustedCaller(AttributionSourceState attr,
138*ec779b8eSAndroid Build Coastguard Worker         const IPermissionProvider& provider) {
139*ec779b8eSAndroid Build Coastguard Worker     const auto callingUid = IPCThreadState::self()->getCallingUid();
140*ec779b8eSAndroid Build Coastguard Worker     // We trust the following UIDs to appropriate validated identities above us
141*ec779b8eSAndroid Build Coastguard Worker     if (isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
142*ec779b8eSAndroid Build Coastguard Worker         // Legacy paths may not properly populate package name, so we attempt to handle.
143*ec779b8eSAndroid Build Coastguard Worker         if (!attr.packageName.has_value() || attr.packageName.value() == "") {
144*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Trusted client %d provided attr with missing package name" , callingUid);
145*ec779b8eSAndroid Build Coastguard Worker             attr.packageName = VALUE_OR_RETURN(provider.getPackagesForUid(callingUid))[0];
146*ec779b8eSAndroid Build Coastguard Worker         }
147*ec779b8eSAndroid Build Coastguard Worker         // Behavior change: In the case of delegation, if pid is invalid,
148*ec779b8eSAndroid Build Coastguard Worker         // filling it in with the callingPid will cause a mismatch between the
149*ec779b8eSAndroid Build Coastguard Worker         // pid and the uid in the attribution, which is error-prone.
150*ec779b8eSAndroid Build Coastguard Worker         // Instead, assert that the pid from a trusted source is valid
151*ec779b8eSAndroid Build Coastguard Worker         if (attr.pid == -1) {
152*ec779b8eSAndroid Build Coastguard Worker             if (callingUid != static_cast<uid_t>(attr.uid)) {
153*ec779b8eSAndroid Build Coastguard Worker                 return error::unexpectedExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT,
154*ec779b8eSAndroid Build Coastguard Worker                         "validateAttribution: Invalid pid from delegating trusted source");
155*ec779b8eSAndroid Build Coastguard Worker             } else {
156*ec779b8eSAndroid Build Coastguard Worker                 // Legacy handling for trusted clients which may not fill pid correctly
157*ec779b8eSAndroid Build Coastguard Worker                 attr.pid = IPCThreadState::self()->getCallingPid();
158*ec779b8eSAndroid Build Coastguard Worker             }
159*ec779b8eSAndroid Build Coastguard Worker         }
160*ec779b8eSAndroid Build Coastguard Worker         return ValidatedAttributionSourceState::createFromTrustedSource(std::move(attr));
161*ec779b8eSAndroid Build Coastguard Worker     } else {
162*ec779b8eSAndroid Build Coastguard Worker         // Behavior change: Populate pid with callingPid unconditionally. Previously, we
163*ec779b8eSAndroid Build Coastguard Worker         // allowed caller provided pid, if uid matched calling context, but this is error-prone
164*ec779b8eSAndroid Build Coastguard Worker         // since it allows mismatching uid/pid
165*ec779b8eSAndroid Build Coastguard Worker         return ValidatedAttributionSourceState::createFromBinderContext(std::move(attr), provider);
166*ec779b8eSAndroid Build Coastguard Worker     }
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker 
169*ec779b8eSAndroid Build Coastguard Worker #define VALUE_OR_RETURN_CONVERTED(exp)                                                \
170*ec779b8eSAndroid Build Coastguard Worker     ({                                                                                \
171*ec779b8eSAndroid Build Coastguard Worker         auto _tmp = (exp);                                                            \
172*ec779b8eSAndroid Build Coastguard Worker         if (!_tmp.ok()) {                                                             \
173*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Function: %s Line: %d Failed result (%s)", __FUNCTION__, __LINE__, \
174*ec779b8eSAndroid Build Coastguard Worker                   errorToString(_tmp.error()).c_str());                               \
175*ec779b8eSAndroid Build Coastguard Worker             return statusTFromBinderStatus(_tmp.error());                             \
176*ec779b8eSAndroid Build Coastguard Worker         }                                                                             \
177*ec779b8eSAndroid Build Coastguard Worker         std::move(_tmp.value());                                                      \
178*ec779b8eSAndroid Build Coastguard Worker     })
179*ec779b8eSAndroid Build Coastguard Worker 
180*ec779b8eSAndroid Build Coastguard Worker 
181*ec779b8eSAndroid Build Coastguard Worker 
182*ec779b8eSAndroid Build Coastguard Worker // Creates association between Binder code to name for IAudioFlinger.
183*ec779b8eSAndroid Build Coastguard Worker #define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \
184*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(createTrack) \
185*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(createRecord) \
186*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(sampleRate) \
187*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(format) \
188*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(frameCount) \
189*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(latency) \
190*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setMasterVolume) \
191*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setMasterMute) \
192*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(masterVolume) \
193*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(masterMute) \
194*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setStreamVolume) \
195*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setStreamMute) \
196*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setPortsVolume) \
197*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setMode) \
198*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setMicMute) \
199*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMicMute) \
200*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setRecordSilenced) \
201*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setParameters) \
202*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getParameters) \
203*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(registerClient) \
204*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getInputBufferSize) \
205*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(openOutput) \
206*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(openDuplicateOutput) \
207*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(closeOutput) \
208*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(suspendOutput) \
209*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(restoreOutput) \
210*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(openInput) \
211*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(closeInput) \
212*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setVoiceVolume) \
213*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getRenderPosition) \
214*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getInputFramesLost) \
215*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(newAudioUniqueId) \
216*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(acquireAudioSessionId) \
217*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(releaseAudioSessionId) \
218*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(queryNumberEffects) \
219*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(queryEffect) \
220*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getEffectDescriptor) \
221*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(createEffect) \
222*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(moveEffects) \
223*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(loadHwModule) \
224*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getPrimaryOutputSamplingRate) \
225*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getPrimaryOutputFrameCount) \
226*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setLowRamDevice) \
227*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAudioPort) \
228*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(createAudioPatch) \
229*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(releaseAudioPatch) \
230*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(listAudioPatches) \
231*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAudioPortConfig) \
232*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAudioHwSyncForSession) \
233*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(systemReady) \
234*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(audioPolicyReady) \
235*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(frameCountHAL) \
236*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMicrophones) \
237*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setMasterBalance) \
238*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMasterBalance) \
239*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setEffectSuspended) \
240*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setAudioHalPids) \
241*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setVibratorInfos) \
242*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(updateSecondaryOutputs) \
243*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getMmapPolicyInfos) \
244*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAAudioMixerBurstCount) \
245*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAAudioHardwareBurstMinUsec) \
246*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setDeviceConnectedState) \
247*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setSimulateDeviceConnections) \
248*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setRequestedLatencyMode) \
249*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getSupportedLatencyModes) \
250*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(setBluetoothVariableLatencyEnabled) \
251*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(isBluetoothVariableLatencyEnabled) \
252*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(supportsBluetoothVariableLatency) \
253*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getSoundDoseInterface) \
254*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAudioPolicyConfig) \
255*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(getAudioMixPort) \
256*ec779b8eSAndroid Build Coastguard Worker BINDER_METHOD_ENTRY(resetReferencesForTest) \
257*ec779b8eSAndroid Build Coastguard Worker 
258*ec779b8eSAndroid Build Coastguard Worker // singleton for Binder Method Statistics for IAudioFlinger
getIAudioFlingerStatistics()259*ec779b8eSAndroid Build Coastguard Worker static auto& getIAudioFlingerStatistics() {
260*ec779b8eSAndroid Build Coastguard Worker     using Code = android::AudioFlingerServerAdapter::Delegate::TransactionCode;
261*ec779b8eSAndroid Build Coastguard Worker 
262*ec779b8eSAndroid Build Coastguard Worker #pragma push_macro("BINDER_METHOD_ENTRY")
263*ec779b8eSAndroid Build Coastguard Worker #undef BINDER_METHOD_ENTRY
264*ec779b8eSAndroid Build Coastguard Worker #define BINDER_METHOD_ENTRY(ENTRY) \
265*ec779b8eSAndroid Build Coastguard Worker     {(Code)media::BnAudioFlingerService::TRANSACTION_##ENTRY, #ENTRY},
266*ec779b8eSAndroid Build Coastguard Worker 
267*ec779b8eSAndroid Build Coastguard Worker     static mediautils::MethodStatistics<Code> methodStatistics{
268*ec779b8eSAndroid Build Coastguard Worker         IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST
269*ec779b8eSAndroid Build Coastguard Worker         METHOD_STATISTICS_BINDER_CODE_NAMES(Code)
270*ec779b8eSAndroid Build Coastguard Worker     };
271*ec779b8eSAndroid Build Coastguard Worker #pragma pop_macro("BINDER_METHOD_ENTRY")
272*ec779b8eSAndroid Build Coastguard Worker 
273*ec779b8eSAndroid Build Coastguard Worker     return methodStatistics;
274*ec779b8eSAndroid Build Coastguard Worker }
275*ec779b8eSAndroid Build Coastguard Worker 
276*ec779b8eSAndroid Build Coastguard Worker namespace base {
277*ec779b8eSAndroid Build Coastguard Worker template <typename T>
278*ec779b8eSAndroid Build Coastguard Worker struct OkOrFail<std::optional<T>> {
279*ec779b8eSAndroid Build Coastguard Worker     using opt_t = std::optional<T>;
280*ec779b8eSAndroid Build Coastguard Worker     OkOrFail() = delete;
281*ec779b8eSAndroid Build Coastguard Worker     OkOrFail(const opt_t&) = delete;
282*ec779b8eSAndroid Build Coastguard Worker 
IsOkandroid::base::OkOrFail283*ec779b8eSAndroid Build Coastguard Worker     static bool IsOk(const opt_t& opt) { return opt.has_value(); }
Unwrapandroid::base::OkOrFail284*ec779b8eSAndroid Build Coastguard Worker     static T Unwrap(opt_t&& opt) { return std::move(opt.value()); }
ErrorMessageandroid::base::OkOrFail285*ec779b8eSAndroid Build Coastguard Worker     static std::string ErrorMessage(const opt_t&) { return "Empty optional"; }
Failandroid::base::OkOrFail286*ec779b8eSAndroid Build Coastguard Worker     static void Fail(opt_t&&) {}
287*ec779b8eSAndroid Build Coastguard Worker };
288*ec779b8eSAndroid Build Coastguard Worker }
289*ec779b8eSAndroid Build Coastguard Worker 
290*ec779b8eSAndroid Build Coastguard Worker class DevicesFactoryHalCallbackImpl : public DevicesFactoryHalCallback {
291*ec779b8eSAndroid Build Coastguard Worker   public:
onNewDevicesAvailable()292*ec779b8eSAndroid Build Coastguard Worker     void onNewDevicesAvailable() override {
293*ec779b8eSAndroid Build Coastguard Worker         // Start a detached thread to execute notification in parallel.
294*ec779b8eSAndroid Build Coastguard Worker         // This is done to prevent mutual blocking of audio_flinger and
295*ec779b8eSAndroid Build Coastguard Worker         // audio_policy services during system initialization.
296*ec779b8eSAndroid Build Coastguard Worker         std::thread notifier([]() {
297*ec779b8eSAndroid Build Coastguard Worker             AudioSystem::onNewAudioModulesAvailable();
298*ec779b8eSAndroid Build Coastguard Worker         });
299*ec779b8eSAndroid Build Coastguard Worker         notifier.detach();
300*ec779b8eSAndroid Build Coastguard Worker     }
301*ec779b8eSAndroid Build Coastguard Worker };
302*ec779b8eSAndroid Build Coastguard Worker 
303*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
304*ec779b8eSAndroid Build Coastguard Worker 
instantiate()305*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::instantiate() {
306*ec779b8eSAndroid Build Coastguard Worker     sp<IServiceManager> sm(defaultServiceManager());
307*ec779b8eSAndroid Build Coastguard Worker     sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME),
308*ec779b8eSAndroid Build Coastguard Worker                    new AudioFlingerServerAdapter(new AudioFlinger()), false,
309*ec779b8eSAndroid Build Coastguard Worker                    IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker 
AudioFlinger()312*ec779b8eSAndroid Build Coastguard Worker AudioFlinger::AudioFlinger()
313*ec779b8eSAndroid Build Coastguard Worker {
314*ec779b8eSAndroid Build Coastguard Worker     // Move the audio session unique ID generator start base as time passes to limit risk of
315*ec779b8eSAndroid Build Coastguard Worker     // generating the same ID again after an audioserver restart.
316*ec779b8eSAndroid Build Coastguard Worker     // This is important because clients will reuse previously allocated audio session IDs
317*ec779b8eSAndroid Build Coastguard Worker     // when reconnecting after an audioserver restart and newly allocated IDs may conflict with
318*ec779b8eSAndroid Build Coastguard Worker     // active clients.
319*ec779b8eSAndroid Build Coastguard Worker     // Moving the base by 1 for each elapsed second is a good compromise between avoiding overlap
320*ec779b8eSAndroid Build Coastguard Worker     // between allocation ranges and not reaching wrap around too soon.
321*ec779b8eSAndroid Build Coastguard Worker     timespec ts{};
322*ec779b8eSAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &ts);
323*ec779b8eSAndroid Build Coastguard Worker     // zero ID has a special meaning, so start allocation at least at AUDIO_UNIQUE_ID_USE_MAX
324*ec779b8eSAndroid Build Coastguard Worker     uint32_t movingBase = (uint32_t)std::max((long)1, ts.tv_sec);
325*ec779b8eSAndroid Build Coastguard Worker     // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
326*ec779b8eSAndroid Build Coastguard Worker     for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
327*ec779b8eSAndroid Build Coastguard Worker         mNextUniqueIds[use] =
328*ec779b8eSAndroid Build Coastguard Worker                 ((use == AUDIO_UNIQUE_ID_USE_SESSION || use == AUDIO_UNIQUE_ID_USE_CLIENT) ?
329*ec779b8eSAndroid Build Coastguard Worker                         movingBase : 1) * AUDIO_UNIQUE_ID_USE_MAX;
330*ec779b8eSAndroid Build Coastguard Worker     }
331*ec779b8eSAndroid Build Coastguard Worker 
332*ec779b8eSAndroid Build Coastguard Worker #if 1
333*ec779b8eSAndroid Build Coastguard Worker     // FIXME See bug 165702394 and bug 168511485
334*ec779b8eSAndroid Build Coastguard Worker     const bool doLog = false;
335*ec779b8eSAndroid Build Coastguard Worker #else
336*ec779b8eSAndroid Build Coastguard Worker     const bool doLog = property_get_bool("ro.test_harness", false);
337*ec779b8eSAndroid Build Coastguard Worker #endif
338*ec779b8eSAndroid Build Coastguard Worker     if (doLog) {
339*ec779b8eSAndroid Build Coastguard Worker         mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
340*ec779b8eSAndroid Build Coastguard Worker                 MemoryHeapBase::READ_ONLY);
341*ec779b8eSAndroid Build Coastguard Worker         (void) pthread_once(&sMediaLogOnce, sMediaLogInit);
342*ec779b8eSAndroid Build Coastguard Worker     }
343*ec779b8eSAndroid Build Coastguard Worker 
344*ec779b8eSAndroid Build Coastguard Worker     // reset battery stats.
345*ec779b8eSAndroid Build Coastguard Worker     // if the audio service has crashed, battery stats could be left
346*ec779b8eSAndroid Build Coastguard Worker     // in bad state, reset the state upon service start.
347*ec779b8eSAndroid Build Coastguard Worker     BatteryNotifier::getInstance().noteResetAudio();
348*ec779b8eSAndroid Build Coastguard Worker 
349*ec779b8eSAndroid Build Coastguard Worker     mMediaLogNotifier->run("MediaLogNotifier");
350*ec779b8eSAndroid Build Coastguard Worker 
351*ec779b8eSAndroid Build Coastguard Worker     // Notify that we have started (also called when audioserver service restarts)
352*ec779b8eSAndroid Build Coastguard Worker     mediametrics::LogItem(mMetricsId)
353*ec779b8eSAndroid Build Coastguard Worker         .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR)
354*ec779b8eSAndroid Build Coastguard Worker         .record();
355*ec779b8eSAndroid Build Coastguard Worker }
356*ec779b8eSAndroid Build Coastguard Worker 
onFirstRef()357*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::onFirstRef()
358*ec779b8eSAndroid Build Coastguard Worker {
359*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
360*ec779b8eSAndroid Build Coastguard Worker 
361*ec779b8eSAndroid Build Coastguard Worker     mMode = AUDIO_MODE_NORMAL;
362*ec779b8eSAndroid Build Coastguard Worker 
363*ec779b8eSAndroid Build Coastguard Worker     gAudioFlinger = this;  // we are already refcounted, store into atomic pointer.
364*ec779b8eSAndroid Build Coastguard Worker     mDeviceEffectManager = sp<DeviceEffectManager>::make(
365*ec779b8eSAndroid Build Coastguard Worker             sp<IAfDeviceEffectManagerCallback>::fromExisting(this)),
366*ec779b8eSAndroid Build Coastguard Worker     mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
367*ec779b8eSAndroid Build Coastguard Worker     mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
368*ec779b8eSAndroid Build Coastguard Worker 
369*ec779b8eSAndroid Build Coastguard Worker     if (mDevicesFactoryHal->getHalVersion() <= kMaxAAudioPropertyDeviceHalVersion) {
370*ec779b8eSAndroid Build Coastguard Worker         mAAudioBurstsPerBuffer = getAAudioMixerBurstCountFromSystemProperty();
371*ec779b8eSAndroid Build Coastguard Worker         mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty();
372*ec779b8eSAndroid Build Coastguard Worker     }
373*ec779b8eSAndroid Build Coastguard Worker 
374*ec779b8eSAndroid Build Coastguard Worker     mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this));
375*ec779b8eSAndroid Build Coastguard Worker     mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this),
376*ec779b8eSAndroid Build Coastguard Worker                                          mPatchPanel);
377*ec779b8eSAndroid Build Coastguard Worker }
378*ec779b8eSAndroid Build Coastguard Worker 
setAudioHalPids(const std::vector<pid_t> & pids)379*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setAudioHalPids(const std::vector<pid_t>& pids) {
380*ec779b8eSAndroid Build Coastguard Worker   mediautils::TimeCheck::setAudioHalPids(pids);
381*ec779b8eSAndroid Build Coastguard Worker   return NO_ERROR;
382*ec779b8eSAndroid Build Coastguard Worker }
383*ec779b8eSAndroid Build Coastguard Worker 
setVibratorInfos(const std::vector<media::AudioVibratorInfo> & vibratorInfos)384*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setVibratorInfos(
385*ec779b8eSAndroid Build Coastguard Worker         const std::vector<media::AudioVibratorInfo>& vibratorInfos) {
386*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
387*ec779b8eSAndroid Build Coastguard Worker     mAudioVibratorInfos = vibratorInfos;
388*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
389*ec779b8eSAndroid Build Coastguard Worker }
390*ec779b8eSAndroid Build Coastguard Worker 
updateSecondaryOutputs(const TrackSecondaryOutputsMap & trackSecondaryOutputs)391*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::updateSecondaryOutputs(
392*ec779b8eSAndroid Build Coastguard Worker         const TrackSecondaryOutputsMap& trackSecondaryOutputs) {
393*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
394*ec779b8eSAndroid Build Coastguard Worker     for (const auto& [trackId, secondaryOutputs] : trackSecondaryOutputs) {
395*ec779b8eSAndroid Build Coastguard Worker         size_t i = 0;
396*ec779b8eSAndroid Build Coastguard Worker         for (; i < mPlaybackThreads.size(); ++i) {
397*ec779b8eSAndroid Build Coastguard Worker             IAfPlaybackThread* thread = mPlaybackThreads.valueAt(i).get();
398*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _tl(thread->mutex());
399*ec779b8eSAndroid Build Coastguard Worker             sp<IAfTrack> track = thread->getTrackById_l(trackId);
400*ec779b8eSAndroid Build Coastguard Worker             if (track != nullptr) {
401*ec779b8eSAndroid Build Coastguard Worker                 ALOGD("%s trackId: %u", __func__, trackId);
402*ec779b8eSAndroid Build Coastguard Worker                 updateSecondaryOutputsForTrack_l(track.get(), thread, secondaryOutputs);
403*ec779b8eSAndroid Build Coastguard Worker                 break;
404*ec779b8eSAndroid Build Coastguard Worker             }
405*ec779b8eSAndroid Build Coastguard Worker         }
406*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(i >= mPlaybackThreads.size(),
407*ec779b8eSAndroid Build Coastguard Worker                  "%s cannot find track with id %u", __func__, trackId);
408*ec779b8eSAndroid Build Coastguard Worker     }
409*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
410*ec779b8eSAndroid Build Coastguard Worker }
411*ec779b8eSAndroid Build Coastguard Worker 
getMmapPolicyInfos(AudioMMapPolicyType policyType,std::vector<AudioMMapPolicyInfo> * policyInfos)412*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getMmapPolicyInfos(
413*ec779b8eSAndroid Build Coastguard Worker             AudioMMapPolicyType policyType, std::vector<AudioMMapPolicyInfo> *policyInfos) {
414*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
415*ec779b8eSAndroid Build Coastguard Worker     if (const auto it = mPolicyInfos.find(policyType); it != mPolicyInfos.end()) {
416*ec779b8eSAndroid Build Coastguard Worker         *policyInfos = it->second;
417*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
418*ec779b8eSAndroid Build Coastguard Worker     }
419*ec779b8eSAndroid Build Coastguard Worker     if (mDevicesFactoryHal->getHalVersion() > kMaxAAudioPropertyDeviceHalVersion) {
420*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard lock(hardwareMutex());
421*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mAudioHwDevs.size(); ++i) {
422*ec779b8eSAndroid Build Coastguard Worker             AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
423*ec779b8eSAndroid Build Coastguard Worker             std::vector<AudioMMapPolicyInfo> infos;
424*ec779b8eSAndroid Build Coastguard Worker             status_t status = dev->getMmapPolicyInfos(policyType, &infos);
425*ec779b8eSAndroid Build Coastguard Worker             if (status != NO_ERROR) {
426*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("Failed to query mmap policy info of %d, error %d",
427*ec779b8eSAndroid Build Coastguard Worker                       mAudioHwDevs.keyAt(i), status);
428*ec779b8eSAndroid Build Coastguard Worker                 continue;
429*ec779b8eSAndroid Build Coastguard Worker             }
430*ec779b8eSAndroid Build Coastguard Worker             policyInfos->insert(policyInfos->end(), infos.begin(), infos.end());
431*ec779b8eSAndroid Build Coastguard Worker         }
432*ec779b8eSAndroid Build Coastguard Worker         mPolicyInfos[policyType] = *policyInfos;
433*ec779b8eSAndroid Build Coastguard Worker     } else {
434*ec779b8eSAndroid Build Coastguard Worker         getMmapPolicyInfosFromSystemProperty(policyType, policyInfos);
435*ec779b8eSAndroid Build Coastguard Worker         mPolicyInfos[policyType] = *policyInfos;
436*ec779b8eSAndroid Build Coastguard Worker     }
437*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
438*ec779b8eSAndroid Build Coastguard Worker }
439*ec779b8eSAndroid Build Coastguard Worker 
getAAudioMixerBurstCount() const440*ec779b8eSAndroid Build Coastguard Worker int32_t AudioFlinger::getAAudioMixerBurstCount() const {
441*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
442*ec779b8eSAndroid Build Coastguard Worker     return mAAudioBurstsPerBuffer;
443*ec779b8eSAndroid Build Coastguard Worker }
444*ec779b8eSAndroid Build Coastguard Worker 
getAAudioHardwareBurstMinUsec() const445*ec779b8eSAndroid Build Coastguard Worker int32_t AudioFlinger::getAAudioHardwareBurstMinUsec() const {
446*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
447*ec779b8eSAndroid Build Coastguard Worker     return mAAudioHwBurstMinMicros;
448*ec779b8eSAndroid Build Coastguard Worker }
449*ec779b8eSAndroid Build Coastguard Worker 
setDeviceConnectedState(const struct audio_port_v7 * port,media::DeviceConnectedState state)450*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port,
451*ec779b8eSAndroid Build Coastguard Worker                                                media::DeviceConnectedState state) {
452*ec779b8eSAndroid Build Coastguard Worker     status_t final_result = NO_INIT;
453*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
454*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
455*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_SET_CONNECTED_STATE;
456*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
457*ec779b8eSAndroid Build Coastguard Worker         sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
458*ec779b8eSAndroid Build Coastguard Worker         status_t result = state == media::DeviceConnectedState::PREPARE_TO_DISCONNECT
459*ec779b8eSAndroid Build Coastguard Worker                 ? dev->prepareToDisconnectExternalDevice(port)
460*ec779b8eSAndroid Build Coastguard Worker                 : dev->setConnectedState(port, state == media::DeviceConnectedState::CONNECTED);
461*ec779b8eSAndroid Build Coastguard Worker         // Same logic as with setParameter: it's a success if at least one
462*ec779b8eSAndroid Build Coastguard Worker         // HAL module accepts the update.
463*ec779b8eSAndroid Build Coastguard Worker         if (final_result != NO_ERROR) {
464*ec779b8eSAndroid Build Coastguard Worker             final_result = result;
465*ec779b8eSAndroid Build Coastguard Worker         }
466*ec779b8eSAndroid Build Coastguard Worker     }
467*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
468*ec779b8eSAndroid Build Coastguard Worker     return final_result;
469*ec779b8eSAndroid Build Coastguard Worker }
470*ec779b8eSAndroid Build Coastguard Worker 
setSimulateDeviceConnections(bool enabled)471*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setSimulateDeviceConnections(bool enabled) {
472*ec779b8eSAndroid Build Coastguard Worker     bool at_least_one_succeeded = false;
473*ec779b8eSAndroid Build Coastguard Worker     status_t last_error = INVALID_OPERATION;
474*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
475*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
476*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_SET_SIMULATE_CONNECTIONS;
477*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
478*ec779b8eSAndroid Build Coastguard Worker         sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
479*ec779b8eSAndroid Build Coastguard Worker         status_t result = dev->setSimulateDeviceConnections(enabled);
480*ec779b8eSAndroid Build Coastguard Worker         if (result == OK) {
481*ec779b8eSAndroid Build Coastguard Worker             at_least_one_succeeded = true;
482*ec779b8eSAndroid Build Coastguard Worker         } else {
483*ec779b8eSAndroid Build Coastguard Worker             last_error = result;
484*ec779b8eSAndroid Build Coastguard Worker         }
485*ec779b8eSAndroid Build Coastguard Worker     }
486*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
487*ec779b8eSAndroid Build Coastguard Worker     return at_least_one_succeeded ? OK : last_error;
488*ec779b8eSAndroid Build Coastguard Worker }
489*ec779b8eSAndroid Build Coastguard Worker 
490*ec779b8eSAndroid Build Coastguard Worker // getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
getDefaultVibratorInfo_l() const491*ec779b8eSAndroid Build Coastguard Worker std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() const {
492*ec779b8eSAndroid Build Coastguard Worker     if (mAudioVibratorInfos.empty()) {
493*ec779b8eSAndroid Build Coastguard Worker         return {};
494*ec779b8eSAndroid Build Coastguard Worker     }
495*ec779b8eSAndroid Build Coastguard Worker     return mAudioVibratorInfos.front();
496*ec779b8eSAndroid Build Coastguard Worker }
497*ec779b8eSAndroid Build Coastguard Worker 
~AudioFlinger()498*ec779b8eSAndroid Build Coastguard Worker AudioFlinger::~AudioFlinger()
499*ec779b8eSAndroid Build Coastguard Worker {
500*ec779b8eSAndroid Build Coastguard Worker     while (!mRecordThreads.isEmpty()) {
501*ec779b8eSAndroid Build Coastguard Worker         // closeInput_nonvirtual() will remove specified entry from mRecordThreads
502*ec779b8eSAndroid Build Coastguard Worker         closeInput_nonvirtual(mRecordThreads.keyAt(0));
503*ec779b8eSAndroid Build Coastguard Worker     }
504*ec779b8eSAndroid Build Coastguard Worker     while (!mPlaybackThreads.isEmpty()) {
505*ec779b8eSAndroid Build Coastguard Worker         // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
506*ec779b8eSAndroid Build Coastguard Worker         closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
507*ec779b8eSAndroid Build Coastguard Worker     }
508*ec779b8eSAndroid Build Coastguard Worker     while (!mMmapThreads.isEmpty()) {
509*ec779b8eSAndroid Build Coastguard Worker         const audio_io_handle_t io = mMmapThreads.keyAt(0);
510*ec779b8eSAndroid Build Coastguard Worker         if (mMmapThreads.valueAt(0)->isOutput()) {
511*ec779b8eSAndroid Build Coastguard Worker             closeOutput_nonvirtual(io); // removes entry from mMmapThreads
512*ec779b8eSAndroid Build Coastguard Worker         } else {
513*ec779b8eSAndroid Build Coastguard Worker             closeInput_nonvirtual(io);  // removes entry from mMmapThreads
514*ec779b8eSAndroid Build Coastguard Worker         }
515*ec779b8eSAndroid Build Coastguard Worker     }
516*ec779b8eSAndroid Build Coastguard Worker 
517*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
518*ec779b8eSAndroid Build Coastguard Worker         // no hardwareMutex() needed, as there are no other references to this
519*ec779b8eSAndroid Build Coastguard Worker         delete mAudioHwDevs.valueAt(i);
520*ec779b8eSAndroid Build Coastguard Worker     }
521*ec779b8eSAndroid Build Coastguard Worker 
522*ec779b8eSAndroid Build Coastguard Worker     // Tell media.log service about any old writers that still need to be unregistered
523*ec779b8eSAndroid Build Coastguard Worker     if (sMediaLogService != 0) {
524*ec779b8eSAndroid Build Coastguard Worker         for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
525*ec779b8eSAndroid Build Coastguard Worker             sp<IMemory> iMemory(mUnregisteredWriters.top()->getIMemory());
526*ec779b8eSAndroid Build Coastguard Worker             mUnregisteredWriters.pop();
527*ec779b8eSAndroid Build Coastguard Worker             sMediaLogService->unregisterWriter(iMemory);
528*ec779b8eSAndroid Build Coastguard Worker         }
529*ec779b8eSAndroid Build Coastguard Worker     }
530*ec779b8eSAndroid Build Coastguard Worker     mMediaLogNotifier->requestExit();
531*ec779b8eSAndroid Build Coastguard Worker     mPatchCommandThread->exit();
532*ec779b8eSAndroid Build Coastguard Worker }
533*ec779b8eSAndroid Build Coastguard Worker 
534*ec779b8eSAndroid Build Coastguard Worker //static
535*ec779b8eSAndroid Build Coastguard Worker __attribute__ ((visibility ("default")))
openMmapStream(MmapStreamInterface::stream_direction_t direction,const audio_attributes_t * attr,audio_config_base_t * config,const AudioClient & client,DeviceIdVector * deviceIds,audio_session_t * sessionId,const sp<MmapStreamCallback> & callback,sp<MmapStreamInterface> & interface,audio_port_handle_t * handle)536*ec779b8eSAndroid Build Coastguard Worker status_t MmapStreamInterface::openMmapStream(MmapStreamInterface::stream_direction_t direction,
537*ec779b8eSAndroid Build Coastguard Worker                                              const audio_attributes_t *attr,
538*ec779b8eSAndroid Build Coastguard Worker                                              audio_config_base_t *config,
539*ec779b8eSAndroid Build Coastguard Worker                                              const AudioClient& client,
540*ec779b8eSAndroid Build Coastguard Worker                                              DeviceIdVector *deviceIds,
541*ec779b8eSAndroid Build Coastguard Worker                                              audio_session_t *sessionId,
542*ec779b8eSAndroid Build Coastguard Worker                                              const sp<MmapStreamCallback>& callback,
543*ec779b8eSAndroid Build Coastguard Worker                                              sp<MmapStreamInterface>& interface,
544*ec779b8eSAndroid Build Coastguard Worker                                              audio_port_handle_t *handle)
545*ec779b8eSAndroid Build Coastguard Worker {
546*ec779b8eSAndroid Build Coastguard Worker     // TODO(b/292281786): Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
547*ec779b8eSAndroid Build Coastguard Worker     // This allows moving oboeservice (AAudio) to a separate process in the future.
548*ec779b8eSAndroid Build Coastguard Worker     sp<AudioFlinger> af = AudioFlinger::gAudioFlinger.load();  // either nullptr or singleton AF.
549*ec779b8eSAndroid Build Coastguard Worker     status_t ret = NO_INIT;
550*ec779b8eSAndroid Build Coastguard Worker     if (af != 0) {
551*ec779b8eSAndroid Build Coastguard Worker         ret = af->openMmapStream(
552*ec779b8eSAndroid Build Coastguard Worker                 direction, attr, config, client, deviceIds,
553*ec779b8eSAndroid Build Coastguard Worker                 sessionId, callback, interface, handle);
554*ec779b8eSAndroid Build Coastguard Worker     }
555*ec779b8eSAndroid Build Coastguard Worker     return ret;
556*ec779b8eSAndroid Build Coastguard Worker }
557*ec779b8eSAndroid Build Coastguard Worker 
openMmapStream(MmapStreamInterface::stream_direction_t direction,const audio_attributes_t * attr,audio_config_base_t * config,const AudioClient & client,DeviceIdVector * deviceIds,audio_session_t * sessionId,const sp<MmapStreamCallback> & callback,sp<MmapStreamInterface> & interface,audio_port_handle_t * handle)558*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t direction,
559*ec779b8eSAndroid Build Coastguard Worker                                       const audio_attributes_t *attr,
560*ec779b8eSAndroid Build Coastguard Worker                                       audio_config_base_t *config,
561*ec779b8eSAndroid Build Coastguard Worker                                       const AudioClient& client,
562*ec779b8eSAndroid Build Coastguard Worker                                       DeviceIdVector *deviceIds,
563*ec779b8eSAndroid Build Coastguard Worker                                       audio_session_t *sessionId,
564*ec779b8eSAndroid Build Coastguard Worker                                       const sp<MmapStreamCallback>& callback,
565*ec779b8eSAndroid Build Coastguard Worker                                       sp<MmapStreamInterface>& interface,
566*ec779b8eSAndroid Build Coastguard Worker                                       audio_port_handle_t *handle)
567*ec779b8eSAndroid Build Coastguard Worker {
568*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
569*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
570*ec779b8eSAndroid Build Coastguard Worker         return ret;
571*ec779b8eSAndroid Build Coastguard Worker     }
572*ec779b8eSAndroid Build Coastguard Worker     audio_session_t actualSessionId = *sessionId;
573*ec779b8eSAndroid Build Coastguard Worker     if (actualSessionId == AUDIO_SESSION_ALLOCATE) {
574*ec779b8eSAndroid Build Coastguard Worker         actualSessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
575*ec779b8eSAndroid Build Coastguard Worker     }
576*ec779b8eSAndroid Build Coastguard Worker     audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
577*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
578*ec779b8eSAndroid Build Coastguard Worker     audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
579*ec779b8eSAndroid Build Coastguard Worker     audio_attributes_t localAttr = *attr;
580*ec779b8eSAndroid Build Coastguard Worker 
581*ec779b8eSAndroid Build Coastguard Worker     // TODO b/182392553: refactor or make clearer
582*ec779b8eSAndroid Build Coastguard Worker     AttributionSourceState adjAttributionSource;
583*ec779b8eSAndroid Build Coastguard Worker     if (!com::android::media::audio::audioserver_permissions()) {
584*ec779b8eSAndroid Build Coastguard Worker         pid_t clientPid =
585*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid));
586*ec779b8eSAndroid Build Coastguard Worker         bool updatePid = (clientPid == (pid_t)-1);
587*ec779b8eSAndroid Build Coastguard Worker         const uid_t callingUid = IPCThreadState::self()->getCallingUid();
588*ec779b8eSAndroid Build Coastguard Worker 
589*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = client.attributionSource;
590*ec779b8eSAndroid Build Coastguard Worker         if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
591*ec779b8eSAndroid Build Coastguard Worker             uid_t clientUid =
592*ec779b8eSAndroid Build Coastguard Worker                 VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(client.attributionSource.uid));
593*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(clientUid != callingUid,
594*ec779b8eSAndroid Build Coastguard Worker                     "%s uid %d tried to pass itself off as %d",
595*ec779b8eSAndroid Build Coastguard Worker                     __FUNCTION__, callingUid, clientUid);
596*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
597*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_uid_t_int32_t(callingUid));
598*ec779b8eSAndroid Build Coastguard Worker             updatePid = true;
599*ec779b8eSAndroid Build Coastguard Worker         }
600*ec779b8eSAndroid Build Coastguard Worker         if (updatePid) {
601*ec779b8eSAndroid Build Coastguard Worker             const pid_t callingPid = IPCThreadState::self()->getCallingPid();
602*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
603*ec779b8eSAndroid Build Coastguard Worker                      "%s uid %d pid %d tried to pass itself off as pid %d",
604*ec779b8eSAndroid Build Coastguard Worker                      __func__, callingUid, callingPid, clientPid);
605*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
606*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_pid_t_int32_t(callingPid));
607*ec779b8eSAndroid Build Coastguard Worker         }
608*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = afutils::checkAttributionSourcePackage(
609*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource);
610*ec779b8eSAndroid Build Coastguard Worker     } else {
611*ec779b8eSAndroid Build Coastguard Worker         auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
612*ec779b8eSAndroid Build Coastguard Worker                 validateAttributionFromContextOrTrustedCaller(client.attributionSource,
613*ec779b8eSAndroid Build Coastguard Worker                 getPermissionProvider()
614*ec779b8eSAndroid Build Coastguard Worker                 ));
615*ec779b8eSAndroid Build Coastguard Worker         // TODO pass wrapped object around
616*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
617*ec779b8eSAndroid Build Coastguard Worker     }
618*ec779b8eSAndroid Build Coastguard Worker 
619*ec779b8eSAndroid Build Coastguard Worker     if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
620*ec779b8eSAndroid Build Coastguard Worker         audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
621*ec779b8eSAndroid Build Coastguard Worker         fullConfig.sample_rate = config->sample_rate;
622*ec779b8eSAndroid Build Coastguard Worker         fullConfig.channel_mask = config->channel_mask;
623*ec779b8eSAndroid Build Coastguard Worker         fullConfig.format = config->format;
624*ec779b8eSAndroid Build Coastguard Worker         std::vector<audio_io_handle_t> secondaryOutputs;
625*ec779b8eSAndroid Build Coastguard Worker         bool isSpatialized;
626*ec779b8eSAndroid Build Coastguard Worker         bool isBitPerfect;
627*ec779b8eSAndroid Build Coastguard Worker         float volume;
628*ec779b8eSAndroid Build Coastguard Worker         bool muted;
629*ec779b8eSAndroid Build Coastguard Worker         ret = AudioSystem::getOutputForAttr(&localAttr, &io,
630*ec779b8eSAndroid Build Coastguard Worker                                             actualSessionId,
631*ec779b8eSAndroid Build Coastguard Worker                                             &streamType, adjAttributionSource,
632*ec779b8eSAndroid Build Coastguard Worker                                             &fullConfig,
633*ec779b8eSAndroid Build Coastguard Worker                                             (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
634*ec779b8eSAndroid Build Coastguard Worker                                                     AUDIO_OUTPUT_FLAG_DIRECT),
635*ec779b8eSAndroid Build Coastguard Worker                                             deviceIds, &portId, &secondaryOutputs,
636*ec779b8eSAndroid Build Coastguard Worker                                             &isSpatialized,
637*ec779b8eSAndroid Build Coastguard Worker                                             &isBitPerfect,
638*ec779b8eSAndroid Build Coastguard Worker                                             &volume,
639*ec779b8eSAndroid Build Coastguard Worker                                             &muted);
640*ec779b8eSAndroid Build Coastguard Worker         if (ret != NO_ERROR) {
641*ec779b8eSAndroid Build Coastguard Worker             config->sample_rate = fullConfig.sample_rate;
642*ec779b8eSAndroid Build Coastguard Worker             config->channel_mask = fullConfig.channel_mask;
643*ec779b8eSAndroid Build Coastguard Worker             config->format = fullConfig.format;
644*ec779b8eSAndroid Build Coastguard Worker         }
645*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(!secondaryOutputs.empty(),
646*ec779b8eSAndroid Build Coastguard Worker                  "%s does not support secondary outputs, ignoring them", __func__);
647*ec779b8eSAndroid Build Coastguard Worker     } else {
648*ec779b8eSAndroid Build Coastguard Worker         audio_port_handle_t deviceId = getFirstDeviceId(*deviceIds);
649*ec779b8eSAndroid Build Coastguard Worker         ret = AudioSystem::getInputForAttr(&localAttr, &io,
650*ec779b8eSAndroid Build Coastguard Worker                                               RECORD_RIID_INVALID,
651*ec779b8eSAndroid Build Coastguard Worker                                               actualSessionId,
652*ec779b8eSAndroid Build Coastguard Worker                                               adjAttributionSource,
653*ec779b8eSAndroid Build Coastguard Worker                                               config,
654*ec779b8eSAndroid Build Coastguard Worker                                               AUDIO_INPUT_FLAG_MMAP_NOIRQ, &deviceId, &portId);
655*ec779b8eSAndroid Build Coastguard Worker         deviceIds->clear();
656*ec779b8eSAndroid Build Coastguard Worker         if (deviceId != AUDIO_PORT_HANDLE_NONE) {
657*ec779b8eSAndroid Build Coastguard Worker             deviceIds->push_back(deviceId);
658*ec779b8eSAndroid Build Coastguard Worker         }
659*ec779b8eSAndroid Build Coastguard Worker     }
660*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
661*ec779b8eSAndroid Build Coastguard Worker         return ret;
662*ec779b8eSAndroid Build Coastguard Worker     }
663*ec779b8eSAndroid Build Coastguard Worker 
664*ec779b8eSAndroid Build Coastguard Worker     // use unique_lock as we may selectively unlock.
665*ec779b8eSAndroid Build Coastguard Worker     audio_utils::unique_lock l(mutex());
666*ec779b8eSAndroid Build Coastguard Worker 
667*ec779b8eSAndroid Build Coastguard Worker     // at this stage, a MmapThread was created when openOutput() or openInput() was called by
668*ec779b8eSAndroid Build Coastguard Worker     // audio policy manager and we can retrieve it
669*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfMmapThread> thread = mMmapThreads.valueFor(io);
670*ec779b8eSAndroid Build Coastguard Worker     if (thread != 0) {
671*ec779b8eSAndroid Build Coastguard Worker         interface = IAfMmapThread::createMmapStreamInterfaceAdapter(thread);
672*ec779b8eSAndroid Build Coastguard Worker         thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceIds, portId);
673*ec779b8eSAndroid Build Coastguard Worker         *handle = portId;
674*ec779b8eSAndroid Build Coastguard Worker         *sessionId = actualSessionId;
675*ec779b8eSAndroid Build Coastguard Worker         config->sample_rate = thread->sampleRate();
676*ec779b8eSAndroid Build Coastguard Worker         config->channel_mask = thread->channelMask();
677*ec779b8eSAndroid Build Coastguard Worker         config->format = thread->format();
678*ec779b8eSAndroid Build Coastguard Worker     } else {
679*ec779b8eSAndroid Build Coastguard Worker         l.unlock();
680*ec779b8eSAndroid Build Coastguard Worker         if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
681*ec779b8eSAndroid Build Coastguard Worker             AudioSystem::releaseOutput(portId);
682*ec779b8eSAndroid Build Coastguard Worker         } else {
683*ec779b8eSAndroid Build Coastguard Worker             AudioSystem::releaseInput(portId);
684*ec779b8eSAndroid Build Coastguard Worker         }
685*ec779b8eSAndroid Build Coastguard Worker         ret = NO_INIT;
686*ec779b8eSAndroid Build Coastguard Worker         // we don't reacquire the lock here as nothing left to do.
687*ec779b8eSAndroid Build Coastguard Worker     }
688*ec779b8eSAndroid Build Coastguard Worker 
689*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s done status %d portId %d", __FUNCTION__, ret, portId);
690*ec779b8eSAndroid Build Coastguard Worker 
691*ec779b8eSAndroid Build Coastguard Worker     return ret;
692*ec779b8eSAndroid Build Coastguard Worker }
693*ec779b8eSAndroid Build Coastguard Worker 
addEffectToHal(const struct audio_port_config * device,const sp<EffectHalInterface> & effect)694*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::addEffectToHal(
695*ec779b8eSAndroid Build Coastguard Worker         const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
696*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
697*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
698*ec779b8eSAndroid Build Coastguard Worker     if (audioHwDevice == nullptr) {
699*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
700*ec779b8eSAndroid Build Coastguard Worker     }
701*ec779b8eSAndroid Build Coastguard Worker     return audioHwDevice->hwDevice()->addDeviceEffect(device, effect);
702*ec779b8eSAndroid Build Coastguard Worker }
703*ec779b8eSAndroid Build Coastguard Worker 
removeEffectFromHal(const struct audio_port_config * device,const sp<EffectHalInterface> & effect)704*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::removeEffectFromHal(
705*ec779b8eSAndroid Build Coastguard Worker         const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
706*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
707*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
708*ec779b8eSAndroid Build Coastguard Worker     if (audioHwDevice == nullptr) {
709*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
710*ec779b8eSAndroid Build Coastguard Worker     }
711*ec779b8eSAndroid Build Coastguard Worker     return audioHwDevice->hwDevice()->removeDeviceEffect(device, effect);
712*ec779b8eSAndroid Build Coastguard Worker }
713*ec779b8eSAndroid Build Coastguard Worker 
714*ec779b8eSAndroid Build Coastguard Worker static const char * const audio_interfaces[] = {
715*ec779b8eSAndroid Build Coastguard Worker     AUDIO_HARDWARE_MODULE_ID_PRIMARY,
716*ec779b8eSAndroid Build Coastguard Worker     AUDIO_HARDWARE_MODULE_ID_A2DP,
717*ec779b8eSAndroid Build Coastguard Worker     AUDIO_HARDWARE_MODULE_ID_USB,
718*ec779b8eSAndroid Build Coastguard Worker };
719*ec779b8eSAndroid Build Coastguard Worker 
findSuitableHwDev_l(audio_module_handle_t module,audio_devices_t deviceType)720*ec779b8eSAndroid Build Coastguard Worker AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
721*ec779b8eSAndroid Build Coastguard Worker         audio_module_handle_t module,
722*ec779b8eSAndroid Build Coastguard Worker         audio_devices_t deviceType)
723*ec779b8eSAndroid Build Coastguard Worker {
724*ec779b8eSAndroid Build Coastguard Worker     // if module is 0, the request comes from an old policy manager and we should load
725*ec779b8eSAndroid Build Coastguard Worker     // well known modules
726*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
727*ec779b8eSAndroid Build Coastguard Worker     if (module == 0) {
728*ec779b8eSAndroid Build Coastguard Worker         ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
729*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < arraysize(audio_interfaces); i++) {
730*ec779b8eSAndroid Build Coastguard Worker             loadHwModule_ll(audio_interfaces[i]);
731*ec779b8eSAndroid Build Coastguard Worker         }
732*ec779b8eSAndroid Build Coastguard Worker         // then try to find a module supporting the requested device.
733*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
734*ec779b8eSAndroid Build Coastguard Worker             AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
735*ec779b8eSAndroid Build Coastguard Worker             sp<DeviceHalInterface> dev = audioHwDevice->hwDevice();
736*ec779b8eSAndroid Build Coastguard Worker             uint32_t supportedDevices;
737*ec779b8eSAndroid Build Coastguard Worker             if (dev->getSupportedDevices(&supportedDevices) == OK &&
738*ec779b8eSAndroid Build Coastguard Worker                     (supportedDevices & deviceType) == deviceType) {
739*ec779b8eSAndroid Build Coastguard Worker                 return audioHwDevice;
740*ec779b8eSAndroid Build Coastguard Worker             }
741*ec779b8eSAndroid Build Coastguard Worker         }
742*ec779b8eSAndroid Build Coastguard Worker     } else {
743*ec779b8eSAndroid Build Coastguard Worker         // check a match for the requested module handle
744*ec779b8eSAndroid Build Coastguard Worker         AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
745*ec779b8eSAndroid Build Coastguard Worker         if (audioHwDevice != NULL) {
746*ec779b8eSAndroid Build Coastguard Worker             return audioHwDevice;
747*ec779b8eSAndroid Build Coastguard Worker         }
748*ec779b8eSAndroid Build Coastguard Worker     }
749*ec779b8eSAndroid Build Coastguard Worker 
750*ec779b8eSAndroid Build Coastguard Worker     return NULL;
751*ec779b8eSAndroid Build Coastguard Worker }
752*ec779b8eSAndroid Build Coastguard Worker 
dumpClients_ll(int fd,bool dumpAllocators)753*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::dumpClients_ll(int fd, bool dumpAllocators) {
754*ec779b8eSAndroid Build Coastguard Worker     String8 result;
755*ec779b8eSAndroid Build Coastguard Worker 
756*ec779b8eSAndroid Build Coastguard Worker     if (dumpAllocators) {
757*ec779b8eSAndroid Build Coastguard Worker         result.append("Client Allocators:\n");
758*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mClients.size(); ++i) {
759*ec779b8eSAndroid Build Coastguard Worker             sp<Client> client = mClients.valueAt(i).promote();
760*ec779b8eSAndroid Build Coastguard Worker             if (client != 0) {
761*ec779b8eSAndroid Build Coastguard Worker               result.appendFormat("Client: %d\n", client->pid());
762*ec779b8eSAndroid Build Coastguard Worker               result.append(client->allocator().dump().c_str());
763*ec779b8eSAndroid Build Coastguard Worker             }
764*ec779b8eSAndroid Build Coastguard Worker         }
765*ec779b8eSAndroid Build Coastguard Worker     }
766*ec779b8eSAndroid Build Coastguard Worker 
767*ec779b8eSAndroid Build Coastguard Worker     result.append("Notification Clients:\n");
768*ec779b8eSAndroid Build Coastguard Worker     result.append("   pid    uid  name\n");
769*ec779b8eSAndroid Build Coastguard Worker     for (const auto& [ _, client ] : mNotificationClients) {
770*ec779b8eSAndroid Build Coastguard Worker         const uid_t uid = client->getUid();
771*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<const mediautils::UidInfo::Info> info =
772*ec779b8eSAndroid Build Coastguard Worker                 mediautils::UidInfo::getInfo(uid);
773*ec779b8eSAndroid Build Coastguard Worker         result.appendFormat("%6d %6u  %s\n",
774*ec779b8eSAndroid Build Coastguard Worker                 client->getPid(), uid, info->package.c_str());
775*ec779b8eSAndroid Build Coastguard Worker     }
776*ec779b8eSAndroid Build Coastguard Worker 
777*ec779b8eSAndroid Build Coastguard Worker     result.append("Global session refs:\n");
778*ec779b8eSAndroid Build Coastguard Worker     result.append("  session  cnt     pid    uid  name\n");
779*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
780*ec779b8eSAndroid Build Coastguard Worker         AudioSessionRef *r = mAudioSessionRefs[i];
781*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<const mediautils::UidInfo::Info> info =
782*ec779b8eSAndroid Build Coastguard Worker                 mediautils::UidInfo::getInfo(r->mUid);
783*ec779b8eSAndroid Build Coastguard Worker         result.appendFormat("  %7d %4d %7d %6u  %s\n", r->mSessionid, r->mCnt, r->mPid,
784*ec779b8eSAndroid Build Coastguard Worker                 r->mUid, info->package.c_str());
785*ec779b8eSAndroid Build Coastguard Worker     }
786*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, result);
787*ec779b8eSAndroid Build Coastguard Worker }
788*ec779b8eSAndroid Build Coastguard Worker 
789*ec779b8eSAndroid Build Coastguard Worker 
dumpInternals_l(int fd)790*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::dumpInternals_l(int fd) {
791*ec779b8eSAndroid Build Coastguard Worker     const size_t SIZE = 256;
792*ec779b8eSAndroid Build Coastguard Worker     char buffer[SIZE];
793*ec779b8eSAndroid Build Coastguard Worker     String8 result;
794*ec779b8eSAndroid Build Coastguard Worker     hardware_call_state hardwareStatus = mHardwareStatus;
795*ec779b8eSAndroid Build Coastguard Worker 
796*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
797*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
798*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, result);
799*ec779b8eSAndroid Build Coastguard Worker 
800*ec779b8eSAndroid Build Coastguard Worker     dprintf(fd, "Vibrator infos(size=%zu):\n", mAudioVibratorInfos.size());
801*ec779b8eSAndroid Build Coastguard Worker     for (const auto& vibratorInfo : mAudioVibratorInfos) {
802*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "  - %s\n", vibratorInfo.toString().c_str());
803*ec779b8eSAndroid Build Coastguard Worker     }
804*ec779b8eSAndroid Build Coastguard Worker     dprintf(fd, "Bluetooth latency modes are %senabled\n",
805*ec779b8eSAndroid Build Coastguard Worker             mBluetoothLatencyModesEnabled ? "" : "not ");
806*ec779b8eSAndroid Build Coastguard Worker }
807*ec779b8eSAndroid Build Coastguard Worker 
dumpStats(int fd)808*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::dumpStats(int fd) {
809*ec779b8eSAndroid Build Coastguard Worker     // Dump binder stats
810*ec779b8eSAndroid Build Coastguard Worker     dprintf(fd, "\nIAudioFlinger binder call profile:\n");
811*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, getIAudioFlingerStatistics().dump());
812*ec779b8eSAndroid Build Coastguard Worker 
813*ec779b8eSAndroid Build Coastguard Worker     extern mediautils::MethodStatistics<int>& getIEffectStatistics();
814*ec779b8eSAndroid Build Coastguard Worker     dprintf(fd, "\nIEffect binder call profile:\n");
815*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, getIEffectStatistics().dump());
816*ec779b8eSAndroid Build Coastguard Worker 
817*ec779b8eSAndroid Build Coastguard Worker     // Automatically fetch HIDL or AIDL statistics.
818*ec779b8eSAndroid Build Coastguard Worker     const std::string_view halType = (mDevicesFactoryHal->getHalVersion().getType() ==
819*ec779b8eSAndroid Build Coastguard Worker                               AudioHalVersionInfo::Type::HIDL)
820*ec779b8eSAndroid Build Coastguard Worker                                      ? METHOD_STATISTICS_MODULE_NAME_AUDIO_HIDL
821*ec779b8eSAndroid Build Coastguard Worker                                      : METHOD_STATISTICS_MODULE_NAME_AUDIO_AIDL;
822*ec779b8eSAndroid Build Coastguard Worker     const std::shared_ptr<std::vector<std::string>> halClassNames =
823*ec779b8eSAndroid Build Coastguard Worker             mediautils::getStatisticsClassesForModule(halType);
824*ec779b8eSAndroid Build Coastguard Worker     if (halClassNames) {
825*ec779b8eSAndroid Build Coastguard Worker         for (const auto& className : *halClassNames) {
826*ec779b8eSAndroid Build Coastguard Worker             auto stats = mediautils::getStatisticsForClass(className);
827*ec779b8eSAndroid Build Coastguard Worker             if (stats) {
828*ec779b8eSAndroid Build Coastguard Worker                 dprintf(fd, "\n%s binder call profile:\n", className.c_str());
829*ec779b8eSAndroid Build Coastguard Worker                 writeStr(fd, stats->dump());
830*ec779b8eSAndroid Build Coastguard Worker             }
831*ec779b8eSAndroid Build Coastguard Worker         }
832*ec779b8eSAndroid Build Coastguard Worker     }
833*ec779b8eSAndroid Build Coastguard Worker 
834*ec779b8eSAndroid Build Coastguard Worker     dprintf(fd, "\nTimeCheck:\n");
835*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, mediautils::TimeCheck::toString());
836*ec779b8eSAndroid Build Coastguard Worker     dprintf(fd, "\n");
837*ec779b8eSAndroid Build Coastguard Worker     // dump mutex stats
838*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, audio_utils::mutex::all_stats_to_string());
839*ec779b8eSAndroid Build Coastguard Worker     // dump held mutexes
840*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, audio_utils::mutex::all_threads_to_string());
841*ec779b8eSAndroid Build Coastguard Worker 
842*ec779b8eSAndroid Build Coastguard Worker }
843*ec779b8eSAndroid Build Coastguard Worker 
dumpPermissionDenial(int fd)844*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::dumpPermissionDenial(int fd) {
845*ec779b8eSAndroid Build Coastguard Worker     const size_t SIZE = 256;
846*ec779b8eSAndroid Build Coastguard Worker     char buffer[SIZE];
847*ec779b8eSAndroid Build Coastguard Worker     String8 result;
848*ec779b8eSAndroid Build Coastguard Worker     snprintf(buffer, SIZE, "Permission Denial: "
849*ec779b8eSAndroid Build Coastguard Worker             "can't dump AudioFlinger from pid=%d, uid=%d\n",
850*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingPid(),
851*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingUid());
852*ec779b8eSAndroid Build Coastguard Worker     result.append(buffer);
853*ec779b8eSAndroid Build Coastguard Worker     writeStr(fd, result);
854*ec779b8eSAndroid Build Coastguard Worker }
855*ec779b8eSAndroid Build Coastguard Worker 
dump_printHelp(int fd)856*ec779b8eSAndroid Build Coastguard Worker static void dump_printHelp(int fd) {
857*ec779b8eSAndroid Build Coastguard Worker     constexpr static auto helpStr =
858*ec779b8eSAndroid Build Coastguard Worker             "AudioFlinger dumpsys help options\n"
859*ec779b8eSAndroid Build Coastguard Worker             "  -h/--help: Print this help text\n"
860*ec779b8eSAndroid Build Coastguard Worker             "  --hal: Include dump of audio hal\n"
861*ec779b8eSAndroid Build Coastguard Worker             "  --stats: Include call/lock/watchdog stats\n"
862*ec779b8eSAndroid Build Coastguard Worker             "  --effects: Include effect definitions\n"
863*ec779b8eSAndroid Build Coastguard Worker             "  --memory: Include memory dump\n"
864*ec779b8eSAndroid Build Coastguard Worker             "  -a/--all: Print all except --memory\n"sv;
865*ec779b8eSAndroid Build Coastguard Worker 
866*ec779b8eSAndroid Build Coastguard Worker     write(fd, helpStr.data(), helpStr.length());
867*ec779b8eSAndroid Build Coastguard Worker }
868*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd,const Vector<String16> & args)869*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
870*ec779b8eSAndroid Build Coastguard Worker {
871*ec779b8eSAndroid Build Coastguard Worker     using afutils::FallibleLockGuard;
872*ec779b8eSAndroid Build Coastguard Worker     if (!dumpAllowed()) {
873*ec779b8eSAndroid Build Coastguard Worker         dumpPermissionDenial(fd);
874*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
875*ec779b8eSAndroid Build Coastguard Worker     }
876*ec779b8eSAndroid Build Coastguard Worker     // Arg parsing
877*ec779b8eSAndroid Build Coastguard Worker     struct {
878*ec779b8eSAndroid Build Coastguard Worker         bool shouldDumpMem, shouldDumpStats, shouldDumpHal, shouldDumpEffects;
879*ec779b8eSAndroid Build Coastguard Worker     } parsedArgs {}; // zero-init
880*ec779b8eSAndroid Build Coastguard Worker 
881*ec779b8eSAndroid Build Coastguard Worker     for (const auto& arg : args) {
882*ec779b8eSAndroid Build Coastguard Worker         const String8 utf8arg{arg};
883*ec779b8eSAndroid Build Coastguard Worker         if (utf8arg == "-h" || utf8arg == "--help") {
884*ec779b8eSAndroid Build Coastguard Worker             dump_printHelp(fd);
885*ec779b8eSAndroid Build Coastguard Worker             return NO_ERROR;
886*ec779b8eSAndroid Build Coastguard Worker         }
887*ec779b8eSAndroid Build Coastguard Worker         if (utf8arg == "-a" || utf8arg == "--all") {
888*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpStats = true;
889*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpHal = true;
890*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpEffects = true;
891*ec779b8eSAndroid Build Coastguard Worker             continue;
892*ec779b8eSAndroid Build Coastguard Worker         }
893*ec779b8eSAndroid Build Coastguard Worker         if (utf8arg == "--hal") {
894*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpHal = true;
895*ec779b8eSAndroid Build Coastguard Worker             continue;
896*ec779b8eSAndroid Build Coastguard Worker         }
897*ec779b8eSAndroid Build Coastguard Worker         if (utf8arg == "--stats") {
898*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpStats = true;
899*ec779b8eSAndroid Build Coastguard Worker             continue;
900*ec779b8eSAndroid Build Coastguard Worker         }
901*ec779b8eSAndroid Build Coastguard Worker         if (utf8arg == "--effects") {
902*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpEffects = true;
903*ec779b8eSAndroid Build Coastguard Worker             continue;
904*ec779b8eSAndroid Build Coastguard Worker         }
905*ec779b8eSAndroid Build Coastguard Worker         if (utf8arg == "--memory") {
906*ec779b8eSAndroid Build Coastguard Worker             parsedArgs.shouldDumpMem = true;
907*ec779b8eSAndroid Build Coastguard Worker             continue;
908*ec779b8eSAndroid Build Coastguard Worker         }
909*ec779b8eSAndroid Build Coastguard Worker         // Unknown arg silently ignored
910*ec779b8eSAndroid Build Coastguard Worker     }
911*ec779b8eSAndroid Build Coastguard Worker 
912*ec779b8eSAndroid Build Coastguard Worker     {
913*ec779b8eSAndroid Build Coastguard Worker         std::string res;
914*ec779b8eSAndroid Build Coastguard Worker         res.reserve(100);
915*ec779b8eSAndroid Build Coastguard Worker         res += "Start begin: ";
916*ec779b8eSAndroid Build Coastguard Worker         const auto startTimeStr = audio_utils_time_string_from_ns(mStartTime);
917*ec779b8eSAndroid Build Coastguard Worker         res += startTimeStr.time;
918*ec779b8eSAndroid Build Coastguard Worker         const auto startFinishedTime = getStartupFinishedTime();
919*ec779b8eSAndroid Build Coastguard Worker         if (startFinishedTime != 0) {
920*ec779b8eSAndroid Build Coastguard Worker             res += "\nStart end:   ";
921*ec779b8eSAndroid Build Coastguard Worker             const auto startEndStr = audio_utils_time_string_from_ns(startFinishedTime);
922*ec779b8eSAndroid Build Coastguard Worker             res += startEndStr.time;
923*ec779b8eSAndroid Build Coastguard Worker         } else {
924*ec779b8eSAndroid Build Coastguard Worker             res += "\nStartup not yet finished!";
925*ec779b8eSAndroid Build Coastguard Worker         }
926*ec779b8eSAndroid Build Coastguard Worker         const auto nowTimeStr = audio_utils_time_string_from_ns(audio_utils_get_real_time_ns());
927*ec779b8eSAndroid Build Coastguard Worker         res += "\nNow:         ";
928*ec779b8eSAndroid Build Coastguard Worker         res += nowTimeStr.time;
929*ec779b8eSAndroid Build Coastguard Worker         res += "\n";
930*ec779b8eSAndroid Build Coastguard Worker         writeStr(fd, res);
931*ec779b8eSAndroid Build Coastguard Worker     }
932*ec779b8eSAndroid Build Coastguard Worker     // get state of hardware lock
933*ec779b8eSAndroid Build Coastguard Worker     {
934*ec779b8eSAndroid Build Coastguard Worker         FallibleLockGuard l{hardwareMutex()};
935*ec779b8eSAndroid Build Coastguard Worker         if (!l) writeStr(fd, kHardwareLockedString);
936*ec779b8eSAndroid Build Coastguard Worker     }
937*ec779b8eSAndroid Build Coastguard Worker     {
938*ec779b8eSAndroid Build Coastguard Worker         FallibleLockGuard  l{mutex()};
939*ec779b8eSAndroid Build Coastguard Worker         if (!l) writeStr(fd, kDeadlockedString);
940*ec779b8eSAndroid Build Coastguard Worker         {
941*ec779b8eSAndroid Build Coastguard Worker             FallibleLockGuard ll{clientMutex()};
942*ec779b8eSAndroid Build Coastguard Worker             if (!ll) writeStr(fd, kClientLockedString);
943*ec779b8eSAndroid Build Coastguard Worker             dumpClients_ll(fd, parsedArgs.shouldDumpMem);
944*ec779b8eSAndroid Build Coastguard Worker         }
945*ec779b8eSAndroid Build Coastguard Worker 
946*ec779b8eSAndroid Build Coastguard Worker         dumpInternals_l(fd);
947*ec779b8eSAndroid Build Coastguard Worker 
948*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "\n ## BEGIN thread dump \n");
949*ec779b8eSAndroid Build Coastguard Worker         // dump playback threads
950*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
951*ec779b8eSAndroid Build Coastguard Worker             mPlaybackThreads.valueAt(i)->dump(fd, args);
952*ec779b8eSAndroid Build Coastguard Worker         }
953*ec779b8eSAndroid Build Coastguard Worker 
954*ec779b8eSAndroid Build Coastguard Worker         // dump record threads
955*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mRecordThreads.size(); i++) {
956*ec779b8eSAndroid Build Coastguard Worker             mRecordThreads.valueAt(i)->dump(fd, args);
957*ec779b8eSAndroid Build Coastguard Worker         }
958*ec779b8eSAndroid Build Coastguard Worker 
959*ec779b8eSAndroid Build Coastguard Worker         // dump mmap threads
960*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mMmapThreads.size(); i++) {
961*ec779b8eSAndroid Build Coastguard Worker             mMmapThreads.valueAt(i)->dump(fd, args);
962*ec779b8eSAndroid Build Coastguard Worker         }
963*ec779b8eSAndroid Build Coastguard Worker 
964*ec779b8eSAndroid Build Coastguard Worker         // dump orphan effect chains
965*ec779b8eSAndroid Build Coastguard Worker         if (mOrphanEffectChains.size() != 0) {
966*ec779b8eSAndroid Build Coastguard Worker             writeStr(fd, "  Orphan Effect Chains\n");
967*ec779b8eSAndroid Build Coastguard Worker             for (size_t i = 0; i < mOrphanEffectChains.size(); i++) {
968*ec779b8eSAndroid Build Coastguard Worker                 mOrphanEffectChains.valueAt(i)->dump(fd, args);
969*ec779b8eSAndroid Build Coastguard Worker             }
970*ec779b8eSAndroid Build Coastguard Worker         }
971*ec779b8eSAndroid Build Coastguard Worker         // dump historical threads in the last 10 seconds
972*ec779b8eSAndroid Build Coastguard Worker         writeStr(fd, mThreadLog.dumpToString(
973*ec779b8eSAndroid Build Coastguard Worker                 "Historical Thread Log ", 0 /* lines */,
974*ec779b8eSAndroid Build Coastguard Worker                 audio_utils_get_real_time_ns() - 10 * 60 * NANOS_PER_SECOND));
975*ec779b8eSAndroid Build Coastguard Worker 
976*ec779b8eSAndroid Build Coastguard Worker         // dump external setParameters
977*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "\n ## BEGIN setParameters dump \n");
978*ec779b8eSAndroid Build Coastguard Worker         auto dumpLogger = [fd](SimpleLog& logger, const char* name) {
979*ec779b8eSAndroid Build Coastguard Worker             dprintf(fd, "\n  %s setParameters:\n", name);
980*ec779b8eSAndroid Build Coastguard Worker             logger.dump(fd, "    " /* prefix */);
981*ec779b8eSAndroid Build Coastguard Worker         };
982*ec779b8eSAndroid Build Coastguard Worker         dumpLogger(mRejectedSetParameterLog, "Rejected");
983*ec779b8eSAndroid Build Coastguard Worker         dumpLogger(mAppSetParameterLog, "App");
984*ec779b8eSAndroid Build Coastguard Worker         dumpLogger(mSystemSetParameterLog, "System");
985*ec779b8eSAndroid Build Coastguard Worker 
986*ec779b8eSAndroid Build Coastguard Worker 
987*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "\n ## BEGIN misc af dump \n");
988*ec779b8eSAndroid Build Coastguard Worker         mPatchPanel->dump(fd);
989*ec779b8eSAndroid Build Coastguard Worker         mDeviceEffectManager->dump(fd);
990*ec779b8eSAndroid Build Coastguard Worker         writeStr(fd, mMelReporter->dump());
991*ec779b8eSAndroid Build Coastguard Worker 
992*ec779b8eSAndroid Build Coastguard Worker         if (media::psh_utils::AudioPowerManager::enabled()) {
993*ec779b8eSAndroid Build Coastguard Worker             char value[PROPERTY_VALUE_MAX];
994*ec779b8eSAndroid Build Coastguard Worker             property_get("ro.build.display.id", value, "Unknown build");
995*ec779b8eSAndroid Build Coastguard Worker             std::string build(value);
996*ec779b8eSAndroid Build Coastguard Worker             writeStr(fd, build + "\n");
997*ec779b8eSAndroid Build Coastguard Worker             writeStr(fd, media::psh_utils::AudioPowerManager::getAudioPowerManager().toString());
998*ec779b8eSAndroid Build Coastguard Worker         }
999*ec779b8eSAndroid Build Coastguard Worker 
1000*ec779b8eSAndroid Build Coastguard Worker         if (parsedArgs.shouldDumpEffects) {
1001*ec779b8eSAndroid Build Coastguard Worker             dprintf(fd, "\n ## BEGIN effects dump \n");
1002*ec779b8eSAndroid Build Coastguard Worker             if (mEffectsFactoryHal != 0) {
1003*ec779b8eSAndroid Build Coastguard Worker                 mEffectsFactoryHal->dumpEffects(fd);
1004*ec779b8eSAndroid Build Coastguard Worker             } else {
1005*ec779b8eSAndroid Build Coastguard Worker                 writeStr(fd, kNoEffectsFactory);
1006*ec779b8eSAndroid Build Coastguard Worker             }
1007*ec779b8eSAndroid Build Coastguard Worker         }
1008*ec779b8eSAndroid Build Coastguard Worker 
1009*ec779b8eSAndroid Build Coastguard Worker         if (parsedArgs.shouldDumpHal) {
1010*ec779b8eSAndroid Build Coastguard Worker             dprintf(fd, "\n ## BEGIN HAL dump \n");
1011*ec779b8eSAndroid Build Coastguard Worker             FallibleLockGuard ll{hardwareMutex()};
1012*ec779b8eSAndroid Build Coastguard Worker             // dump all hardware devs
1013*ec779b8eSAndroid Build Coastguard Worker             for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1014*ec779b8eSAndroid Build Coastguard Worker                 sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
1015*ec779b8eSAndroid Build Coastguard Worker                 dev->dump(fd, args);
1016*ec779b8eSAndroid Build Coastguard Worker             }
1017*ec779b8eSAndroid Build Coastguard Worker         }
1018*ec779b8eSAndroid Build Coastguard Worker     }  // end af lock
1019*ec779b8eSAndroid Build Coastguard Worker 
1020*ec779b8eSAndroid Build Coastguard Worker     if (parsedArgs.shouldDumpStats) {
1021*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "\n ## BEGIN stats dump \n");
1022*ec779b8eSAndroid Build Coastguard Worker         dumpStats(fd);
1023*ec779b8eSAndroid Build Coastguard Worker     }
1024*ec779b8eSAndroid Build Coastguard Worker 
1025*ec779b8eSAndroid Build Coastguard Worker     if (parsedArgs.shouldDumpMem) {
1026*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "\n ## BEGIN memory dump \n");
1027*ec779b8eSAndroid Build Coastguard Worker         writeStr(fd, dumpMemoryAddresses(100 /* limit */));
1028*ec779b8eSAndroid Build Coastguard Worker         dprintf(fd, "\nDumping unreachable memory:\n");
1029*ec779b8eSAndroid Build Coastguard Worker         // TODO - should limit be an argument parameter?
1030*ec779b8eSAndroid Build Coastguard Worker         writeStr(fd, GetUnreachableMemoryString(true /* contents */, 100 /* limit */));
1031*ec779b8eSAndroid Build Coastguard Worker     }
1032*ec779b8eSAndroid Build Coastguard Worker 
1033*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1034*ec779b8eSAndroid Build Coastguard Worker }
1035*ec779b8eSAndroid Build Coastguard Worker 
registerClient(pid_t pid,uid_t uid)1036*ec779b8eSAndroid Build Coastguard Worker sp<Client> AudioFlinger::registerClient(pid_t pid, uid_t uid)
1037*ec779b8eSAndroid Build Coastguard Worker {
1038*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _cl(clientMutex());
1039*ec779b8eSAndroid Build Coastguard Worker     // If pid is already in the mClients wp<> map, then use that entry
1040*ec779b8eSAndroid Build Coastguard Worker     // (for which promote() is always != 0), otherwise create a new entry and Client.
1041*ec779b8eSAndroid Build Coastguard Worker     sp<Client> client = mClients.valueFor(pid).promote();
1042*ec779b8eSAndroid Build Coastguard Worker     if (client == 0) {
1043*ec779b8eSAndroid Build Coastguard Worker         client = sp<Client>::make(sp<IAfClientCallback>::fromExisting(this), pid, uid);
1044*ec779b8eSAndroid Build Coastguard Worker         mClients.add(pid, client);
1045*ec779b8eSAndroid Build Coastguard Worker     }
1046*ec779b8eSAndroid Build Coastguard Worker 
1047*ec779b8eSAndroid Build Coastguard Worker     return client;
1048*ec779b8eSAndroid Build Coastguard Worker }
1049*ec779b8eSAndroid Build Coastguard Worker 
newWriter_l(size_t size,const char * name)1050*ec779b8eSAndroid Build Coastguard Worker sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
1051*ec779b8eSAndroid Build Coastguard Worker {
1052*ec779b8eSAndroid Build Coastguard Worker     // If there is no memory allocated for logs, return a no-op writer that does nothing.
1053*ec779b8eSAndroid Build Coastguard Worker     // Similarly if we can't contact the media.log service, also return a no-op writer.
1054*ec779b8eSAndroid Build Coastguard Worker     if (mLogMemoryDealer == 0 || sMediaLogService == 0) {
1055*ec779b8eSAndroid Build Coastguard Worker         return new NBLog::Writer();
1056*ec779b8eSAndroid Build Coastguard Worker     }
1057*ec779b8eSAndroid Build Coastguard Worker     sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
1058*ec779b8eSAndroid Build Coastguard Worker     // If allocation fails, consult the vector of previously unregistered writers
1059*ec779b8eSAndroid Build Coastguard Worker     // and garbage-collect one or more them until an allocation succeeds
1060*ec779b8eSAndroid Build Coastguard Worker     if (shared == 0) {
1061*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(unregisteredWritersMutex());
1062*ec779b8eSAndroid Build Coastguard Worker         for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
1063*ec779b8eSAndroid Build Coastguard Worker             {
1064*ec779b8eSAndroid Build Coastguard Worker                 // Pick the oldest stale writer to garbage-collect
1065*ec779b8eSAndroid Build Coastguard Worker                 sp<IMemory> iMemory(mUnregisteredWriters[0]->getIMemory());
1066*ec779b8eSAndroid Build Coastguard Worker                 mUnregisteredWriters.removeAt(0);
1067*ec779b8eSAndroid Build Coastguard Worker                 sMediaLogService->unregisterWriter(iMemory);
1068*ec779b8eSAndroid Build Coastguard Worker                 // Now the media.log remote reference to IMemory is gone.  When our last local
1069*ec779b8eSAndroid Build Coastguard Worker                 // reference to IMemory also drops to zero at end of this block,
1070*ec779b8eSAndroid Build Coastguard Worker                 // the IMemory destructor will deallocate the region from mLogMemoryDealer.
1071*ec779b8eSAndroid Build Coastguard Worker             }
1072*ec779b8eSAndroid Build Coastguard Worker             // Re-attempt the allocation
1073*ec779b8eSAndroid Build Coastguard Worker             shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
1074*ec779b8eSAndroid Build Coastguard Worker             if (shared != 0) {
1075*ec779b8eSAndroid Build Coastguard Worker                 goto success;
1076*ec779b8eSAndroid Build Coastguard Worker             }
1077*ec779b8eSAndroid Build Coastguard Worker         }
1078*ec779b8eSAndroid Build Coastguard Worker         // Even after garbage-collecting all old writers, there is still not enough memory,
1079*ec779b8eSAndroid Build Coastguard Worker         // so return a no-op writer
1080*ec779b8eSAndroid Build Coastguard Worker         return new NBLog::Writer();
1081*ec779b8eSAndroid Build Coastguard Worker     }
1082*ec779b8eSAndroid Build Coastguard Worker success:
1083*ec779b8eSAndroid Build Coastguard Worker     NBLog::Shared *sharedRawPtr = (NBLog::Shared *) shared->unsecurePointer();
1084*ec779b8eSAndroid Build Coastguard Worker     new((void *) sharedRawPtr) NBLog::Shared(); // placement new here, but the corresponding
1085*ec779b8eSAndroid Build Coastguard Worker                                                 // explicit destructor not needed since it is POD
1086*ec779b8eSAndroid Build Coastguard Worker     sMediaLogService->registerWriter(shared, size, name);
1087*ec779b8eSAndroid Build Coastguard Worker     return new NBLog::Writer(shared, size);
1088*ec779b8eSAndroid Build Coastguard Worker }
1089*ec779b8eSAndroid Build Coastguard Worker 
unregisterWriter(const sp<NBLog::Writer> & writer)1090*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
1091*ec779b8eSAndroid Build Coastguard Worker {
1092*ec779b8eSAndroid Build Coastguard Worker     if (writer == 0) {
1093*ec779b8eSAndroid Build Coastguard Worker         return;
1094*ec779b8eSAndroid Build Coastguard Worker     }
1095*ec779b8eSAndroid Build Coastguard Worker     sp<IMemory> iMemory(writer->getIMemory());
1096*ec779b8eSAndroid Build Coastguard Worker     if (iMemory == 0) {
1097*ec779b8eSAndroid Build Coastguard Worker         return;
1098*ec779b8eSAndroid Build Coastguard Worker     }
1099*ec779b8eSAndroid Build Coastguard Worker     // Rather than removing the writer immediately, append it to a queue of old writers to
1100*ec779b8eSAndroid Build Coastguard Worker     // be garbage-collected later.  This allows us to continue to view old logs for a while.
1101*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(unregisteredWritersMutex());
1102*ec779b8eSAndroid Build Coastguard Worker     mUnregisteredWriters.push(writer);
1103*ec779b8eSAndroid Build Coastguard Worker }
1104*ec779b8eSAndroid Build Coastguard Worker 
1105*ec779b8eSAndroid Build Coastguard Worker // IAudioFlinger interface
1106*ec779b8eSAndroid Build Coastguard Worker 
createTrack(const media::CreateTrackRequest & _input,media::CreateTrackResponse & _output)1107*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
1108*ec779b8eSAndroid Build Coastguard Worker                                    media::CreateTrackResponse& _output)
1109*ec779b8eSAndroid Build Coastguard Worker {
1110*ec779b8eSAndroid Build Coastguard Worker     ATRACE_CALL();
1111*ec779b8eSAndroid Build Coastguard Worker     // Local version of VALUE_OR_RETURN, specific to this method's calling conventions.
1112*ec779b8eSAndroid Build Coastguard Worker     CreateTrackInput input = VALUE_OR_RETURN_STATUS(CreateTrackInput::fromAidl(_input));
1113*ec779b8eSAndroid Build Coastguard Worker     CreateTrackOutput output;
1114*ec779b8eSAndroid Build Coastguard Worker 
1115*ec779b8eSAndroid Build Coastguard Worker     sp<IAfTrack> track;
1116*ec779b8eSAndroid Build Coastguard Worker     sp<Client> client;
1117*ec779b8eSAndroid Build Coastguard Worker     status_t lStatus;
1118*ec779b8eSAndroid Build Coastguard Worker     audio_stream_type_t streamType;
1119*ec779b8eSAndroid Build Coastguard Worker     audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
1120*ec779b8eSAndroid Build Coastguard Worker     std::vector<audio_io_handle_t> secondaryOutputs;
1121*ec779b8eSAndroid Build Coastguard Worker     bool isSpatialized = false;
1122*ec779b8eSAndroid Build Coastguard Worker     bool isBitPerfect = false;
1123*ec779b8eSAndroid Build Coastguard Worker     float volume;
1124*ec779b8eSAndroid Build Coastguard Worker     bool muted;
1125*ec779b8eSAndroid Build Coastguard Worker 
1126*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE;
1127*ec779b8eSAndroid Build Coastguard Worker     std::vector<int> effectIds;
1128*ec779b8eSAndroid Build Coastguard Worker     audio_attributes_t localAttr = input.attr;
1129*ec779b8eSAndroid Build Coastguard Worker 
1130*ec779b8eSAndroid Build Coastguard Worker     AttributionSourceState adjAttributionSource;
1131*ec779b8eSAndroid Build Coastguard Worker     pid_t callingPid = IPCThreadState::self()->getCallingPid();
1132*ec779b8eSAndroid Build Coastguard Worker     if (!com::android::media::audio::audioserver_permissions()) {
1133*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = input.clientInfo.attributionSource;
1134*ec779b8eSAndroid Build Coastguard Worker         const uid_t callingUid = IPCThreadState::self()->getCallingUid();
1135*ec779b8eSAndroid Build Coastguard Worker         uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(
1136*ec779b8eSAndroid Build Coastguard Worker                         input.clientInfo.attributionSource.uid));
1137*ec779b8eSAndroid Build Coastguard Worker         pid_t clientPid =
1138*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
1139*ec779b8eSAndroid Build Coastguard Worker                         input.clientInfo.attributionSource.pid));
1140*ec779b8eSAndroid Build Coastguard Worker         bool updatePid = (clientPid == (pid_t)-1);
1141*ec779b8eSAndroid Build Coastguard Worker 
1142*ec779b8eSAndroid Build Coastguard Worker         if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
1143*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(clientUid != callingUid,
1144*ec779b8eSAndroid Build Coastguard Worker                     "%s uid %d tried to pass itself off as %d",
1145*ec779b8eSAndroid Build Coastguard Worker                     __FUNCTION__, callingUid, clientUid);
1146*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
1147*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_uid_t_int32_t(callingUid));
1148*ec779b8eSAndroid Build Coastguard Worker             clientUid = callingUid;
1149*ec779b8eSAndroid Build Coastguard Worker             updatePid = true;
1150*ec779b8eSAndroid Build Coastguard Worker         }
1151*ec779b8eSAndroid Build Coastguard Worker         if (updatePid) {
1152*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
1153*ec779b8eSAndroid Build Coastguard Worker                      "%s uid %d pid %d tried to pass itself off as pid %d",
1154*ec779b8eSAndroid Build Coastguard Worker                      __func__, callingUid, callingPid, clientPid);
1155*ec779b8eSAndroid Build Coastguard Worker             clientPid = callingPid;
1156*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
1157*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_pid_t_int32_t(callingPid));
1158*ec779b8eSAndroid Build Coastguard Worker         }
1159*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = afutils::checkAttributionSourcePackage(
1160*ec779b8eSAndroid Build Coastguard Worker                 adjAttributionSource);
1161*ec779b8eSAndroid Build Coastguard Worker 
1162*ec779b8eSAndroid Build Coastguard Worker     } else {
1163*ec779b8eSAndroid Build Coastguard Worker         auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
1164*ec779b8eSAndroid Build Coastguard Worker                 validateAttributionFromContextOrTrustedCaller(input.clientInfo.attributionSource,
1165*ec779b8eSAndroid Build Coastguard Worker                 getPermissionProvider()
1166*ec779b8eSAndroid Build Coastguard Worker                 ));
1167*ec779b8eSAndroid Build Coastguard Worker         // TODO pass wrapped object around
1168*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
1169*ec779b8eSAndroid Build Coastguard Worker     }
1170*ec779b8eSAndroid Build Coastguard Worker 
1171*ec779b8eSAndroid Build Coastguard Worker     DeviceIdVector selectedDeviceIds;
1172*ec779b8eSAndroid Build Coastguard Worker     audio_session_t sessionId = input.sessionId;
1173*ec779b8eSAndroid Build Coastguard Worker     if (sessionId == AUDIO_SESSION_ALLOCATE) {
1174*ec779b8eSAndroid Build Coastguard Worker         sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
1175*ec779b8eSAndroid Build Coastguard Worker     } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
1176*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
1177*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
1178*ec779b8eSAndroid Build Coastguard Worker     }
1179*ec779b8eSAndroid Build Coastguard Worker 
1180*ec779b8eSAndroid Build Coastguard Worker     output.sessionId = sessionId;
1181*ec779b8eSAndroid Build Coastguard Worker     output.outputId = AUDIO_IO_HANDLE_NONE;
1182*ec779b8eSAndroid Build Coastguard Worker     if (input.selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
1183*ec779b8eSAndroid Build Coastguard Worker         selectedDeviceIds.push_back(input.selectedDeviceId);
1184*ec779b8eSAndroid Build Coastguard Worker     }
1185*ec779b8eSAndroid Build Coastguard Worker     lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
1186*ec779b8eSAndroid Build Coastguard Worker                                             adjAttributionSource, &input.config, input.flags,
1187*ec779b8eSAndroid Build Coastguard Worker                                             &selectedDeviceIds, &portId, &secondaryOutputs,
1188*ec779b8eSAndroid Build Coastguard Worker                                             &isSpatialized, &isBitPerfect, &volume, &muted);
1189*ec779b8eSAndroid Build Coastguard Worker     output.selectedDeviceIds = selectedDeviceIds;
1190*ec779b8eSAndroid Build Coastguard Worker 
1191*ec779b8eSAndroid Build Coastguard Worker     if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
1192*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus);
1193*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
1194*ec779b8eSAndroid Build Coastguard Worker     }
1195*ec779b8eSAndroid Build Coastguard Worker     // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
1196*ec779b8eSAndroid Build Coastguard Worker     // but if someone uses binder directly they could bypass that and cause us to crash
1197*ec779b8eSAndroid Build Coastguard Worker     if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
1198*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createTrack() invalid stream type %d", streamType);
1199*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
1200*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
1201*ec779b8eSAndroid Build Coastguard Worker     }
1202*ec779b8eSAndroid Build Coastguard Worker 
1203*ec779b8eSAndroid Build Coastguard Worker     // further channel mask checks are performed by createTrack_l() depending on the thread type
1204*ec779b8eSAndroid Build Coastguard Worker     if (!audio_is_output_channel(input.config.channel_mask)) {
1205*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createTrack() invalid channel mask %#x", input.config.channel_mask);
1206*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
1207*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
1208*ec779b8eSAndroid Build Coastguard Worker     }
1209*ec779b8eSAndroid Build Coastguard Worker 
1210*ec779b8eSAndroid Build Coastguard Worker     // further format checks are performed by createTrack_l() depending on the thread type
1211*ec779b8eSAndroid Build Coastguard Worker     if (!audio_is_valid_format(input.config.format)) {
1212*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createTrack() invalid format %#x", input.config.format);
1213*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
1214*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
1215*ec779b8eSAndroid Build Coastguard Worker     }
1216*ec779b8eSAndroid Build Coastguard Worker 
1217*ec779b8eSAndroid Build Coastguard Worker     {
1218*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
1219*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* thread = checkPlaybackThread_l(output.outputId);
1220*ec779b8eSAndroid Build Coastguard Worker         if (thread == NULL) {
1221*ec779b8eSAndroid Build Coastguard Worker             ALOGE("no playback thread found for output handle %d", output.outputId);
1222*ec779b8eSAndroid Build Coastguard Worker             lStatus = BAD_VALUE;
1223*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
1224*ec779b8eSAndroid Build Coastguard Worker         }
1225*ec779b8eSAndroid Build Coastguard Worker 
1226*ec779b8eSAndroid Build Coastguard Worker         client = registerClient(adjAttributionSource.pid, adjAttributionSource.uid);
1227*ec779b8eSAndroid Build Coastguard Worker 
1228*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* effectThread = nullptr;
1229*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> effectChain = nullptr;
1230*ec779b8eSAndroid Build Coastguard Worker         // check if an effect chain with the same session ID is present on another
1231*ec779b8eSAndroid Build Coastguard Worker         // output thread and move it here.
1232*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1233*ec779b8eSAndroid Build Coastguard Worker             sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
1234*ec779b8eSAndroid Build Coastguard Worker             if (mPlaybackThreads.keyAt(i) != output.outputId) {
1235*ec779b8eSAndroid Build Coastguard Worker                 uint32_t sessions = t->hasAudioSession(sessionId);
1236*ec779b8eSAndroid Build Coastguard Worker                 if (sessions & IAfThreadBase::EFFECT_SESSION) {
1237*ec779b8eSAndroid Build Coastguard Worker                     effectThread = t.get();
1238*ec779b8eSAndroid Build Coastguard Worker                     break;
1239*ec779b8eSAndroid Build Coastguard Worker                 }
1240*ec779b8eSAndroid Build Coastguard Worker             }
1241*ec779b8eSAndroid Build Coastguard Worker         }
1242*ec779b8eSAndroid Build Coastguard Worker         // Check if an orphan effect chain exists for this session
1243*ec779b8eSAndroid Build Coastguard Worker         if (effectThread == nullptr) {
1244*ec779b8eSAndroid Build Coastguard Worker             effectChain = getOrphanEffectChain_l(sessionId);
1245*ec779b8eSAndroid Build Coastguard Worker         }
1246*ec779b8eSAndroid Build Coastguard Worker         ALOGV("createTrack() sessionId: %d volume: %f muted %d", sessionId, volume, muted);
1247*ec779b8eSAndroid Build Coastguard Worker 
1248*ec779b8eSAndroid Build Coastguard Worker         output.sampleRate = input.config.sample_rate;
1249*ec779b8eSAndroid Build Coastguard Worker         output.frameCount = input.frameCount;
1250*ec779b8eSAndroid Build Coastguard Worker         output.notificationFrameCount = input.notificationFrameCount;
1251*ec779b8eSAndroid Build Coastguard Worker         output.flags = input.flags;
1252*ec779b8eSAndroid Build Coastguard Worker         output.streamType = streamType;
1253*ec779b8eSAndroid Build Coastguard Worker 
1254*ec779b8eSAndroid Build Coastguard Worker         track = thread->createTrack_l(client, streamType, localAttr, &output.sampleRate,
1255*ec779b8eSAndroid Build Coastguard Worker                                       input.config.format, input.config.channel_mask,
1256*ec779b8eSAndroid Build Coastguard Worker                                       &output.frameCount, &output.notificationFrameCount,
1257*ec779b8eSAndroid Build Coastguard Worker                                       input.notificationsPerBuffer, input.speed,
1258*ec779b8eSAndroid Build Coastguard Worker                                       input.sharedBuffer, sessionId, &output.flags,
1259*ec779b8eSAndroid Build Coastguard Worker                                       callingPid, adjAttributionSource, input.clientInfo.clientTid,
1260*ec779b8eSAndroid Build Coastguard Worker                                       &lStatus, portId, input.audioTrackCallback, isSpatialized,
1261*ec779b8eSAndroid Build Coastguard Worker                                       isBitPerfect, &output.afTrackFlags, volume, muted);
1262*ec779b8eSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0));
1263*ec779b8eSAndroid Build Coastguard Worker         // we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
1264*ec779b8eSAndroid Build Coastguard Worker 
1265*ec779b8eSAndroid Build Coastguard Worker         output.afFrameCount = thread->frameCount();
1266*ec779b8eSAndroid Build Coastguard Worker         output.afSampleRate = thread->sampleRate();
1267*ec779b8eSAndroid Build Coastguard Worker         output.afChannelMask = static_cast<audio_channel_mask_t>(thread->channelMask() |
1268*ec779b8eSAndroid Build Coastguard Worker                                                                  thread->hapticChannelMask());
1269*ec779b8eSAndroid Build Coastguard Worker         output.afFormat = thread->format();
1270*ec779b8eSAndroid Build Coastguard Worker         output.afLatencyMs = thread->latency();
1271*ec779b8eSAndroid Build Coastguard Worker         output.portId = portId;
1272*ec779b8eSAndroid Build Coastguard Worker 
1273*ec779b8eSAndroid Build Coastguard Worker         if (lStatus == NO_ERROR) {
1274*ec779b8eSAndroid Build Coastguard Worker             // no risk of deadlock because AudioFlinger::mutex() is held
1275*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _dl(thread->mutex());
1276*ec779b8eSAndroid Build Coastguard Worker             // Connect secondary outputs. Failure on a secondary output must not imped the primary
1277*ec779b8eSAndroid Build Coastguard Worker             // Any secondary output setup failure will lead to a desync between the AP and AF until
1278*ec779b8eSAndroid Build Coastguard Worker             // the track is destroyed.
1279*ec779b8eSAndroid Build Coastguard Worker             updateSecondaryOutputsForTrack_l(track.get(), thread, secondaryOutputs);
1280*ec779b8eSAndroid Build Coastguard Worker             // move effect chain to this output thread if an effect on same session was waiting
1281*ec779b8eSAndroid Build Coastguard Worker             // for a track to be created
1282*ec779b8eSAndroid Build Coastguard Worker             if (effectThread != nullptr) {
1283*ec779b8eSAndroid Build Coastguard Worker                 // No thread safety analysis: double lock on a thread capability.
1284*ec779b8eSAndroid Build Coastguard Worker                 audio_utils::lock_guard_no_thread_safety_analysis _sl(effectThread->mutex());
1285*ec779b8eSAndroid Build Coastguard Worker                 if (moveEffectChain_ll(sessionId, effectThread, thread) == NO_ERROR) {
1286*ec779b8eSAndroid Build Coastguard Worker                     effectThreadId = thread->id();
1287*ec779b8eSAndroid Build Coastguard Worker                     effectIds = thread->getEffectIds_l(sessionId);
1288*ec779b8eSAndroid Build Coastguard Worker                 }
1289*ec779b8eSAndroid Build Coastguard Worker             }
1290*ec779b8eSAndroid Build Coastguard Worker             if (effectChain != nullptr) {
1291*ec779b8eSAndroid Build Coastguard Worker                 if (moveEffectChain_ll(sessionId, nullptr, thread, effectChain.get())
1292*ec779b8eSAndroid Build Coastguard Worker                         == NO_ERROR) {
1293*ec779b8eSAndroid Build Coastguard Worker                     effectThreadId = thread->id();
1294*ec779b8eSAndroid Build Coastguard Worker                     effectIds = thread->getEffectIds_l(sessionId);
1295*ec779b8eSAndroid Build Coastguard Worker                 }
1296*ec779b8eSAndroid Build Coastguard Worker             }
1297*ec779b8eSAndroid Build Coastguard Worker         }
1298*ec779b8eSAndroid Build Coastguard Worker 
1299*ec779b8eSAndroid Build Coastguard Worker         // Look for sync events awaiting for a session to be used.
1300*ec779b8eSAndroid Build Coastguard Worker         for (auto it = mPendingSyncEvents.begin(); it != mPendingSyncEvents.end();) {
1301*ec779b8eSAndroid Build Coastguard Worker             if ((*it)->triggerSession() == sessionId) {
1302*ec779b8eSAndroid Build Coastguard Worker                 if (thread->isValidSyncEvent(*it)) {
1303*ec779b8eSAndroid Build Coastguard Worker                     if (lStatus == NO_ERROR) {
1304*ec779b8eSAndroid Build Coastguard Worker                         (void) track->setSyncEvent(*it);
1305*ec779b8eSAndroid Build Coastguard Worker                     } else {
1306*ec779b8eSAndroid Build Coastguard Worker                         (*it)->cancel();
1307*ec779b8eSAndroid Build Coastguard Worker                     }
1308*ec779b8eSAndroid Build Coastguard Worker                     it = mPendingSyncEvents.erase(it);
1309*ec779b8eSAndroid Build Coastguard Worker                     continue;
1310*ec779b8eSAndroid Build Coastguard Worker                 }
1311*ec779b8eSAndroid Build Coastguard Worker             }
1312*ec779b8eSAndroid Build Coastguard Worker             ++it;
1313*ec779b8eSAndroid Build Coastguard Worker         }
1314*ec779b8eSAndroid Build Coastguard Worker         if ((output.flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
1315*ec779b8eSAndroid Build Coastguard Worker             setAudioHwSyncForSession_l(thread, sessionId);
1316*ec779b8eSAndroid Build Coastguard Worker         }
1317*ec779b8eSAndroid Build Coastguard Worker     }
1318*ec779b8eSAndroid Build Coastguard Worker 
1319*ec779b8eSAndroid Build Coastguard Worker     if (lStatus != NO_ERROR) {
1320*ec779b8eSAndroid Build Coastguard Worker         // remove local strong reference to Client before deleting the Track so that the
1321*ec779b8eSAndroid Build Coastguard Worker         // Client destructor is called by the TrackBase destructor with clientMutex() held
1322*ec779b8eSAndroid Build Coastguard Worker         // Don't hold clientMutex() when releasing the reference on the track as the
1323*ec779b8eSAndroid Build Coastguard Worker         // destructor will acquire it.
1324*ec779b8eSAndroid Build Coastguard Worker         {
1325*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _cl(clientMutex());
1326*ec779b8eSAndroid Build Coastguard Worker             client.clear();
1327*ec779b8eSAndroid Build Coastguard Worker         }
1328*ec779b8eSAndroid Build Coastguard Worker         track.clear();
1329*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
1330*ec779b8eSAndroid Build Coastguard Worker     }
1331*ec779b8eSAndroid Build Coastguard Worker 
1332*ec779b8eSAndroid Build Coastguard Worker     // effectThreadId is not NONE if an effect chain corresponding to the track session
1333*ec779b8eSAndroid Build Coastguard Worker     // was found on another thread and must be moved on this thread
1334*ec779b8eSAndroid Build Coastguard Worker     if (effectThreadId != AUDIO_IO_HANDLE_NONE) {
1335*ec779b8eSAndroid Build Coastguard Worker         AudioSystem::moveEffectsToIo(effectIds, effectThreadId);
1336*ec779b8eSAndroid Build Coastguard Worker     }
1337*ec779b8eSAndroid Build Coastguard Worker 
1338*ec779b8eSAndroid Build Coastguard Worker     output.audioTrack = IAfTrack::createIAudioTrackAdapter(track);
1339*ec779b8eSAndroid Build Coastguard Worker     _output = VALUE_OR_FATAL(output.toAidl());
1340*ec779b8eSAndroid Build Coastguard Worker 
1341*ec779b8eSAndroid Build Coastguard Worker Exit:
1342*ec779b8eSAndroid Build Coastguard Worker     if (lStatus != NO_ERROR && output.outputId != AUDIO_IO_HANDLE_NONE) {
1343*ec779b8eSAndroid Build Coastguard Worker         AudioSystem::releaseOutput(portId);
1344*ec779b8eSAndroid Build Coastguard Worker     }
1345*ec779b8eSAndroid Build Coastguard Worker     return lStatus;
1346*ec779b8eSAndroid Build Coastguard Worker }
1347*ec779b8eSAndroid Build Coastguard Worker 
sampleRate(audio_io_handle_t ioHandle) const1348*ec779b8eSAndroid Build Coastguard Worker uint32_t AudioFlinger::sampleRate(audio_io_handle_t ioHandle) const
1349*ec779b8eSAndroid Build Coastguard Worker {
1350*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1351*ec779b8eSAndroid Build Coastguard Worker     IAfThreadBase* const thread = checkThread_l(ioHandle);
1352*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
1353*ec779b8eSAndroid Build Coastguard Worker         ALOGW("sampleRate() unknown thread %d", ioHandle);
1354*ec779b8eSAndroid Build Coastguard Worker         return 0;
1355*ec779b8eSAndroid Build Coastguard Worker     }
1356*ec779b8eSAndroid Build Coastguard Worker     return thread->sampleRate();
1357*ec779b8eSAndroid Build Coastguard Worker }
1358*ec779b8eSAndroid Build Coastguard Worker 
format(audio_io_handle_t output) const1359*ec779b8eSAndroid Build Coastguard Worker audio_format_t AudioFlinger::format(audio_io_handle_t output) const
1360*ec779b8eSAndroid Build Coastguard Worker {
1361*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1362*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
1363*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
1364*ec779b8eSAndroid Build Coastguard Worker         ALOGW("format() unknown thread %d", output);
1365*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_FORMAT_INVALID;
1366*ec779b8eSAndroid Build Coastguard Worker     }
1367*ec779b8eSAndroid Build Coastguard Worker     return thread->format();
1368*ec779b8eSAndroid Build Coastguard Worker }
1369*ec779b8eSAndroid Build Coastguard Worker 
frameCount(audio_io_handle_t ioHandle) const1370*ec779b8eSAndroid Build Coastguard Worker size_t AudioFlinger::frameCount(audio_io_handle_t ioHandle) const
1371*ec779b8eSAndroid Build Coastguard Worker {
1372*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1373*ec779b8eSAndroid Build Coastguard Worker     IAfThreadBase* const thread = checkThread_l(ioHandle);
1374*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
1375*ec779b8eSAndroid Build Coastguard Worker         ALOGW("frameCount() unknown thread %d", ioHandle);
1376*ec779b8eSAndroid Build Coastguard Worker         return 0;
1377*ec779b8eSAndroid Build Coastguard Worker     }
1378*ec779b8eSAndroid Build Coastguard Worker     // FIXME currently returns the normal mixer's frame count to avoid confusing legacy callers;
1379*ec779b8eSAndroid Build Coastguard Worker     //       should examine all callers and fix them to handle smaller counts
1380*ec779b8eSAndroid Build Coastguard Worker     return thread->frameCount();
1381*ec779b8eSAndroid Build Coastguard Worker }
1382*ec779b8eSAndroid Build Coastguard Worker 
frameCountHAL(audio_io_handle_t ioHandle) const1383*ec779b8eSAndroid Build Coastguard Worker size_t AudioFlinger::frameCountHAL(audio_io_handle_t ioHandle) const
1384*ec779b8eSAndroid Build Coastguard Worker {
1385*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1386*ec779b8eSAndroid Build Coastguard Worker     IAfThreadBase* const thread = checkThread_l(ioHandle);
1387*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
1388*ec779b8eSAndroid Build Coastguard Worker         ALOGW("frameCountHAL() unknown thread %d", ioHandle);
1389*ec779b8eSAndroid Build Coastguard Worker         return 0;
1390*ec779b8eSAndroid Build Coastguard Worker     }
1391*ec779b8eSAndroid Build Coastguard Worker     return thread->frameCountHAL();
1392*ec779b8eSAndroid Build Coastguard Worker }
1393*ec779b8eSAndroid Build Coastguard Worker 
latency(audio_io_handle_t output) const1394*ec779b8eSAndroid Build Coastguard Worker uint32_t AudioFlinger::latency(audio_io_handle_t output) const
1395*ec779b8eSAndroid Build Coastguard Worker {
1396*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1397*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
1398*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
1399*ec779b8eSAndroid Build Coastguard Worker         ALOGW("latency(): no playback thread found for output handle %d", output);
1400*ec779b8eSAndroid Build Coastguard Worker         return 0;
1401*ec779b8eSAndroid Build Coastguard Worker     }
1402*ec779b8eSAndroid Build Coastguard Worker     return thread->latency();
1403*ec779b8eSAndroid Build Coastguard Worker }
1404*ec779b8eSAndroid Build Coastguard Worker 
setMasterVolume(float value)1405*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setMasterVolume(float value)
1406*ec779b8eSAndroid Build Coastguard Worker {
1407*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
1408*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
1409*ec779b8eSAndroid Build Coastguard Worker         return ret;
1410*ec779b8eSAndroid Build Coastguard Worker     }
1411*ec779b8eSAndroid Build Coastguard Worker 
1412*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1413*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1414*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1415*ec779b8eSAndroid Build Coastguard Worker     }
1416*ec779b8eSAndroid Build Coastguard Worker 
1417*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1418*ec779b8eSAndroid Build Coastguard Worker     mMasterVolume = value;
1419*ec779b8eSAndroid Build Coastguard Worker 
1420*ec779b8eSAndroid Build Coastguard Worker     // Set master volume in the HALs which support it.
1421*ec779b8eSAndroid Build Coastguard Worker     {
1422*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard lock(hardwareMutex());
1423*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1424*ec779b8eSAndroid Build Coastguard Worker             AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
1425*ec779b8eSAndroid Build Coastguard Worker 
1426*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
1427*ec779b8eSAndroid Build Coastguard Worker             if (dev->canSetMasterVolume()) {
1428*ec779b8eSAndroid Build Coastguard Worker                 dev->hwDevice()->setMasterVolume(value);
1429*ec779b8eSAndroid Build Coastguard Worker             }
1430*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_IDLE;
1431*ec779b8eSAndroid Build Coastguard Worker         }
1432*ec779b8eSAndroid Build Coastguard Worker     }
1433*ec779b8eSAndroid Build Coastguard Worker     // Now set the master volume in each playback thread.  Playback threads
1434*ec779b8eSAndroid Build Coastguard Worker     // assigned to HALs which do not have master volume support will apply
1435*ec779b8eSAndroid Build Coastguard Worker     // master volume during the mix operation.  Threads with HALs which do
1436*ec779b8eSAndroid Build Coastguard Worker     // support master volume will simply ignore the setting.
1437*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1438*ec779b8eSAndroid Build Coastguard Worker         if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
1439*ec779b8eSAndroid Build Coastguard Worker             continue;
1440*ec779b8eSAndroid Build Coastguard Worker         }
1441*ec779b8eSAndroid Build Coastguard Worker         mPlaybackThreads.valueAt(i)->setMasterVolume(value);
1442*ec779b8eSAndroid Build Coastguard Worker     }
1443*ec779b8eSAndroid Build Coastguard Worker 
1444*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1445*ec779b8eSAndroid Build Coastguard Worker }
1446*ec779b8eSAndroid Build Coastguard Worker 
setMasterBalance(float balance)1447*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setMasterBalance(float balance)
1448*ec779b8eSAndroid Build Coastguard Worker {
1449*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
1450*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
1451*ec779b8eSAndroid Build Coastguard Worker         return ret;
1452*ec779b8eSAndroid Build Coastguard Worker     }
1453*ec779b8eSAndroid Build Coastguard Worker 
1454*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1455*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1456*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1457*ec779b8eSAndroid Build Coastguard Worker     }
1458*ec779b8eSAndroid Build Coastguard Worker 
1459*ec779b8eSAndroid Build Coastguard Worker     // check range
1460*ec779b8eSAndroid Build Coastguard Worker     if (isnan(balance) || fabs(balance) > 1.f) {
1461*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1462*ec779b8eSAndroid Build Coastguard Worker     }
1463*ec779b8eSAndroid Build Coastguard Worker 
1464*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1465*ec779b8eSAndroid Build Coastguard Worker 
1466*ec779b8eSAndroid Build Coastguard Worker     // short cut.
1467*ec779b8eSAndroid Build Coastguard Worker     if (mMasterBalance == balance) return NO_ERROR;
1468*ec779b8eSAndroid Build Coastguard Worker 
1469*ec779b8eSAndroid Build Coastguard Worker     mMasterBalance = balance;
1470*ec779b8eSAndroid Build Coastguard Worker 
1471*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1472*ec779b8eSAndroid Build Coastguard Worker         if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
1473*ec779b8eSAndroid Build Coastguard Worker             continue;
1474*ec779b8eSAndroid Build Coastguard Worker         }
1475*ec779b8eSAndroid Build Coastguard Worker         mPlaybackThreads.valueAt(i)->setMasterBalance(balance);
1476*ec779b8eSAndroid Build Coastguard Worker     }
1477*ec779b8eSAndroid Build Coastguard Worker 
1478*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1479*ec779b8eSAndroid Build Coastguard Worker }
1480*ec779b8eSAndroid Build Coastguard Worker 
setMode(audio_mode_t mode)1481*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setMode(audio_mode_t mode)
1482*ec779b8eSAndroid Build Coastguard Worker {
1483*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
1484*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
1485*ec779b8eSAndroid Build Coastguard Worker         return ret;
1486*ec779b8eSAndroid Build Coastguard Worker     }
1487*ec779b8eSAndroid Build Coastguard Worker 
1488*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1489*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1490*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1491*ec779b8eSAndroid Build Coastguard Worker     }
1492*ec779b8eSAndroid Build Coastguard Worker     if (uint32_t(mode) >= AUDIO_MODE_CNT) {
1493*ec779b8eSAndroid Build Coastguard Worker         ALOGW("Illegal value: setMode(%d)", mode);
1494*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1495*ec779b8eSAndroid Build Coastguard Worker     }
1496*ec779b8eSAndroid Build Coastguard Worker 
1497*ec779b8eSAndroid Build Coastguard Worker     { // scope for the lock
1498*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard lock(hardwareMutex());
1499*ec779b8eSAndroid Build Coastguard Worker         if (mPrimaryHardwareDev == nullptr) {
1500*ec779b8eSAndroid Build Coastguard Worker             return INVALID_OPERATION;
1501*ec779b8eSAndroid Build Coastguard Worker         }
1502*ec779b8eSAndroid Build Coastguard Worker         sp<DeviceHalInterface> dev = mPrimaryHardwareDev.load()->hwDevice();
1503*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_SET_MODE;
1504*ec779b8eSAndroid Build Coastguard Worker         ret = dev->setMode(mode);
1505*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_IDLE;
1506*ec779b8eSAndroid Build Coastguard Worker     }
1507*ec779b8eSAndroid Build Coastguard Worker 
1508*ec779b8eSAndroid Build Coastguard Worker     if (NO_ERROR == ret) {
1509*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
1510*ec779b8eSAndroid Build Coastguard Worker         mMode = mode;
1511*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1512*ec779b8eSAndroid Build Coastguard Worker             mPlaybackThreads.valueAt(i)->setMode(mode);
1513*ec779b8eSAndroid Build Coastguard Worker         }
1514*ec779b8eSAndroid Build Coastguard Worker     }
1515*ec779b8eSAndroid Build Coastguard Worker 
1516*ec779b8eSAndroid Build Coastguard Worker     mediametrics::LogItem(mMetricsId)
1517*ec779b8eSAndroid Build Coastguard Worker         .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETMODE)
1518*ec779b8eSAndroid Build Coastguard Worker         .set(AMEDIAMETRICS_PROP_AUDIOMODE, toString(mode))
1519*ec779b8eSAndroid Build Coastguard Worker         .record();
1520*ec779b8eSAndroid Build Coastguard Worker     return ret;
1521*ec779b8eSAndroid Build Coastguard Worker }
1522*ec779b8eSAndroid Build Coastguard Worker 
setMicMute(bool state)1523*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setMicMute(bool state)
1524*ec779b8eSAndroid Build Coastguard Worker {
1525*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
1526*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
1527*ec779b8eSAndroid Build Coastguard Worker         return ret;
1528*ec779b8eSAndroid Build Coastguard Worker     }
1529*ec779b8eSAndroid Build Coastguard Worker 
1530*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1531*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1532*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1533*ec779b8eSAndroid Build Coastguard Worker     }
1534*ec779b8eSAndroid Build Coastguard Worker 
1535*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
1536*ec779b8eSAndroid Build Coastguard Worker     if (mPrimaryHardwareDev == nullptr) {
1537*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
1538*ec779b8eSAndroid Build Coastguard Worker     }
1539*ec779b8eSAndroid Build Coastguard Worker     sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev.load()->hwDevice();
1540*ec779b8eSAndroid Build Coastguard Worker     if (primaryDev == nullptr) {
1541*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: no primary HAL device", __func__);
1542*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
1543*ec779b8eSAndroid Build Coastguard Worker     }
1544*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
1545*ec779b8eSAndroid Build Coastguard Worker     ret = primaryDev->setMicMute(state);
1546*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1547*ec779b8eSAndroid Build Coastguard Worker         sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
1548*ec779b8eSAndroid Build Coastguard Worker         if (dev != primaryDev) {
1549*ec779b8eSAndroid Build Coastguard Worker             (void)dev->setMicMute(state);
1550*ec779b8eSAndroid Build Coastguard Worker         }
1551*ec779b8eSAndroid Build Coastguard Worker     }
1552*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
1553*ec779b8eSAndroid Build Coastguard Worker     ALOGW_IF(ret != NO_ERROR, "%s: error %d setting state to HAL", __func__, ret);
1554*ec779b8eSAndroid Build Coastguard Worker     return ret;
1555*ec779b8eSAndroid Build Coastguard Worker }
1556*ec779b8eSAndroid Build Coastguard Worker 
getMicMute() const1557*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::getMicMute() const
1558*ec779b8eSAndroid Build Coastguard Worker {
1559*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
1560*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
1561*ec779b8eSAndroid Build Coastguard Worker         return false;
1562*ec779b8eSAndroid Build Coastguard Worker     }
1563*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
1564*ec779b8eSAndroid Build Coastguard Worker     if (mPrimaryHardwareDev == nullptr) {
1565*ec779b8eSAndroid Build Coastguard Worker         return false;
1566*ec779b8eSAndroid Build Coastguard Worker     }
1567*ec779b8eSAndroid Build Coastguard Worker     sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev.load()->hwDevice();
1568*ec779b8eSAndroid Build Coastguard Worker     if (primaryDev == nullptr) {
1569*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: no primary HAL device", __func__);
1570*ec779b8eSAndroid Build Coastguard Worker         return false;
1571*ec779b8eSAndroid Build Coastguard Worker     }
1572*ec779b8eSAndroid Build Coastguard Worker     bool state;
1573*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
1574*ec779b8eSAndroid Build Coastguard Worker     ret = primaryDev->getMicMute(&state);
1575*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
1576*ec779b8eSAndroid Build Coastguard Worker     ALOGE_IF(ret != NO_ERROR, "%s: error %d getting state from HAL", __func__, ret);
1577*ec779b8eSAndroid Build Coastguard Worker     return (ret == NO_ERROR) && state;
1578*ec779b8eSAndroid Build Coastguard Worker }
1579*ec779b8eSAndroid Build Coastguard Worker 
setRecordSilenced(audio_port_handle_t portId,bool silenced)1580*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::setRecordSilenced(audio_port_handle_t portId, bool silenced)
1581*ec779b8eSAndroid Build Coastguard Worker {
1582*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AudioFlinger::setRecordSilenced(portId:%d, silenced:%d)", portId, silenced);
1583*ec779b8eSAndroid Build Coastguard Worker 
1584*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(mutex());
1585*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
1586*ec779b8eSAndroid Build Coastguard Worker         mRecordThreads[i]->setRecordSilenced(portId, silenced);
1587*ec779b8eSAndroid Build Coastguard Worker     }
1588*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mMmapThreads.size(); i++) {
1589*ec779b8eSAndroid Build Coastguard Worker         mMmapThreads[i]->setRecordSilenced(portId, silenced);
1590*ec779b8eSAndroid Build Coastguard Worker     }
1591*ec779b8eSAndroid Build Coastguard Worker }
1592*ec779b8eSAndroid Build Coastguard Worker 
setMasterMute(bool muted)1593*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setMasterMute(bool muted)
1594*ec779b8eSAndroid Build Coastguard Worker {
1595*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
1596*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
1597*ec779b8eSAndroid Build Coastguard Worker         return ret;
1598*ec779b8eSAndroid Build Coastguard Worker     }
1599*ec779b8eSAndroid Build Coastguard Worker 
1600*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1601*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1602*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1603*ec779b8eSAndroid Build Coastguard Worker     }
1604*ec779b8eSAndroid Build Coastguard Worker 
1605*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1606*ec779b8eSAndroid Build Coastguard Worker     mMasterMute = muted;
1607*ec779b8eSAndroid Build Coastguard Worker 
1608*ec779b8eSAndroid Build Coastguard Worker     // Set master mute in the HALs which support it.
1609*ec779b8eSAndroid Build Coastguard Worker     {
1610*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard lock(hardwareMutex());
1611*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1612*ec779b8eSAndroid Build Coastguard Worker             AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
1613*ec779b8eSAndroid Build Coastguard Worker 
1614*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
1615*ec779b8eSAndroid Build Coastguard Worker             if (dev->canSetMasterMute()) {
1616*ec779b8eSAndroid Build Coastguard Worker                 dev->hwDevice()->setMasterMute(muted);
1617*ec779b8eSAndroid Build Coastguard Worker             }
1618*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_IDLE;
1619*ec779b8eSAndroid Build Coastguard Worker         }
1620*ec779b8eSAndroid Build Coastguard Worker     }
1621*ec779b8eSAndroid Build Coastguard Worker 
1622*ec779b8eSAndroid Build Coastguard Worker     // Now set the master mute in each playback thread.  Playback threads
1623*ec779b8eSAndroid Build Coastguard Worker     // assigned to HALs which do not have master mute support will apply master mute
1624*ec779b8eSAndroid Build Coastguard Worker     // during the mix operation.  Threads with HALs which do support master mute
1625*ec779b8eSAndroid Build Coastguard Worker     // will simply ignore the setting.
1626*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<VolumeInterface>> volumeInterfaces = getAllVolumeInterfaces_l();
1627*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < volumeInterfaces.size(); i++) {
1628*ec779b8eSAndroid Build Coastguard Worker         volumeInterfaces[i]->setMasterMute(muted);
1629*ec779b8eSAndroid Build Coastguard Worker     }
1630*ec779b8eSAndroid Build Coastguard Worker 
1631*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1632*ec779b8eSAndroid Build Coastguard Worker }
1633*ec779b8eSAndroid Build Coastguard Worker 
masterVolume() const1634*ec779b8eSAndroid Build Coastguard Worker float AudioFlinger::masterVolume() const
1635*ec779b8eSAndroid Build Coastguard Worker {
1636*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1637*ec779b8eSAndroid Build Coastguard Worker     return masterVolume_l();
1638*ec779b8eSAndroid Build Coastguard Worker }
1639*ec779b8eSAndroid Build Coastguard Worker 
getMasterBalance(float * balance) const1640*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getMasterBalance(float *balance) const
1641*ec779b8eSAndroid Build Coastguard Worker {
1642*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1643*ec779b8eSAndroid Build Coastguard Worker     *balance = getMasterBalance_l();
1644*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR; // if called through binder, may return a transactional error
1645*ec779b8eSAndroid Build Coastguard Worker }
1646*ec779b8eSAndroid Build Coastguard Worker 
masterMute() const1647*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::masterMute() const
1648*ec779b8eSAndroid Build Coastguard Worker {
1649*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1650*ec779b8eSAndroid Build Coastguard Worker     return masterMute_l();
1651*ec779b8eSAndroid Build Coastguard Worker }
1652*ec779b8eSAndroid Build Coastguard Worker 
masterVolume_l() const1653*ec779b8eSAndroid Build Coastguard Worker float AudioFlinger::masterVolume_l() const
1654*ec779b8eSAndroid Build Coastguard Worker {
1655*ec779b8eSAndroid Build Coastguard Worker     return mMasterVolume;
1656*ec779b8eSAndroid Build Coastguard Worker }
1657*ec779b8eSAndroid Build Coastguard Worker 
getMasterBalance_l() const1658*ec779b8eSAndroid Build Coastguard Worker float AudioFlinger::getMasterBalance_l() const
1659*ec779b8eSAndroid Build Coastguard Worker {
1660*ec779b8eSAndroid Build Coastguard Worker     return mMasterBalance;
1661*ec779b8eSAndroid Build Coastguard Worker }
1662*ec779b8eSAndroid Build Coastguard Worker 
masterMute_l() const1663*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::masterMute_l() const
1664*ec779b8eSAndroid Build Coastguard Worker {
1665*ec779b8eSAndroid Build Coastguard Worker     return mMasterMute;
1666*ec779b8eSAndroid Build Coastguard Worker }
1667*ec779b8eSAndroid Build Coastguard Worker 
1668*ec779b8eSAndroid Build Coastguard Worker /* static */
checkStreamType(audio_stream_type_t stream)1669*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::checkStreamType(audio_stream_type_t stream)
1670*ec779b8eSAndroid Build Coastguard Worker {
1671*ec779b8eSAndroid Build Coastguard Worker     if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
1672*ec779b8eSAndroid Build Coastguard Worker         ALOGW("checkStreamType() invalid stream %d", stream);
1673*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1674*ec779b8eSAndroid Build Coastguard Worker     }
1675*ec779b8eSAndroid Build Coastguard Worker     const uid_t callerUid = IPCThreadState::self()->getCallingUid();
1676*ec779b8eSAndroid Build Coastguard Worker     if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && !isAudioServerUid(callerUid)) {
1677*ec779b8eSAndroid Build Coastguard Worker         ALOGW("checkStreamType() uid %d cannot use internal stream type %d", callerUid, stream);
1678*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1679*ec779b8eSAndroid Build Coastguard Worker     }
1680*ec779b8eSAndroid Build Coastguard Worker 
1681*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1682*ec779b8eSAndroid Build Coastguard Worker }
1683*ec779b8eSAndroid Build Coastguard Worker 
setStreamVolume(audio_stream_type_t stream,float value,bool muted,audio_io_handle_t output)1684*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
1685*ec779b8eSAndroid Build Coastguard Worker         bool muted, audio_io_handle_t output)
1686*ec779b8eSAndroid Build Coastguard Worker {
1687*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1688*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1689*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1690*ec779b8eSAndroid Build Coastguard Worker     }
1691*ec779b8eSAndroid Build Coastguard Worker 
1692*ec779b8eSAndroid Build Coastguard Worker     status_t status = checkStreamType(stream);
1693*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
1694*ec779b8eSAndroid Build Coastguard Worker         return status;
1695*ec779b8eSAndroid Build Coastguard Worker     }
1696*ec779b8eSAndroid Build Coastguard Worker     if (output == AUDIO_IO_HANDLE_NONE) {
1697*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1698*ec779b8eSAndroid Build Coastguard Worker     }
1699*ec779b8eSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(stream == AUDIO_STREAM_PATCH && value != 1.0f,
1700*ec779b8eSAndroid Build Coastguard Worker                         "AUDIO_STREAM_PATCH must have full scale volume");
1701*ec779b8eSAndroid Build Coastguard Worker 
1702*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(mutex());
1703*ec779b8eSAndroid Build Coastguard Worker     sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
1704*ec779b8eSAndroid Build Coastguard Worker     if (volumeInterface == NULL) {
1705*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1706*ec779b8eSAndroid Build Coastguard Worker     }
1707*ec779b8eSAndroid Build Coastguard Worker     volumeInterface->setStreamVolume(stream, value, muted);
1708*ec779b8eSAndroid Build Coastguard Worker 
1709*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1710*ec779b8eSAndroid Build Coastguard Worker }
1711*ec779b8eSAndroid Build Coastguard Worker 
setPortsVolume(const std::vector<audio_port_handle_t> & ports,float volume,bool muted,audio_io_handle_t output)1712*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setPortsVolume(
1713*ec779b8eSAndroid Build Coastguard Worker         const std::vector<audio_port_handle_t> &ports, float volume, bool muted,
1714*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output) {
1715*ec779b8eSAndroid Build Coastguard Worker     for (const auto& port : ports) {
1716*ec779b8eSAndroid Build Coastguard Worker         if (port == AUDIO_PORT_HANDLE_NONE) {
1717*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
1718*ec779b8eSAndroid Build Coastguard Worker         }
1719*ec779b8eSAndroid Build Coastguard Worker     }
1720*ec779b8eSAndroid Build Coastguard Worker     if (isnan(volume) || volume > 1.0f || volume < 0.0f) {
1721*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1722*ec779b8eSAndroid Build Coastguard Worker     }
1723*ec779b8eSAndroid Build Coastguard Worker     if (output == AUDIO_IO_HANDLE_NONE) {
1724*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1725*ec779b8eSAndroid Build Coastguard Worker     }
1726*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(mutex());
1727*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread *thread = checkPlaybackThread_l(output);
1728*ec779b8eSAndroid Build Coastguard Worker     if (thread != nullptr) {
1729*ec779b8eSAndroid Build Coastguard Worker         return thread->setPortsVolume(ports, volume, muted);
1730*ec779b8eSAndroid Build Coastguard Worker     }
1731*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfMmapThread> mmapThread = checkMmapThread_l(output);
1732*ec779b8eSAndroid Build Coastguard Worker     if (mmapThread != nullptr && mmapThread->isOutput()) {
1733*ec779b8eSAndroid Build Coastguard Worker         IAfMmapPlaybackThread *mmapPlaybackThread = mmapThread->asIAfMmapPlaybackThread().get();
1734*ec779b8eSAndroid Build Coastguard Worker         return mmapPlaybackThread->setPortsVolume(ports, volume, muted);
1735*ec779b8eSAndroid Build Coastguard Worker     }
1736*ec779b8eSAndroid Build Coastguard Worker     return BAD_VALUE;
1737*ec779b8eSAndroid Build Coastguard Worker }
1738*ec779b8eSAndroid Build Coastguard Worker 
setRequestedLatencyMode(audio_io_handle_t output,audio_latency_mode_t mode)1739*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setRequestedLatencyMode(
1740*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output, audio_latency_mode_t mode) {
1741*ec779b8eSAndroid Build Coastguard Worker     if (output == AUDIO_IO_HANDLE_NONE) {
1742*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1743*ec779b8eSAndroid Build Coastguard Worker     }
1744*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(mutex());
1745*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
1746*ec779b8eSAndroid Build Coastguard Worker     if (thread == nullptr) {
1747*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1748*ec779b8eSAndroid Build Coastguard Worker     }
1749*ec779b8eSAndroid Build Coastguard Worker     return thread->setRequestedLatencyMode(mode);
1750*ec779b8eSAndroid Build Coastguard Worker }
1751*ec779b8eSAndroid Build Coastguard Worker 
getSupportedLatencyModes(audio_io_handle_t output,std::vector<audio_latency_mode_t> * modes) const1752*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getSupportedLatencyModes(audio_io_handle_t output,
1753*ec779b8eSAndroid Build Coastguard Worker             std::vector<audio_latency_mode_t>* modes) const {
1754*ec779b8eSAndroid Build Coastguard Worker     if (output == AUDIO_IO_HANDLE_NONE) {
1755*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1756*ec779b8eSAndroid Build Coastguard Worker     }
1757*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(mutex());
1758*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
1759*ec779b8eSAndroid Build Coastguard Worker     if (thread == nullptr) {
1760*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1761*ec779b8eSAndroid Build Coastguard Worker     }
1762*ec779b8eSAndroid Build Coastguard Worker     return thread->getSupportedLatencyModes(modes);
1763*ec779b8eSAndroid Build Coastguard Worker }
1764*ec779b8eSAndroid Build Coastguard Worker 
setBluetoothVariableLatencyEnabled(bool enabled)1765*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setBluetoothVariableLatencyEnabled(bool enabled) {
1766*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
1767*ec779b8eSAndroid Build Coastguard Worker     status_t status = INVALID_OPERATION;
1768*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1769*ec779b8eSAndroid Build Coastguard Worker         // Success if at least one PlaybackThread supports Bluetooth latency modes
1770*ec779b8eSAndroid Build Coastguard Worker         if (mPlaybackThreads.valueAt(i)->setBluetoothVariableLatencyEnabled(enabled) == NO_ERROR) {
1771*ec779b8eSAndroid Build Coastguard Worker             status = NO_ERROR;
1772*ec779b8eSAndroid Build Coastguard Worker         }
1773*ec779b8eSAndroid Build Coastguard Worker     }
1774*ec779b8eSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
1775*ec779b8eSAndroid Build Coastguard Worker         mBluetoothLatencyModesEnabled.store(enabled);
1776*ec779b8eSAndroid Build Coastguard Worker     }
1777*ec779b8eSAndroid Build Coastguard Worker     return status;
1778*ec779b8eSAndroid Build Coastguard Worker }
1779*ec779b8eSAndroid Build Coastguard Worker 
isBluetoothVariableLatencyEnabled(bool * enabled) const1780*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::isBluetoothVariableLatencyEnabled(bool* enabled) const {
1781*ec779b8eSAndroid Build Coastguard Worker     if (enabled == nullptr) {
1782*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1783*ec779b8eSAndroid Build Coastguard Worker     }
1784*ec779b8eSAndroid Build Coastguard Worker     *enabled = mBluetoothLatencyModesEnabled.load();
1785*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1786*ec779b8eSAndroid Build Coastguard Worker }
1787*ec779b8eSAndroid Build Coastguard Worker 
supportsBluetoothVariableLatency(bool * support) const1788*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::supportsBluetoothVariableLatency(bool* support) const {
1789*ec779b8eSAndroid Build Coastguard Worker     if (support == nullptr) {
1790*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1791*ec779b8eSAndroid Build Coastguard Worker     }
1792*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(hardwareMutex());
1793*ec779b8eSAndroid Build Coastguard Worker     *support = false;
1794*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1795*ec779b8eSAndroid Build Coastguard Worker         if (mAudioHwDevs.valueAt(i)->supportsBluetoothVariableLatency()) {
1796*ec779b8eSAndroid Build Coastguard Worker              *support = true;
1797*ec779b8eSAndroid Build Coastguard Worker              break;
1798*ec779b8eSAndroid Build Coastguard Worker         }
1799*ec779b8eSAndroid Build Coastguard Worker     }
1800*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1801*ec779b8eSAndroid Build Coastguard Worker }
1802*ec779b8eSAndroid Build Coastguard Worker 
getSoundDoseInterface(const sp<media::ISoundDoseCallback> & callback,sp<media::ISoundDose> * soundDose) const1803*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
1804*ec779b8eSAndroid Build Coastguard Worker                                              sp<media::ISoundDose>* soundDose) const {
1805*ec779b8eSAndroid Build Coastguard Worker     if (soundDose == nullptr) {
1806*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1807*ec779b8eSAndroid Build Coastguard Worker     }
1808*ec779b8eSAndroid Build Coastguard Worker 
1809*ec779b8eSAndroid Build Coastguard Worker     *soundDose = mMelReporter->getSoundDoseInterface(callback);
1810*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1811*ec779b8eSAndroid Build Coastguard Worker }
1812*ec779b8eSAndroid Build Coastguard Worker 
setStreamMute(audio_stream_type_t stream,bool muted)1813*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
1814*ec779b8eSAndroid Build Coastguard Worker {
1815*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1816*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1817*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1818*ec779b8eSAndroid Build Coastguard Worker     }
1819*ec779b8eSAndroid Build Coastguard Worker 
1820*ec779b8eSAndroid Build Coastguard Worker     status_t status = checkStreamType(stream);
1821*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
1822*ec779b8eSAndroid Build Coastguard Worker         return status;
1823*ec779b8eSAndroid Build Coastguard Worker     }
1824*ec779b8eSAndroid Build Coastguard Worker     ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to mute AUDIO_STREAM_PATCH");
1825*ec779b8eSAndroid Build Coastguard Worker 
1826*ec779b8eSAndroid Build Coastguard Worker     if (uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
1827*ec779b8eSAndroid Build Coastguard Worker         ALOGE("setStreamMute() invalid stream %d", stream);
1828*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1829*ec779b8eSAndroid Build Coastguard Worker     }
1830*ec779b8eSAndroid Build Coastguard Worker 
1831*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(mutex());
1832*ec779b8eSAndroid Build Coastguard Worker     mStreamTypes[stream].mute = muted;
1833*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<VolumeInterface>> volumeInterfaces = getAllVolumeInterfaces_l();
1834*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < volumeInterfaces.size(); i++) {
1835*ec779b8eSAndroid Build Coastguard Worker         volumeInterfaces[i]->setStreamMute(stream, muted);
1836*ec779b8eSAndroid Build Coastguard Worker     }
1837*ec779b8eSAndroid Build Coastguard Worker 
1838*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
1839*ec779b8eSAndroid Build Coastguard Worker }
1840*ec779b8eSAndroid Build Coastguard Worker 
broadcastParametersToRecordThreads_l(const String8 & keyValuePairs)1841*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::broadcastParametersToRecordThreads_l(const String8& keyValuePairs)
1842*ec779b8eSAndroid Build Coastguard Worker {
1843*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
1844*ec779b8eSAndroid Build Coastguard Worker         mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
1845*ec779b8eSAndroid Build Coastguard Worker     }
1846*ec779b8eSAndroid Build Coastguard Worker }
1847*ec779b8eSAndroid Build Coastguard Worker 
updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector & devices)1848*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices)
1849*ec779b8eSAndroid Build Coastguard Worker {
1850*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
1851*ec779b8eSAndroid Build Coastguard Worker         mRecordThreads.valueAt(i)->updateOutDevices(devices);
1852*ec779b8eSAndroid Build Coastguard Worker     }
1853*ec779b8eSAndroid Build Coastguard Worker }
1854*ec779b8eSAndroid Build Coastguard Worker 
1855*ec779b8eSAndroid Build Coastguard Worker // forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mutex() held
forwardParametersToDownstreamPatches_l(audio_io_handle_t upStream,const String8 & keyValuePairs,const std::function<bool (const sp<IAfPlaybackThread> &)> & useThread)1856*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::forwardParametersToDownstreamPatches_l(
1857*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t upStream, const String8& keyValuePairs,
1858*ec779b8eSAndroid Build Coastguard Worker         const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread)
1859*ec779b8eSAndroid Build Coastguard Worker {
1860*ec779b8eSAndroid Build Coastguard Worker     std::vector<SoftwarePatch> swPatches;
1861*ec779b8eSAndroid Build Coastguard Worker     if (mPatchPanel->getDownstreamSoftwarePatches(upStream, &swPatches) != OK) return;
1862*ec779b8eSAndroid Build Coastguard Worker     ALOGV_IF(!swPatches.empty(), "%s found %zu downstream patches for stream ID %d",
1863*ec779b8eSAndroid Build Coastguard Worker             __func__, swPatches.size(), upStream);
1864*ec779b8eSAndroid Build Coastguard Worker     for (const auto& swPatch : swPatches) {
1865*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfPlaybackThread> downStream =
1866*ec779b8eSAndroid Build Coastguard Worker                 checkPlaybackThread_l(swPatch.getPlaybackThreadHandle());
1867*ec779b8eSAndroid Build Coastguard Worker         if (downStream != NULL && (useThread == nullptr || useThread(downStream))) {
1868*ec779b8eSAndroid Build Coastguard Worker             downStream->setParameters(keyValuePairs);
1869*ec779b8eSAndroid Build Coastguard Worker         }
1870*ec779b8eSAndroid Build Coastguard Worker     }
1871*ec779b8eSAndroid Build Coastguard Worker }
1872*ec779b8eSAndroid Build Coastguard Worker 
1873*ec779b8eSAndroid Build Coastguard Worker // Update downstream patches for all playback threads attached to an MSD module
updateDownStreamPatches_l(const struct audio_patch * patch,const std::set<audio_io_handle_t> & streams)1874*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::updateDownStreamPatches_l(const struct audio_patch *patch,
1875*ec779b8eSAndroid Build Coastguard Worker                                              const std::set<audio_io_handle_t>& streams)
1876*ec779b8eSAndroid Build Coastguard Worker {
1877*ec779b8eSAndroid Build Coastguard Worker     for (const audio_io_handle_t stream : streams) {
1878*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const playbackThread = checkPlaybackThread_l(stream);
1879*ec779b8eSAndroid Build Coastguard Worker         if (playbackThread == nullptr || !playbackThread->isMsdDevice()) {
1880*ec779b8eSAndroid Build Coastguard Worker             continue;
1881*ec779b8eSAndroid Build Coastguard Worker         }
1882*ec779b8eSAndroid Build Coastguard Worker         playbackThread->setDownStreamPatch(patch);
1883*ec779b8eSAndroid Build Coastguard Worker         playbackThread->sendIoConfigEvent(AUDIO_OUTPUT_CONFIG_CHANGED);
1884*ec779b8eSAndroid Build Coastguard Worker     }
1885*ec779b8eSAndroid Build Coastguard Worker }
1886*ec779b8eSAndroid Build Coastguard Worker 
1887*ec779b8eSAndroid Build Coastguard Worker // Filter reserved keys from setParameters() before forwarding to audio HAL or acting upon.
1888*ec779b8eSAndroid Build Coastguard Worker // Some keys are used for audio routing and audio path configuration and should be reserved for use
1889*ec779b8eSAndroid Build Coastguard Worker // by audio policy and audio flinger for functional, privacy and security reasons.
filterReservedParameters(String8 & keyValuePairs,uid_t callingUid)1890*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::filterReservedParameters(String8& keyValuePairs, uid_t callingUid)
1891*ec779b8eSAndroid Build Coastguard Worker {
1892*ec779b8eSAndroid Build Coastguard Worker     static const String8 kReservedParameters[] = {
1893*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyRouting),
1894*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keySamplingRate),
1895*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyFormat),
1896*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyChannels),
1897*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyFrameCount),
1898*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyInputSource),
1899*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyMonoOutput),
1900*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyDeviceConnect),
1901*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyDeviceDisconnect),
1902*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyStreamSupportedFormats),
1903*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyStreamSupportedChannels),
1904*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyStreamSupportedSamplingRates),
1905*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyClosing),
1906*ec779b8eSAndroid Build Coastguard Worker         String8(AudioParameter::keyExiting),
1907*ec779b8eSAndroid Build Coastguard Worker     };
1908*ec779b8eSAndroid Build Coastguard Worker 
1909*ec779b8eSAndroid Build Coastguard Worker     if (isAudioServerUid(callingUid)) {
1910*ec779b8eSAndroid Build Coastguard Worker         return; // no need to filter if audioserver.
1911*ec779b8eSAndroid Build Coastguard Worker     }
1912*ec779b8eSAndroid Build Coastguard Worker 
1913*ec779b8eSAndroid Build Coastguard Worker     AudioParameter param = AudioParameter(keyValuePairs);
1914*ec779b8eSAndroid Build Coastguard Worker     String8 value;
1915*ec779b8eSAndroid Build Coastguard Worker     AudioParameter rejectedParam;
1916*ec779b8eSAndroid Build Coastguard Worker     for (auto& key : kReservedParameters) {
1917*ec779b8eSAndroid Build Coastguard Worker         if (param.get(key, value) == NO_ERROR) {
1918*ec779b8eSAndroid Build Coastguard Worker             rejectedParam.add(key, value);
1919*ec779b8eSAndroid Build Coastguard Worker             param.remove(key);
1920*ec779b8eSAndroid Build Coastguard Worker         }
1921*ec779b8eSAndroid Build Coastguard Worker     }
1922*ec779b8eSAndroid Build Coastguard Worker     logFilteredParameters(param.size() + rejectedParam.size(), keyValuePairs,
1923*ec779b8eSAndroid Build Coastguard Worker                           rejectedParam.size(), rejectedParam.toString(), callingUid);
1924*ec779b8eSAndroid Build Coastguard Worker     keyValuePairs = param.toString();
1925*ec779b8eSAndroid Build Coastguard Worker }
1926*ec779b8eSAndroid Build Coastguard Worker 
logFilteredParameters(size_t originalKVPSize,const String8 & originalKVPs,size_t rejectedKVPSize,const String8 & rejectedKVPs,uid_t callingUid)1927*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::logFilteredParameters(size_t originalKVPSize, const String8& originalKVPs,
1928*ec779b8eSAndroid Build Coastguard Worker                                          size_t rejectedKVPSize, const String8& rejectedKVPs,
1929*ec779b8eSAndroid Build Coastguard Worker                                          uid_t callingUid) {
1930*ec779b8eSAndroid Build Coastguard Worker     auto prefix = String8::format("UID %5d", callingUid);
1931*ec779b8eSAndroid Build Coastguard Worker     auto suffix = String8::format("%zu KVP received: %s", originalKVPSize, originalKVPs.c_str());
1932*ec779b8eSAndroid Build Coastguard Worker     if (rejectedKVPSize != 0) {
1933*ec779b8eSAndroid Build Coastguard Worker         auto error = String8::format("%zu KVP rejected: %s", rejectedKVPSize, rejectedKVPs.c_str());
1934*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: %s, %s, %s", __func__, prefix.c_str(), error.c_str(), suffix.c_str());
1935*ec779b8eSAndroid Build Coastguard Worker         mRejectedSetParameterLog.log("%s, %s, %s", prefix.c_str(), error.c_str(), suffix.c_str());
1936*ec779b8eSAndroid Build Coastguard Worker     } else {
1937*ec779b8eSAndroid Build Coastguard Worker         auto& logger = (isServiceUid(callingUid) ? mSystemSetParameterLog : mAppSetParameterLog);
1938*ec779b8eSAndroid Build Coastguard Worker         logger.log("%s, %s", prefix.c_str(), suffix.c_str());
1939*ec779b8eSAndroid Build Coastguard Worker     }
1940*ec779b8eSAndroid Build Coastguard Worker }
1941*ec779b8eSAndroid Build Coastguard Worker 
setParameters(audio_io_handle_t ioHandle,const String8 & keyValuePairs)1942*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
1943*ec779b8eSAndroid Build Coastguard Worker {
1944*ec779b8eSAndroid Build Coastguard Worker     ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d calling uid %d",
1945*ec779b8eSAndroid Build Coastguard Worker             ioHandle, keyValuePairs.c_str(),
1946*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1947*ec779b8eSAndroid Build Coastguard Worker 
1948*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
1949*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
1950*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
1951*ec779b8eSAndroid Build Coastguard Worker     }
1952*ec779b8eSAndroid Build Coastguard Worker 
1953*ec779b8eSAndroid Build Coastguard Worker     String8 filteredKeyValuePairs = keyValuePairs;
1954*ec779b8eSAndroid Build Coastguard Worker     filterReservedParameters(filteredKeyValuePairs, IPCThreadState::self()->getCallingUid());
1955*ec779b8eSAndroid Build Coastguard Worker 
1956*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: filtered keyvalue %s", __func__, filteredKeyValuePairs.c_str());
1957*ec779b8eSAndroid Build Coastguard Worker 
1958*ec779b8eSAndroid Build Coastguard Worker     // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
1959*ec779b8eSAndroid Build Coastguard Worker     if (ioHandle == AUDIO_IO_HANDLE_NONE) {
1960*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
1961*ec779b8eSAndroid Build Coastguard Worker         // result will remain NO_INIT if no audio device is present
1962*ec779b8eSAndroid Build Coastguard Worker         status_t final_result = NO_INIT;
1963*ec779b8eSAndroid Build Coastguard Worker         {
1964*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard lock(hardwareMutex());
1965*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_SET_PARAMETER;
1966*ec779b8eSAndroid Build Coastguard Worker             for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1967*ec779b8eSAndroid Build Coastguard Worker                 sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
1968*ec779b8eSAndroid Build Coastguard Worker                 status_t result = dev->setParameters(filteredKeyValuePairs);
1969*ec779b8eSAndroid Build Coastguard Worker                 // return success if at least one audio device accepts the parameters as not all
1970*ec779b8eSAndroid Build Coastguard Worker                 // HALs are requested to support all parameters. If no audio device supports the
1971*ec779b8eSAndroid Build Coastguard Worker                 // requested parameters, the last error is reported.
1972*ec779b8eSAndroid Build Coastguard Worker                 if (final_result != NO_ERROR) {
1973*ec779b8eSAndroid Build Coastguard Worker                     final_result = result;
1974*ec779b8eSAndroid Build Coastguard Worker                 }
1975*ec779b8eSAndroid Build Coastguard Worker             }
1976*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_IDLE;
1977*ec779b8eSAndroid Build Coastguard Worker         }
1978*ec779b8eSAndroid Build Coastguard Worker         // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
1979*ec779b8eSAndroid Build Coastguard Worker         AudioParameter param = AudioParameter(filteredKeyValuePairs);
1980*ec779b8eSAndroid Build Coastguard Worker         String8 value;
1981*ec779b8eSAndroid Build Coastguard Worker         if (param.get(String8(AudioParameter::keyBtNrec), value) == NO_ERROR) {
1982*ec779b8eSAndroid Build Coastguard Worker             bool btNrecIsOff = (value == AudioParameter::valueOff);
1983*ec779b8eSAndroid Build Coastguard Worker             if (mBtNrecIsOff.exchange(btNrecIsOff) != btNrecIsOff) {
1984*ec779b8eSAndroid Build Coastguard Worker                 for (size_t i = 0; i < mRecordThreads.size(); i++) {
1985*ec779b8eSAndroid Build Coastguard Worker                     mRecordThreads.valueAt(i)->checkBtNrec();
1986*ec779b8eSAndroid Build Coastguard Worker                 }
1987*ec779b8eSAndroid Build Coastguard Worker             }
1988*ec779b8eSAndroid Build Coastguard Worker         }
1989*ec779b8eSAndroid Build Coastguard Worker         String8 screenState;
1990*ec779b8eSAndroid Build Coastguard Worker         if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
1991*ec779b8eSAndroid Build Coastguard Worker             bool isOff = (screenState == AudioParameter::valueOff);
1992*ec779b8eSAndroid Build Coastguard Worker             if (isOff != (mScreenState & 1)) {
1993*ec779b8eSAndroid Build Coastguard Worker                 mScreenState = ((mScreenState & ~1) + 2) | isOff;
1994*ec779b8eSAndroid Build Coastguard Worker             }
1995*ec779b8eSAndroid Build Coastguard Worker         }
1996*ec779b8eSAndroid Build Coastguard Worker         return final_result;
1997*ec779b8eSAndroid Build Coastguard Worker     }
1998*ec779b8eSAndroid Build Coastguard Worker 
1999*ec779b8eSAndroid Build Coastguard Worker     // hold a strong ref on thread in case closeOutput() or closeInput() is called
2000*ec779b8eSAndroid Build Coastguard Worker     // and the thread is exited once the lock is released
2001*ec779b8eSAndroid Build Coastguard Worker     sp<IAfThreadBase> thread;
2002*ec779b8eSAndroid Build Coastguard Worker     {
2003*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
2004*ec779b8eSAndroid Build Coastguard Worker         thread = checkPlaybackThread_l(ioHandle);
2005*ec779b8eSAndroid Build Coastguard Worker         if (thread == 0) {
2006*ec779b8eSAndroid Build Coastguard Worker             thread = checkRecordThread_l(ioHandle);
2007*ec779b8eSAndroid Build Coastguard Worker             if (thread == 0) {
2008*ec779b8eSAndroid Build Coastguard Worker                 thread = checkMmapThread_l(ioHandle);
2009*ec779b8eSAndroid Build Coastguard Worker             }
2010*ec779b8eSAndroid Build Coastguard Worker         } else if (thread == primaryPlaybackThread_l()) {
2011*ec779b8eSAndroid Build Coastguard Worker             // indicate output device change to all input threads for pre processing
2012*ec779b8eSAndroid Build Coastguard Worker             AudioParameter param = AudioParameter(filteredKeyValuePairs);
2013*ec779b8eSAndroid Build Coastguard Worker             int value;
2014*ec779b8eSAndroid Build Coastguard Worker             if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
2015*ec779b8eSAndroid Build Coastguard Worker                     (value != 0)) {
2016*ec779b8eSAndroid Build Coastguard Worker                 broadcastParametersToRecordThreads_l(filteredKeyValuePairs);
2017*ec779b8eSAndroid Build Coastguard Worker             }
2018*ec779b8eSAndroid Build Coastguard Worker         }
2019*ec779b8eSAndroid Build Coastguard Worker     }
2020*ec779b8eSAndroid Build Coastguard Worker     if (thread != 0) {
2021*ec779b8eSAndroid Build Coastguard Worker         status_t result = thread->setParameters(filteredKeyValuePairs);
2022*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
2023*ec779b8eSAndroid Build Coastguard Worker         forwardParametersToDownstreamPatches_l(thread->id(), filteredKeyValuePairs);
2024*ec779b8eSAndroid Build Coastguard Worker         return result;
2025*ec779b8eSAndroid Build Coastguard Worker     }
2026*ec779b8eSAndroid Build Coastguard Worker     return BAD_VALUE;
2027*ec779b8eSAndroid Build Coastguard Worker }
2028*ec779b8eSAndroid Build Coastguard Worker 
getParameters(audio_io_handle_t ioHandle,const String8 & keys) const2029*ec779b8eSAndroid Build Coastguard Worker String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
2030*ec779b8eSAndroid Build Coastguard Worker {
2031*ec779b8eSAndroid Build Coastguard Worker     ALOGVV("getParameters() io %d, keys %s, calling pid %d",
2032*ec779b8eSAndroid Build Coastguard Worker             ioHandle, keys.c_str(), IPCThreadState::self()->getCallingPid());
2033*ec779b8eSAndroid Build Coastguard Worker 
2034*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2035*ec779b8eSAndroid Build Coastguard Worker 
2036*ec779b8eSAndroid Build Coastguard Worker     if (ioHandle == AUDIO_IO_HANDLE_NONE) {
2037*ec779b8eSAndroid Build Coastguard Worker         String8 out_s8;
2038*ec779b8eSAndroid Build Coastguard Worker 
2039*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard lock(hardwareMutex());
2040*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
2041*ec779b8eSAndroid Build Coastguard Worker             String8 s;
2042*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_GET_PARAMETER;
2043*ec779b8eSAndroid Build Coastguard Worker             sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
2044*ec779b8eSAndroid Build Coastguard Worker             status_t result = dev->getParameters(keys, &s);
2045*ec779b8eSAndroid Build Coastguard Worker             mHardwareStatus = AUDIO_HW_IDLE;
2046*ec779b8eSAndroid Build Coastguard Worker             if (result == OK) out_s8 += s;
2047*ec779b8eSAndroid Build Coastguard Worker         }
2048*ec779b8eSAndroid Build Coastguard Worker         return out_s8;
2049*ec779b8eSAndroid Build Coastguard Worker     }
2050*ec779b8eSAndroid Build Coastguard Worker 
2051*ec779b8eSAndroid Build Coastguard Worker     IAfThreadBase* thread = checkPlaybackThread_l(ioHandle);
2052*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
2053*ec779b8eSAndroid Build Coastguard Worker         thread = checkRecordThread_l(ioHandle);
2054*ec779b8eSAndroid Build Coastguard Worker         if (thread == NULL) {
2055*ec779b8eSAndroid Build Coastguard Worker             thread = checkMmapThread_l(ioHandle);
2056*ec779b8eSAndroid Build Coastguard Worker             if (thread == NULL) {
2057*ec779b8eSAndroid Build Coastguard Worker                 return String8("");
2058*ec779b8eSAndroid Build Coastguard Worker             }
2059*ec779b8eSAndroid Build Coastguard Worker         }
2060*ec779b8eSAndroid Build Coastguard Worker     }
2061*ec779b8eSAndroid Build Coastguard Worker     return thread->getParameters(keys);
2062*ec779b8eSAndroid Build Coastguard Worker }
2063*ec779b8eSAndroid Build Coastguard Worker 
getInputBufferSize(uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask) const2064*ec779b8eSAndroid Build Coastguard Worker size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
2065*ec779b8eSAndroid Build Coastguard Worker         audio_channel_mask_t channelMask) const
2066*ec779b8eSAndroid Build Coastguard Worker {
2067*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
2068*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
2069*ec779b8eSAndroid Build Coastguard Worker         return 0;
2070*ec779b8eSAndroid Build Coastguard Worker     }
2071*ec779b8eSAndroid Build Coastguard Worker     if ((sampleRate == 0) ||
2072*ec779b8eSAndroid Build Coastguard Worker             !audio_is_valid_format(format) ||
2073*ec779b8eSAndroid Build Coastguard Worker             !audio_is_input_channel(channelMask)) {
2074*ec779b8eSAndroid Build Coastguard Worker         return 0;
2075*ec779b8eSAndroid Build Coastguard Worker     }
2076*ec779b8eSAndroid Build Coastguard Worker 
2077*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
2078*ec779b8eSAndroid Build Coastguard Worker     if (mPrimaryHardwareDev == nullptr) {
2079*ec779b8eSAndroid Build Coastguard Worker         return 0;
2080*ec779b8eSAndroid Build Coastguard Worker     }
2081*ec779b8eSAndroid Build Coastguard Worker     if (mInputBufferSizeOrderedDevs.empty()) {
2082*ec779b8eSAndroid Build Coastguard Worker         return 0;
2083*ec779b8eSAndroid Build Coastguard Worker     }
2084*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
2085*ec779b8eSAndroid Build Coastguard Worker 
2086*ec779b8eSAndroid Build Coastguard Worker     std::vector<audio_channel_mask_t> channelMasks = {channelMask};
2087*ec779b8eSAndroid Build Coastguard Worker     if (channelMask != AUDIO_CHANNEL_IN_MONO) {
2088*ec779b8eSAndroid Build Coastguard Worker         channelMasks.push_back(AUDIO_CHANNEL_IN_MONO);
2089*ec779b8eSAndroid Build Coastguard Worker     }
2090*ec779b8eSAndroid Build Coastguard Worker     if (channelMask != AUDIO_CHANNEL_IN_STEREO) {
2091*ec779b8eSAndroid Build Coastguard Worker         channelMasks.push_back(AUDIO_CHANNEL_IN_STEREO);
2092*ec779b8eSAndroid Build Coastguard Worker     }
2093*ec779b8eSAndroid Build Coastguard Worker 
2094*ec779b8eSAndroid Build Coastguard Worker     std::vector<audio_format_t> formats = {format};
2095*ec779b8eSAndroid Build Coastguard Worker     if (format != AUDIO_FORMAT_PCM_16_BIT) {
2096*ec779b8eSAndroid Build Coastguard Worker         // For compressed format, buffer size may be queried using PCM. Allow this for compatibility
2097*ec779b8eSAndroid Build Coastguard Worker         // in cases the primary hw dev does not support the format.
2098*ec779b8eSAndroid Build Coastguard Worker         // TODO: replace with a table of formats and nominal buffer sizes (based on nominal bitrate
2099*ec779b8eSAndroid Build Coastguard Worker         // and codec frame size).
2100*ec779b8eSAndroid Build Coastguard Worker         formats.push_back(AUDIO_FORMAT_PCM_16_BIT);
2101*ec779b8eSAndroid Build Coastguard Worker     }
2102*ec779b8eSAndroid Build Coastguard Worker 
2103*ec779b8eSAndroid Build Coastguard Worker     std::vector<uint32_t> sampleRates = {sampleRate};
2104*ec779b8eSAndroid Build Coastguard Worker     static const uint32_t SR_44100 = 44100;
2105*ec779b8eSAndroid Build Coastguard Worker     static const uint32_t SR_48000 = 48000;
2106*ec779b8eSAndroid Build Coastguard Worker     if (sampleRate != SR_48000) {
2107*ec779b8eSAndroid Build Coastguard Worker         sampleRates.push_back(SR_48000);
2108*ec779b8eSAndroid Build Coastguard Worker     }
2109*ec779b8eSAndroid Build Coastguard Worker     if (sampleRate != SR_44100) {
2110*ec779b8eSAndroid Build Coastguard Worker         sampleRates.push_back(SR_44100);
2111*ec779b8eSAndroid Build Coastguard Worker     }
2112*ec779b8eSAndroid Build Coastguard Worker 
2113*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
2114*ec779b8eSAndroid Build Coastguard Worker 
2115*ec779b8eSAndroid Build Coastguard Worker     auto getInputBufferSize = [](const sp<DeviceHalInterface>& dev, audio_config_t config,
2116*ec779b8eSAndroid Build Coastguard Worker                                  size_t* bytes) -> status_t {
2117*ec779b8eSAndroid Build Coastguard Worker         if (!dev) {
2118*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
2119*ec779b8eSAndroid Build Coastguard Worker         }
2120*ec779b8eSAndroid Build Coastguard Worker         status_t result = dev->getInputBufferSize(&config, bytes);
2121*ec779b8eSAndroid Build Coastguard Worker         if (result == BAD_VALUE) {
2122*ec779b8eSAndroid Build Coastguard Worker             // Retry with the config suggested by the HAL.
2123*ec779b8eSAndroid Build Coastguard Worker             result = dev->getInputBufferSize(&config, bytes);
2124*ec779b8eSAndroid Build Coastguard Worker         }
2125*ec779b8eSAndroid Build Coastguard Worker         if (result != OK || *bytes == 0) {
2126*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
2127*ec779b8eSAndroid Build Coastguard Worker         }
2128*ec779b8eSAndroid Build Coastguard Worker         return result;
2129*ec779b8eSAndroid Build Coastguard Worker     };
2130*ec779b8eSAndroid Build Coastguard Worker 
2131*ec779b8eSAndroid Build Coastguard Worker     // Change parameters of the configuration each iteration until we find a
2132*ec779b8eSAndroid Build Coastguard Worker     // configuration that the device will support, or HAL suggests what it supports.
2133*ec779b8eSAndroid Build Coastguard Worker     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2134*ec779b8eSAndroid Build Coastguard Worker     for (auto testChannelMask : channelMasks) {
2135*ec779b8eSAndroid Build Coastguard Worker         config.channel_mask = testChannelMask;
2136*ec779b8eSAndroid Build Coastguard Worker         for (auto testFormat : formats) {
2137*ec779b8eSAndroid Build Coastguard Worker             config.format = testFormat;
2138*ec779b8eSAndroid Build Coastguard Worker             for (auto testSampleRate : sampleRates) {
2139*ec779b8eSAndroid Build Coastguard Worker                 config.sample_rate = testSampleRate;
2140*ec779b8eSAndroid Build Coastguard Worker 
2141*ec779b8eSAndroid Build Coastguard Worker                 size_t bytes = 0;
2142*ec779b8eSAndroid Build Coastguard Worker                 ret = BAD_VALUE;
2143*ec779b8eSAndroid Build Coastguard Worker                 for (const AudioHwDevice* dev : mInputBufferSizeOrderedDevs) {
2144*ec779b8eSAndroid Build Coastguard Worker                     ret = getInputBufferSize(dev->hwDevice(), config, &bytes);
2145*ec779b8eSAndroid Build Coastguard Worker                     if (ret == OK) {
2146*ec779b8eSAndroid Build Coastguard Worker                         break;
2147*ec779b8eSAndroid Build Coastguard Worker                     }
2148*ec779b8eSAndroid Build Coastguard Worker                 }
2149*ec779b8eSAndroid Build Coastguard Worker                 if (ret == BAD_VALUE) continue;
2150*ec779b8eSAndroid Build Coastguard Worker 
2151*ec779b8eSAndroid Build Coastguard Worker                 if (config.sample_rate != sampleRate || config.channel_mask != channelMask ||
2152*ec779b8eSAndroid Build Coastguard Worker                     config.format != format) {
2153*ec779b8eSAndroid Build Coastguard Worker                     uint32_t dstChannelCount = audio_channel_count_from_in_mask(channelMask);
2154*ec779b8eSAndroid Build Coastguard Worker                     uint32_t srcChannelCount =
2155*ec779b8eSAndroid Build Coastguard Worker                         audio_channel_count_from_in_mask(config.channel_mask);
2156*ec779b8eSAndroid Build Coastguard Worker                     size_t srcFrames =
2157*ec779b8eSAndroid Build Coastguard Worker                         bytes / audio_bytes_per_frame(srcChannelCount, config.format);
2158*ec779b8eSAndroid Build Coastguard Worker                     size_t dstFrames = destinationFramesPossible(
2159*ec779b8eSAndroid Build Coastguard Worker                         srcFrames, config.sample_rate, sampleRate);
2160*ec779b8eSAndroid Build Coastguard Worker                     bytes = dstFrames * audio_bytes_per_frame(dstChannelCount, format);
2161*ec779b8eSAndroid Build Coastguard Worker                 }
2162*ec779b8eSAndroid Build Coastguard Worker                 return bytes;
2163*ec779b8eSAndroid Build Coastguard Worker             }
2164*ec779b8eSAndroid Build Coastguard Worker         }
2165*ec779b8eSAndroid Build Coastguard Worker     }
2166*ec779b8eSAndroid Build Coastguard Worker 
2167*ec779b8eSAndroid Build Coastguard Worker     ALOGW("getInputBufferSize failed with minimum buffer size sampleRate %u, "
2168*ec779b8eSAndroid Build Coastguard Worker               "format %#x, channelMask %#x",sampleRate, format, channelMask);
2169*ec779b8eSAndroid Build Coastguard Worker     return 0;
2170*ec779b8eSAndroid Build Coastguard Worker }
2171*ec779b8eSAndroid Build Coastguard Worker 
getInputFramesLost(audio_io_handle_t ioHandle) const2172*ec779b8eSAndroid Build Coastguard Worker uint32_t AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
2173*ec779b8eSAndroid Build Coastguard Worker {
2174*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2175*ec779b8eSAndroid Build Coastguard Worker 
2176*ec779b8eSAndroid Build Coastguard Worker     IAfRecordThread* const recordThread = checkRecordThread_l(ioHandle);
2177*ec779b8eSAndroid Build Coastguard Worker     if (recordThread != NULL) {
2178*ec779b8eSAndroid Build Coastguard Worker         return recordThread->getInputFramesLost();
2179*ec779b8eSAndroid Build Coastguard Worker     }
2180*ec779b8eSAndroid Build Coastguard Worker     return 0;
2181*ec779b8eSAndroid Build Coastguard Worker }
2182*ec779b8eSAndroid Build Coastguard Worker 
setVoiceVolume(float value)2183*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setVoiceVolume(float value)
2184*ec779b8eSAndroid Build Coastguard Worker {
2185*ec779b8eSAndroid Build Coastguard Worker     status_t ret = initCheck();
2186*ec779b8eSAndroid Build Coastguard Worker     if (ret != NO_ERROR) {
2187*ec779b8eSAndroid Build Coastguard Worker         return ret;
2188*ec779b8eSAndroid Build Coastguard Worker     }
2189*ec779b8eSAndroid Build Coastguard Worker 
2190*ec779b8eSAndroid Build Coastguard Worker     // check calling permissions
2191*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
2192*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
2193*ec779b8eSAndroid Build Coastguard Worker     }
2194*ec779b8eSAndroid Build Coastguard Worker 
2195*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
2196*ec779b8eSAndroid Build Coastguard Worker     if (mPrimaryHardwareDev == nullptr) {
2197*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
2198*ec779b8eSAndroid Build Coastguard Worker     }
2199*ec779b8eSAndroid Build Coastguard Worker     sp<DeviceHalInterface> dev = mPrimaryHardwareDev.load()->hwDevice();
2200*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
2201*ec779b8eSAndroid Build Coastguard Worker     ret = dev->setVoiceVolume(value);
2202*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
2203*ec779b8eSAndroid Build Coastguard Worker 
2204*ec779b8eSAndroid Build Coastguard Worker     mediametrics::LogItem(mMetricsId)
2205*ec779b8eSAndroid Build Coastguard Worker         .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETVOICEVOLUME)
2206*ec779b8eSAndroid Build Coastguard Worker         .set(AMEDIAMETRICS_PROP_VOICEVOLUME, (double)value)
2207*ec779b8eSAndroid Build Coastguard Worker         .record();
2208*ec779b8eSAndroid Build Coastguard Worker     return ret;
2209*ec779b8eSAndroid Build Coastguard Worker }
2210*ec779b8eSAndroid Build Coastguard Worker 
getRenderPosition(uint32_t * halFrames,uint32_t * dspFrames,audio_io_handle_t output) const2211*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
2212*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output) const
2213*ec779b8eSAndroid Build Coastguard Worker {
2214*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2215*ec779b8eSAndroid Build Coastguard Worker 
2216*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const playbackThread = checkPlaybackThread_l(output);
2217*ec779b8eSAndroid Build Coastguard Worker     if (playbackThread != NULL) {
2218*ec779b8eSAndroid Build Coastguard Worker         return playbackThread->getRenderPosition(halFrames, dspFrames);
2219*ec779b8eSAndroid Build Coastguard Worker     }
2220*ec779b8eSAndroid Build Coastguard Worker 
2221*ec779b8eSAndroid Build Coastguard Worker     return BAD_VALUE;
2222*ec779b8eSAndroid Build Coastguard Worker }
2223*ec779b8eSAndroid Build Coastguard Worker 
registerClient(const sp<media::IAudioFlingerClient> & client)2224*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::registerClient(const sp<media::IAudioFlingerClient>& client)
2225*ec779b8eSAndroid Build Coastguard Worker {
2226*ec779b8eSAndroid Build Coastguard Worker     if (client == 0) {
2227*ec779b8eSAndroid Build Coastguard Worker         return;
2228*ec779b8eSAndroid Build Coastguard Worker     }
2229*ec779b8eSAndroid Build Coastguard Worker     const pid_t pid = IPCThreadState::self()->getCallingPid();
2230*ec779b8eSAndroid Build Coastguard Worker     const uid_t uid = IPCThreadState::self()->getCallingUid();
2231*ec779b8eSAndroid Build Coastguard Worker 
2232*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2233*ec779b8eSAndroid Build Coastguard Worker     {
2234*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _cl(clientMutex());
2235*ec779b8eSAndroid Build Coastguard Worker         if (mNotificationClients.count(pid) == 0) {
2236*ec779b8eSAndroid Build Coastguard Worker             auto notificationClient = sp<NotificationClient>::make(
2237*ec779b8eSAndroid Build Coastguard Worker                     this, client, pid, uid);
2238*ec779b8eSAndroid Build Coastguard Worker             ALOGV("registerClient() client %p, pid %d, uid %u",
2239*ec779b8eSAndroid Build Coastguard Worker                     notificationClient.get(), pid, uid);
2240*ec779b8eSAndroid Build Coastguard Worker 
2241*ec779b8eSAndroid Build Coastguard Worker             mNotificationClients[pid] = notificationClient;
2242*ec779b8eSAndroid Build Coastguard Worker             sp<IBinder> binder = IInterface::asBinder(client);
2243*ec779b8eSAndroid Build Coastguard Worker             binder->linkToDeath(notificationClient);
2244*ec779b8eSAndroid Build Coastguard Worker         }
2245*ec779b8eSAndroid Build Coastguard Worker     }
2246*ec779b8eSAndroid Build Coastguard Worker 
2247*ec779b8eSAndroid Build Coastguard Worker     // clientMutex() should not be held here because ThreadBase::sendIoConfigEvent()
2248*ec779b8eSAndroid Build Coastguard Worker     // will lock the ThreadBase::mutex() and the locking order is
2249*ec779b8eSAndroid Build Coastguard Worker     // ThreadBase::mutex() then AudioFlinger::clientMutex().
2250*ec779b8eSAndroid Build Coastguard Worker     // The config change is always sent from playback or record threads to avoid deadlock
2251*ec779b8eSAndroid Build Coastguard Worker     // with AudioSystem::gLock
2252*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
2253*ec779b8eSAndroid Build Coastguard Worker         mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_REGISTERED, pid);
2254*ec779b8eSAndroid Build Coastguard Worker     }
2255*ec779b8eSAndroid Build Coastguard Worker 
2256*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
2257*ec779b8eSAndroid Build Coastguard Worker         mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_REGISTERED, pid);
2258*ec779b8eSAndroid Build Coastguard Worker     }
2259*ec779b8eSAndroid Build Coastguard Worker }
2260*ec779b8eSAndroid Build Coastguard Worker 
removeNotificationClient(pid_t pid)2261*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::removeNotificationClient(pid_t pid)
2262*ec779b8eSAndroid Build Coastguard Worker {
2263*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<IAfEffectModule>> removedEffects;
2264*ec779b8eSAndroid Build Coastguard Worker     {
2265*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
2266*ec779b8eSAndroid Build Coastguard Worker         {
2267*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _cl(clientMutex());
2268*ec779b8eSAndroid Build Coastguard Worker             mNotificationClients.erase(pid);
2269*ec779b8eSAndroid Build Coastguard Worker         }
2270*ec779b8eSAndroid Build Coastguard Worker 
2271*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%d died, releasing its sessions", pid);
2272*ec779b8eSAndroid Build Coastguard Worker         size_t num = mAudioSessionRefs.size();
2273*ec779b8eSAndroid Build Coastguard Worker         bool removed = false;
2274*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < num; ) {
2275*ec779b8eSAndroid Build Coastguard Worker             AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
2276*ec779b8eSAndroid Build Coastguard Worker             ALOGV(" pid %d @ %zu", ref->mPid, i);
2277*ec779b8eSAndroid Build Coastguard Worker             if (ref->mPid == pid) {
2278*ec779b8eSAndroid Build Coastguard Worker                 ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
2279*ec779b8eSAndroid Build Coastguard Worker                 mAudioSessionRefs.removeAt(i);
2280*ec779b8eSAndroid Build Coastguard Worker                 delete ref;
2281*ec779b8eSAndroid Build Coastguard Worker                 removed = true;
2282*ec779b8eSAndroid Build Coastguard Worker                 num--;
2283*ec779b8eSAndroid Build Coastguard Worker             } else {
2284*ec779b8eSAndroid Build Coastguard Worker                 i++;
2285*ec779b8eSAndroid Build Coastguard Worker             }
2286*ec779b8eSAndroid Build Coastguard Worker         }
2287*ec779b8eSAndroid Build Coastguard Worker         if (removed) {
2288*ec779b8eSAndroid Build Coastguard Worker             removedEffects = purgeStaleEffects_l();
2289*ec779b8eSAndroid Build Coastguard Worker             std::vector< sp<IAfEffectModule> > removedOrphanEffects = purgeOrphanEffectChains_l();
2290*ec779b8eSAndroid Build Coastguard Worker             removedEffects.insert(removedEffects.end(), removedOrphanEffects.begin(),
2291*ec779b8eSAndroid Build Coastguard Worker                     removedOrphanEffects.end());
2292*ec779b8eSAndroid Build Coastguard Worker         }
2293*ec779b8eSAndroid Build Coastguard Worker     }
2294*ec779b8eSAndroid Build Coastguard Worker     for (auto& effect : removedEffects) {
2295*ec779b8eSAndroid Build Coastguard Worker         effect->updatePolicyState();
2296*ec779b8eSAndroid Build Coastguard Worker     }
2297*ec779b8eSAndroid Build Coastguard Worker }
2298*ec779b8eSAndroid Build Coastguard Worker 
2299*ec779b8eSAndroid Build Coastguard Worker // Hold either AudioFlinger::mutex or ThreadBase::mutex
ioConfigChanged_l(audio_io_config_event_t event,const sp<AudioIoDescriptor> & ioDesc,pid_t pid)2300*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::ioConfigChanged_l(audio_io_config_event_t event,
2301*ec779b8eSAndroid Build Coastguard Worker                                    const sp<AudioIoDescriptor>& ioDesc,
2302*ec779b8eSAndroid Build Coastguard Worker                                    pid_t pid) {
2303*ec779b8eSAndroid Build Coastguard Worker     media::AudioIoConfigEvent eventAidl = VALUE_OR_FATAL(
2304*ec779b8eSAndroid Build Coastguard Worker             legacy2aidl_audio_io_config_event_t_AudioIoConfigEvent(event));
2305*ec779b8eSAndroid Build Coastguard Worker     media::AudioIoDescriptor descAidl = VALUE_OR_FATAL(
2306*ec779b8eSAndroid Build Coastguard Worker             legacy2aidl_AudioIoDescriptor_AudioIoDescriptor(ioDesc));
2307*ec779b8eSAndroid Build Coastguard Worker 
2308*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(clientMutex());
2309*ec779b8eSAndroid Build Coastguard Worker     if (pid != 0) {
2310*ec779b8eSAndroid Build Coastguard Worker         if (auto it = mNotificationClients.find(pid); it != mNotificationClients.end()) {
2311*ec779b8eSAndroid Build Coastguard Worker             it->second->audioFlingerClient()->ioConfigChanged(eventAidl, descAidl);
2312*ec779b8eSAndroid Build Coastguard Worker         }
2313*ec779b8eSAndroid Build Coastguard Worker     } else {
2314*ec779b8eSAndroid Build Coastguard Worker         for (const auto& [ client_pid, client] : mNotificationClients) {
2315*ec779b8eSAndroid Build Coastguard Worker             client->audioFlingerClient()->ioConfigChanged(eventAidl, descAidl);
2316*ec779b8eSAndroid Build Coastguard Worker         }
2317*ec779b8eSAndroid Build Coastguard Worker     }
2318*ec779b8eSAndroid Build Coastguard Worker }
2319*ec779b8eSAndroid Build Coastguard Worker 
onSupportedLatencyModesChanged(audio_io_handle_t output,const std::vector<audio_latency_mode_t> & modes)2320*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::onSupportedLatencyModesChanged(
2321*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) {
2322*ec779b8eSAndroid Build Coastguard Worker     int32_t outputAidl = VALUE_OR_FATAL(legacy2aidl_audio_io_handle_t_int32_t(output));
2323*ec779b8eSAndroid Build Coastguard Worker     std::vector<media::audio::common::AudioLatencyMode> modesAidl = VALUE_OR_FATAL(
2324*ec779b8eSAndroid Build Coastguard Worker                 convertContainer<std::vector<media::audio::common::AudioLatencyMode>>(
2325*ec779b8eSAndroid Build Coastguard Worker                         modes, legacy2aidl_audio_latency_mode_t_AudioLatencyMode));
2326*ec779b8eSAndroid Build Coastguard Worker 
2327*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(clientMutex());
2328*ec779b8eSAndroid Build Coastguard Worker     size_t size = mNotificationClients.size();
2329*ec779b8eSAndroid Build Coastguard Worker     for (const auto& [_, client] : mNotificationClients) {
2330*ec779b8eSAndroid Build Coastguard Worker         client->audioFlingerClient()->onSupportedLatencyModesChanged(outputAidl, modesAidl);
2331*ec779b8eSAndroid Build Coastguard Worker     }
2332*ec779b8eSAndroid Build Coastguard Worker }
2333*ec779b8eSAndroid Build Coastguard Worker 
onHardError(std::set<audio_port_handle_t> & trackPortIds)2334*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::onHardError(std::set<audio_port_handle_t>& trackPortIds) {
2335*ec779b8eSAndroid Build Coastguard Worker     ALOGI("releasing tracks due to a hard error occurred on an I/O thread");
2336*ec779b8eSAndroid Build Coastguard Worker     for (const auto portId : trackPortIds) {
2337*ec779b8eSAndroid Build Coastguard Worker         AudioSystem::releaseOutput(portId);
2338*ec779b8eSAndroid Build Coastguard Worker     }
2339*ec779b8eSAndroid Build Coastguard Worker }
2340*ec779b8eSAndroid Build Coastguard Worker 
getPermissionProvider()2341*ec779b8eSAndroid Build Coastguard Worker const IPermissionProvider& AudioFlinger::getPermissionProvider() {
2342*ec779b8eSAndroid Build Coastguard Worker     // This is inited as part of service construction, prior to binder registration,
2343*ec779b8eSAndroid Build Coastguard Worker     // so it should always be non-null.
2344*ec779b8eSAndroid Build Coastguard Worker     return mAudioPolicyServiceLocal.load()->getPermissionProvider();
2345*ec779b8eSAndroid Build Coastguard Worker }
2346*ec779b8eSAndroid Build Coastguard Worker 
2347*ec779b8eSAndroid Build Coastguard Worker // removeClient_l() must be called with AudioFlinger::clientMutex() held
removeClient_l(pid_t pid)2348*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::removeClient_l(pid_t pid)
2349*ec779b8eSAndroid Build Coastguard Worker {
2350*ec779b8eSAndroid Build Coastguard Worker     ALOGV("removeClient_l() pid %d, calling pid %d", pid,
2351*ec779b8eSAndroid Build Coastguard Worker             IPCThreadState::self()->getCallingPid());
2352*ec779b8eSAndroid Build Coastguard Worker     mClients.removeItem(pid);
2353*ec779b8eSAndroid Build Coastguard Worker }
2354*ec779b8eSAndroid Build Coastguard Worker 
2355*ec779b8eSAndroid Build Coastguard Worker // getEffectThread_l() must be called with AudioFlinger::mutex() held
getEffectThread_l(audio_session_t sessionId,int effectId)2356*ec779b8eSAndroid Build Coastguard Worker sp<IAfThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
2357*ec779b8eSAndroid Build Coastguard Worker         int effectId)
2358*ec779b8eSAndroid Build Coastguard Worker {
2359*ec779b8eSAndroid Build Coastguard Worker     sp<IAfThreadBase> thread;
2360*ec779b8eSAndroid Build Coastguard Worker 
2361*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
2362*ec779b8eSAndroid Build Coastguard Worker         thread = mPlaybackThreads.valueAt(i);
2363*ec779b8eSAndroid Build Coastguard Worker         if (thread->getEffect(sessionId, effectId) != 0) {
2364*ec779b8eSAndroid Build Coastguard Worker             return thread;
2365*ec779b8eSAndroid Build Coastguard Worker         }
2366*ec779b8eSAndroid Build Coastguard Worker     }
2367*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
2368*ec779b8eSAndroid Build Coastguard Worker         thread = mRecordThreads.valueAt(i);
2369*ec779b8eSAndroid Build Coastguard Worker         if (thread->getEffect(sessionId, effectId) != 0) {
2370*ec779b8eSAndroid Build Coastguard Worker             return thread;
2371*ec779b8eSAndroid Build Coastguard Worker         }
2372*ec779b8eSAndroid Build Coastguard Worker     }
2373*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mMmapThreads.size(); i++) {
2374*ec779b8eSAndroid Build Coastguard Worker         thread = mMmapThreads.valueAt(i);
2375*ec779b8eSAndroid Build Coastguard Worker         if (thread->getEffect(sessionId, effectId) != 0) {
2376*ec779b8eSAndroid Build Coastguard Worker             return thread;
2377*ec779b8eSAndroid Build Coastguard Worker         }
2378*ec779b8eSAndroid Build Coastguard Worker     }
2379*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
2380*ec779b8eSAndroid Build Coastguard Worker }
2381*ec779b8eSAndroid Build Coastguard Worker 
2382*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2383*ec779b8eSAndroid Build Coastguard Worker 
NotificationClient(const sp<AudioFlinger> & audioFlinger,const sp<media::IAudioFlingerClient> & client,pid_t pid,uid_t uid)2384*ec779b8eSAndroid Build Coastguard Worker AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
2385*ec779b8eSAndroid Build Coastguard Worker                                                      const sp<media::IAudioFlingerClient>& client,
2386*ec779b8eSAndroid Build Coastguard Worker                                                      pid_t pid,
2387*ec779b8eSAndroid Build Coastguard Worker                                                      uid_t uid)
2388*ec779b8eSAndroid Build Coastguard Worker     : mAudioFlinger(audioFlinger), mPid(pid), mUid(uid), mAudioFlingerClient(client)
2389*ec779b8eSAndroid Build Coastguard Worker     , mClientToken(media::psh_utils::AudioPowerManager::enabled()
2390*ec779b8eSAndroid Build Coastguard Worker             ? media::psh_utils::createAudioClientToken(pid, uid)
2391*ec779b8eSAndroid Build Coastguard Worker             : nullptr)
2392*ec779b8eSAndroid Build Coastguard Worker {
2393*ec779b8eSAndroid Build Coastguard Worker }
2394*ec779b8eSAndroid Build Coastguard Worker 
~NotificationClient()2395*ec779b8eSAndroid Build Coastguard Worker AudioFlinger::NotificationClient::~NotificationClient()
2396*ec779b8eSAndroid Build Coastguard Worker {
2397*ec779b8eSAndroid Build Coastguard Worker }
2398*ec779b8eSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> & who __unused)2399*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who __unused)
2400*ec779b8eSAndroid Build Coastguard Worker {
2401*ec779b8eSAndroid Build Coastguard Worker     const auto keep = sp<NotificationClient>::fromExisting(this);
2402*ec779b8eSAndroid Build Coastguard Worker     mAudioFlinger->removeNotificationClient(mPid);
2403*ec779b8eSAndroid Build Coastguard Worker }
2404*ec779b8eSAndroid Build Coastguard Worker 
2405*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
MediaLogNotifier()2406*ec779b8eSAndroid Build Coastguard Worker AudioFlinger::MediaLogNotifier::MediaLogNotifier()
2407*ec779b8eSAndroid Build Coastguard Worker     : mPendingRequests(false) {}
2408*ec779b8eSAndroid Build Coastguard Worker 
2409*ec779b8eSAndroid Build Coastguard Worker 
requestMerge()2410*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::MediaLogNotifier::requestMerge() {
2411*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mMutex);
2412*ec779b8eSAndroid Build Coastguard Worker     mPendingRequests = true;
2413*ec779b8eSAndroid Build Coastguard Worker     mCondition.notify_one();
2414*ec779b8eSAndroid Build Coastguard Worker }
2415*ec779b8eSAndroid Build Coastguard Worker 
threadLoop()2416*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::MediaLogNotifier::threadLoop() {
2417*ec779b8eSAndroid Build Coastguard Worker     // Should already have been checked, but just in case
2418*ec779b8eSAndroid Build Coastguard Worker     if (sMediaLogService == 0) {
2419*ec779b8eSAndroid Build Coastguard Worker         return false;
2420*ec779b8eSAndroid Build Coastguard Worker     }
2421*ec779b8eSAndroid Build Coastguard Worker     // Wait until there are pending requests
2422*ec779b8eSAndroid Build Coastguard Worker     {
2423*ec779b8eSAndroid Build Coastguard Worker         audio_utils::unique_lock _l(mMutex);
2424*ec779b8eSAndroid Build Coastguard Worker         mPendingRequests = false; // to ignore past requests
2425*ec779b8eSAndroid Build Coastguard Worker         while (!mPendingRequests) {
2426*ec779b8eSAndroid Build Coastguard Worker             mCondition.wait(_l);
2427*ec779b8eSAndroid Build Coastguard Worker             // TODO may also need an exitPending check
2428*ec779b8eSAndroid Build Coastguard Worker         }
2429*ec779b8eSAndroid Build Coastguard Worker         mPendingRequests = false;
2430*ec779b8eSAndroid Build Coastguard Worker     }
2431*ec779b8eSAndroid Build Coastguard Worker     // Execute the actual MediaLogService binder call and ignore extra requests for a while
2432*ec779b8eSAndroid Build Coastguard Worker     sMediaLogService->requestMergeWakeup();
2433*ec779b8eSAndroid Build Coastguard Worker     usleep(kPostTriggerSleepPeriod);
2434*ec779b8eSAndroid Build Coastguard Worker     return true;
2435*ec779b8eSAndroid Build Coastguard Worker }
2436*ec779b8eSAndroid Build Coastguard Worker 
requestLogMerge()2437*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::requestLogMerge() {
2438*ec779b8eSAndroid Build Coastguard Worker     mMediaLogNotifier->requestMerge();
2439*ec779b8eSAndroid Build Coastguard Worker }
2440*ec779b8eSAndroid Build Coastguard Worker 
2441*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2442*ec779b8eSAndroid Build Coastguard Worker 
createRecord(const media::CreateRecordRequest & _input,media::CreateRecordResponse & _output)2443*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
2444*ec779b8eSAndroid Build Coastguard Worker                                     media::CreateRecordResponse& _output)
2445*ec779b8eSAndroid Build Coastguard Worker {
2446*ec779b8eSAndroid Build Coastguard Worker     CreateRecordInput input = VALUE_OR_RETURN_STATUS(CreateRecordInput::fromAidl(_input));
2447*ec779b8eSAndroid Build Coastguard Worker     CreateRecordOutput output;
2448*ec779b8eSAndroid Build Coastguard Worker 
2449*ec779b8eSAndroid Build Coastguard Worker     sp<IAfRecordTrack> recordTrack;
2450*ec779b8eSAndroid Build Coastguard Worker     sp<Client> client;
2451*ec779b8eSAndroid Build Coastguard Worker     status_t lStatus;
2452*ec779b8eSAndroid Build Coastguard Worker     audio_session_t sessionId = input.sessionId;
2453*ec779b8eSAndroid Build Coastguard Worker     audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
2454*ec779b8eSAndroid Build Coastguard Worker 
2455*ec779b8eSAndroid Build Coastguard Worker     output.cblk.clear();
2456*ec779b8eSAndroid Build Coastguard Worker     output.buffers.clear();
2457*ec779b8eSAndroid Build Coastguard Worker     output.inputId = AUDIO_IO_HANDLE_NONE;
2458*ec779b8eSAndroid Build Coastguard Worker 
2459*ec779b8eSAndroid Build Coastguard Worker     AttributionSourceState adjAttributionSource;
2460*ec779b8eSAndroid Build Coastguard Worker     pid_t callingPid = IPCThreadState::self()->getCallingPid();
2461*ec779b8eSAndroid Build Coastguard Worker     if (!com::android::media::audio::audioserver_permissions()) {
2462*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = input.clientInfo.attributionSource;
2463*ec779b8eSAndroid Build Coastguard Worker         bool updatePid = (adjAttributionSource.pid == -1);
2464*ec779b8eSAndroid Build Coastguard Worker         const uid_t callingUid = IPCThreadState::self()->getCallingUid();
2465*ec779b8eSAndroid Build Coastguard Worker         const uid_t currentUid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(
2466*ec779b8eSAndroid Build Coastguard Worker                adjAttributionSource.uid));
2467*ec779b8eSAndroid Build Coastguard Worker         if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
2468*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(currentUid != callingUid,
2469*ec779b8eSAndroid Build Coastguard Worker                     "%s uid %d tried to pass itself off as %d",
2470*ec779b8eSAndroid Build Coastguard Worker                     __FUNCTION__, callingUid, currentUid);
2471*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
2472*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_uid_t_int32_t(callingUid));
2473*ec779b8eSAndroid Build Coastguard Worker             updatePid = true;
2474*ec779b8eSAndroid Build Coastguard Worker         }
2475*ec779b8eSAndroid Build Coastguard Worker         const pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
2476*ec779b8eSAndroid Build Coastguard Worker                 adjAttributionSource.pid));
2477*ec779b8eSAndroid Build Coastguard Worker         if (updatePid) {
2478*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(currentPid != (pid_t)-1 && currentPid != callingPid,
2479*ec779b8eSAndroid Build Coastguard Worker                      "%s uid %d pid %d tried to pass itself off as pid %d",
2480*ec779b8eSAndroid Build Coastguard Worker                      __func__, callingUid, callingPid, currentPid);
2481*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
2482*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_pid_t_int32_t(callingPid));
2483*ec779b8eSAndroid Build Coastguard Worker         }
2484*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = afutils::checkAttributionSourcePackage(
2485*ec779b8eSAndroid Build Coastguard Worker                 adjAttributionSource);
2486*ec779b8eSAndroid Build Coastguard Worker     } else {
2487*ec779b8eSAndroid Build Coastguard Worker         auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
2488*ec779b8eSAndroid Build Coastguard Worker                 validateAttributionFromContextOrTrustedCaller(
2489*ec779b8eSAndroid Build Coastguard Worker                     input.clientInfo.attributionSource,
2490*ec779b8eSAndroid Build Coastguard Worker                     getPermissionProvider()
2491*ec779b8eSAndroid Build Coastguard Worker                     ));
2492*ec779b8eSAndroid Build Coastguard Worker         // TODO pass wrapped object around
2493*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
2494*ec779b8eSAndroid Build Coastguard Worker     }
2495*ec779b8eSAndroid Build Coastguard Worker 
2496*ec779b8eSAndroid Build Coastguard Worker     // further format checks are performed by createRecordTrack_l()
2497*ec779b8eSAndroid Build Coastguard Worker     if (!audio_is_valid_format(input.config.format)) {
2498*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createRecord() invalid format %#x", input.config.format);
2499*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
2500*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
2501*ec779b8eSAndroid Build Coastguard Worker     }
2502*ec779b8eSAndroid Build Coastguard Worker 
2503*ec779b8eSAndroid Build Coastguard Worker     // further channel mask checks are performed by createRecordTrack_l()
2504*ec779b8eSAndroid Build Coastguard Worker     if (!audio_is_input_channel(input.config.channel_mask)) {
2505*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createRecord() invalid channel mask %#x", input.config.channel_mask);
2506*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
2507*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
2508*ec779b8eSAndroid Build Coastguard Worker     }
2509*ec779b8eSAndroid Build Coastguard Worker 
2510*ec779b8eSAndroid Build Coastguard Worker     if (sessionId == AUDIO_SESSION_ALLOCATE) {
2511*ec779b8eSAndroid Build Coastguard Worker         sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
2512*ec779b8eSAndroid Build Coastguard Worker     } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
2513*ec779b8eSAndroid Build Coastguard Worker         lStatus = BAD_VALUE;
2514*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
2515*ec779b8eSAndroid Build Coastguard Worker     }
2516*ec779b8eSAndroid Build Coastguard Worker 
2517*ec779b8eSAndroid Build Coastguard Worker     output.sessionId = sessionId;
2518*ec779b8eSAndroid Build Coastguard Worker     output.selectedDeviceId = input.selectedDeviceId;
2519*ec779b8eSAndroid Build Coastguard Worker     output.flags = input.flags;
2520*ec779b8eSAndroid Build Coastguard Worker 
2521*ec779b8eSAndroid Build Coastguard Worker     client = registerClient(adjAttributionSource.pid, adjAttributionSource.uid);
2522*ec779b8eSAndroid Build Coastguard Worker 
2523*ec779b8eSAndroid Build Coastguard Worker     // Not a conventional loop, but a retry loop for at most two iterations total.
2524*ec779b8eSAndroid Build Coastguard Worker     // Try first maybe with FAST flag then try again without FAST flag if that fails.
2525*ec779b8eSAndroid Build Coastguard Worker     // Exits loop via break on no error of got exit on error
2526*ec779b8eSAndroid Build Coastguard Worker     // The sp<> references will be dropped when re-entering scope.
2527*ec779b8eSAndroid Build Coastguard Worker     // The lack of indentation is deliberate, to reduce code churn and ease merges.
2528*ec779b8eSAndroid Build Coastguard Worker     for (;;) {
2529*ec779b8eSAndroid Build Coastguard Worker     // release previously opened input if retrying.
2530*ec779b8eSAndroid Build Coastguard Worker     if (output.inputId != AUDIO_IO_HANDLE_NONE) {
2531*ec779b8eSAndroid Build Coastguard Worker         recordTrack.clear();
2532*ec779b8eSAndroid Build Coastguard Worker         AudioSystem::releaseInput(portId);
2533*ec779b8eSAndroid Build Coastguard Worker         output.inputId = AUDIO_IO_HANDLE_NONE;
2534*ec779b8eSAndroid Build Coastguard Worker         output.selectedDeviceId = input.selectedDeviceId;
2535*ec779b8eSAndroid Build Coastguard Worker         portId = AUDIO_PORT_HANDLE_NONE;
2536*ec779b8eSAndroid Build Coastguard Worker     }
2537*ec779b8eSAndroid Build Coastguard Worker     lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
2538*ec779b8eSAndroid Build Coastguard Worker                                       input.riid,
2539*ec779b8eSAndroid Build Coastguard Worker                                       sessionId,
2540*ec779b8eSAndroid Build Coastguard Worker                                     // FIXME compare to AudioTrack
2541*ec779b8eSAndroid Build Coastguard Worker                                       adjAttributionSource,
2542*ec779b8eSAndroid Build Coastguard Worker                                       &input.config,
2543*ec779b8eSAndroid Build Coastguard Worker                                       output.flags, &output.selectedDeviceId, &portId);
2544*ec779b8eSAndroid Build Coastguard Worker     if (lStatus != NO_ERROR) {
2545*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createRecord() getInputForAttr return error %d", lStatus);
2546*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
2547*ec779b8eSAndroid Build Coastguard Worker     }
2548*ec779b8eSAndroid Build Coastguard Worker 
2549*ec779b8eSAndroid Build Coastguard Worker     {
2550*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
2551*ec779b8eSAndroid Build Coastguard Worker         IAfRecordThread* const thread = checkRecordThread_l(output.inputId);
2552*ec779b8eSAndroid Build Coastguard Worker         if (thread == NULL) {
2553*ec779b8eSAndroid Build Coastguard Worker             ALOGW("createRecord() checkRecordThread_l failed, input handle %d", output.inputId);
2554*ec779b8eSAndroid Build Coastguard Worker             lStatus = FAILED_TRANSACTION;
2555*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
2556*ec779b8eSAndroid Build Coastguard Worker         }
2557*ec779b8eSAndroid Build Coastguard Worker 
2558*ec779b8eSAndroid Build Coastguard Worker         ALOGV("createRecord() lSessionId: %d input %d", sessionId, output.inputId);
2559*ec779b8eSAndroid Build Coastguard Worker 
2560*ec779b8eSAndroid Build Coastguard Worker         output.sampleRate = input.config.sample_rate;
2561*ec779b8eSAndroid Build Coastguard Worker         output.frameCount = input.frameCount;
2562*ec779b8eSAndroid Build Coastguard Worker         output.notificationFrameCount = input.notificationFrameCount;
2563*ec779b8eSAndroid Build Coastguard Worker 
2564*ec779b8eSAndroid Build Coastguard Worker         recordTrack = thread->createRecordTrack_l(client, input.attr, &output.sampleRate,
2565*ec779b8eSAndroid Build Coastguard Worker                                                   input.config.format, input.config.channel_mask,
2566*ec779b8eSAndroid Build Coastguard Worker                                                   &output.frameCount, sessionId,
2567*ec779b8eSAndroid Build Coastguard Worker                                                   &output.notificationFrameCount,
2568*ec779b8eSAndroid Build Coastguard Worker                                                   callingPid, adjAttributionSource, &output.flags,
2569*ec779b8eSAndroid Build Coastguard Worker                                                   input.clientInfo.clientTid,
2570*ec779b8eSAndroid Build Coastguard Worker                                                   &lStatus, portId, input.maxSharedAudioHistoryMs);
2571*ec779b8eSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
2572*ec779b8eSAndroid Build Coastguard Worker 
2573*ec779b8eSAndroid Build Coastguard Worker         // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from
2574*ec779b8eSAndroid Build Coastguard Worker         // audio policy manager without FAST constraint
2575*ec779b8eSAndroid Build Coastguard Worker         if (lStatus == BAD_TYPE) {
2576*ec779b8eSAndroid Build Coastguard Worker             continue;
2577*ec779b8eSAndroid Build Coastguard Worker         }
2578*ec779b8eSAndroid Build Coastguard Worker 
2579*ec779b8eSAndroid Build Coastguard Worker         if (lStatus != NO_ERROR) {
2580*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
2581*ec779b8eSAndroid Build Coastguard Worker         }
2582*ec779b8eSAndroid Build Coastguard Worker 
2583*ec779b8eSAndroid Build Coastguard Worker         if (recordTrack->isFastTrack()) {
2584*ec779b8eSAndroid Build Coastguard Worker             output.serverConfig = {
2585*ec779b8eSAndroid Build Coastguard Worker                     thread->sampleRate(),
2586*ec779b8eSAndroid Build Coastguard Worker                     thread->channelMask(),
2587*ec779b8eSAndroid Build Coastguard Worker                     thread->format()
2588*ec779b8eSAndroid Build Coastguard Worker             };
2589*ec779b8eSAndroid Build Coastguard Worker         } else {
2590*ec779b8eSAndroid Build Coastguard Worker             output.serverConfig = {
2591*ec779b8eSAndroid Build Coastguard Worker                     recordTrack->sampleRate(),
2592*ec779b8eSAndroid Build Coastguard Worker                     recordTrack->channelMask(),
2593*ec779b8eSAndroid Build Coastguard Worker                     recordTrack->format()
2594*ec779b8eSAndroid Build Coastguard Worker             };
2595*ec779b8eSAndroid Build Coastguard Worker         }
2596*ec779b8eSAndroid Build Coastguard Worker 
2597*ec779b8eSAndroid Build Coastguard Worker         output.halConfig = {
2598*ec779b8eSAndroid Build Coastguard Worker                 thread->sampleRate(),
2599*ec779b8eSAndroid Build Coastguard Worker                 thread->channelMask(),
2600*ec779b8eSAndroid Build Coastguard Worker                 thread->format()
2601*ec779b8eSAndroid Build Coastguard Worker         };
2602*ec779b8eSAndroid Build Coastguard Worker 
2603*ec779b8eSAndroid Build Coastguard Worker         // Check if one effect chain was awaiting for an AudioRecord to be created on this
2604*ec779b8eSAndroid Build Coastguard Worker         // session and move it to this thread.
2605*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
2606*ec779b8eSAndroid Build Coastguard Worker         if (chain != 0) {
2607*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _l2(thread->mutex());
2608*ec779b8eSAndroid Build Coastguard Worker             thread->addEffectChain_l(chain);
2609*ec779b8eSAndroid Build Coastguard Worker         }
2610*ec779b8eSAndroid Build Coastguard Worker         break;
2611*ec779b8eSAndroid Build Coastguard Worker     }
2612*ec779b8eSAndroid Build Coastguard Worker     // End of retry loop.
2613*ec779b8eSAndroid Build Coastguard Worker     // The lack of indentation is deliberate, to reduce code churn and ease merges.
2614*ec779b8eSAndroid Build Coastguard Worker     }
2615*ec779b8eSAndroid Build Coastguard Worker 
2616*ec779b8eSAndroid Build Coastguard Worker     output.cblk = recordTrack->getCblk();
2617*ec779b8eSAndroid Build Coastguard Worker     output.buffers = recordTrack->getBuffers();
2618*ec779b8eSAndroid Build Coastguard Worker     output.portId = portId;
2619*ec779b8eSAndroid Build Coastguard Worker 
2620*ec779b8eSAndroid Build Coastguard Worker     output.audioRecord = IAfRecordTrack::createIAudioRecordAdapter(recordTrack);
2621*ec779b8eSAndroid Build Coastguard Worker     _output = VALUE_OR_FATAL(output.toAidl());
2622*ec779b8eSAndroid Build Coastguard Worker 
2623*ec779b8eSAndroid Build Coastguard Worker Exit:
2624*ec779b8eSAndroid Build Coastguard Worker     if (lStatus != NO_ERROR) {
2625*ec779b8eSAndroid Build Coastguard Worker         // remove local strong reference to Client before deleting the RecordTrack so that the
2626*ec779b8eSAndroid Build Coastguard Worker         // Client destructor is called by the TrackBase destructor with clientMutex() held
2627*ec779b8eSAndroid Build Coastguard Worker         // Don't hold clientMutex() when releasing the reference on the track as the
2628*ec779b8eSAndroid Build Coastguard Worker         // destructor will acquire it.
2629*ec779b8eSAndroid Build Coastguard Worker         {
2630*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _cl(clientMutex());
2631*ec779b8eSAndroid Build Coastguard Worker             client.clear();
2632*ec779b8eSAndroid Build Coastguard Worker         }
2633*ec779b8eSAndroid Build Coastguard Worker         recordTrack.clear();
2634*ec779b8eSAndroid Build Coastguard Worker         if (output.inputId != AUDIO_IO_HANDLE_NONE) {
2635*ec779b8eSAndroid Build Coastguard Worker             AudioSystem::releaseInput(portId);
2636*ec779b8eSAndroid Build Coastguard Worker         }
2637*ec779b8eSAndroid Build Coastguard Worker     }
2638*ec779b8eSAndroid Build Coastguard Worker 
2639*ec779b8eSAndroid Build Coastguard Worker     return lStatus;
2640*ec779b8eSAndroid Build Coastguard Worker }
2641*ec779b8eSAndroid Build Coastguard Worker 
2642*ec779b8eSAndroid Build Coastguard Worker 
2643*ec779b8eSAndroid Build Coastguard Worker 
2644*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2645*ec779b8eSAndroid Build Coastguard Worker 
getAudioPolicyConfig(media::AudioPolicyConfig * config)2646*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getAudioPolicyConfig(media::AudioPolicyConfig *config)
2647*ec779b8eSAndroid Build Coastguard Worker {
2648*ec779b8eSAndroid Build Coastguard Worker     if (config == nullptr) {
2649*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
2650*ec779b8eSAndroid Build Coastguard Worker     }
2651*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2652*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
2653*ec779b8eSAndroid Build Coastguard Worker     RETURN_STATUS_IF_ERROR(
2654*ec779b8eSAndroid Build Coastguard Worker             mDevicesFactoryHal->getSurroundSoundConfig(&config->surroundSoundConfig));
2655*ec779b8eSAndroid Build Coastguard Worker     RETURN_STATUS_IF_ERROR(mDevicesFactoryHal->getEngineConfig(&config->engineConfig));
2656*ec779b8eSAndroid Build Coastguard Worker     std::vector<std::string> hwModuleNames;
2657*ec779b8eSAndroid Build Coastguard Worker     RETURN_STATUS_IF_ERROR(mDevicesFactoryHal->getDeviceNames(&hwModuleNames));
2658*ec779b8eSAndroid Build Coastguard Worker     std::set<AudioMode> allSupportedModes;
2659*ec779b8eSAndroid Build Coastguard Worker     for (const auto& name : hwModuleNames) {
2660*ec779b8eSAndroid Build Coastguard Worker         AudioHwDevice* module = loadHwModule_ll(name.c_str());
2661*ec779b8eSAndroid Build Coastguard Worker         if (module == nullptr) continue;
2662*ec779b8eSAndroid Build Coastguard Worker         media::AudioHwModule aidlModule;
2663*ec779b8eSAndroid Build Coastguard Worker         if (module->hwDevice()->getAudioPorts(&aidlModule.ports) == OK &&
2664*ec779b8eSAndroid Build Coastguard Worker                 module->hwDevice()->getAudioRoutes(&aidlModule.routes) == OK) {
2665*ec779b8eSAndroid Build Coastguard Worker             aidlModule.handle = module->handle();
2666*ec779b8eSAndroid Build Coastguard Worker             aidlModule.name = module->moduleName();
2667*ec779b8eSAndroid Build Coastguard Worker             config->modules.push_back(std::move(aidlModule));
2668*ec779b8eSAndroid Build Coastguard Worker         }
2669*ec779b8eSAndroid Build Coastguard Worker         std::vector<AudioMode> supportedModes;
2670*ec779b8eSAndroid Build Coastguard Worker         if (module->hwDevice()->getSupportedModes(&supportedModes) == OK) {
2671*ec779b8eSAndroid Build Coastguard Worker             allSupportedModes.insert(supportedModes.begin(), supportedModes.end());
2672*ec779b8eSAndroid Build Coastguard Worker         }
2673*ec779b8eSAndroid Build Coastguard Worker     }
2674*ec779b8eSAndroid Build Coastguard Worker     if (!allSupportedModes.empty()) {
2675*ec779b8eSAndroid Build Coastguard Worker         config->supportedModes.insert(config->supportedModes.end(),
2676*ec779b8eSAndroid Build Coastguard Worker                 allSupportedModes.begin(), allSupportedModes.end());
2677*ec779b8eSAndroid Build Coastguard Worker     } else {
2678*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: The HAL does not provide telephony functionality", __func__);
2679*ec779b8eSAndroid Build Coastguard Worker         config->supportedModes = { media::audio::common::AudioMode::NORMAL,
2680*ec779b8eSAndroid Build Coastguard Worker             media::audio::common::AudioMode::RINGTONE,
2681*ec779b8eSAndroid Build Coastguard Worker             media::audio::common::AudioMode::IN_CALL,
2682*ec779b8eSAndroid Build Coastguard Worker             media::audio::common::AudioMode::IN_COMMUNICATION };
2683*ec779b8eSAndroid Build Coastguard Worker     }
2684*ec779b8eSAndroid Build Coastguard Worker     return OK;
2685*ec779b8eSAndroid Build Coastguard Worker }
2686*ec779b8eSAndroid Build Coastguard Worker 
loadHwModule(const char * name)2687*ec779b8eSAndroid Build Coastguard Worker audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
2688*ec779b8eSAndroid Build Coastguard Worker {
2689*ec779b8eSAndroid Build Coastguard Worker     if (name == NULL) {
2690*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_MODULE_HANDLE_NONE;
2691*ec779b8eSAndroid Build Coastguard Worker     }
2692*ec779b8eSAndroid Build Coastguard Worker     if (!settingsAllowed()) {
2693*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_MODULE_HANDLE_NONE;
2694*ec779b8eSAndroid Build Coastguard Worker     }
2695*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2696*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
2697*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice* module = loadHwModule_ll(name);
2698*ec779b8eSAndroid Build Coastguard Worker     return module != nullptr ? module->handle() : AUDIO_MODULE_HANDLE_NONE;
2699*ec779b8eSAndroid Build Coastguard Worker }
2700*ec779b8eSAndroid Build Coastguard Worker 
2701*ec779b8eSAndroid Build Coastguard Worker // loadHwModule_l() must be called with AudioFlinger::mutex()
2702*ec779b8eSAndroid Build Coastguard Worker // and AudioFlinger::hardwareMutex() held
loadHwModule_ll(const char * name)2703*ec779b8eSAndroid Build Coastguard Worker AudioHwDevice* AudioFlinger::loadHwModule_ll(const char *name)
2704*ec779b8eSAndroid Build Coastguard Worker {
2705*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
2706*ec779b8eSAndroid Build Coastguard Worker         if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
2707*ec779b8eSAndroid Build Coastguard Worker             ALOGW("loadHwModule() module %s already loaded", name);
2708*ec779b8eSAndroid Build Coastguard Worker             return mAudioHwDevs.valueAt(i);
2709*ec779b8eSAndroid Build Coastguard Worker         }
2710*ec779b8eSAndroid Build Coastguard Worker     }
2711*ec779b8eSAndroid Build Coastguard Worker 
2712*ec779b8eSAndroid Build Coastguard Worker     sp<DeviceHalInterface> dev;
2713*ec779b8eSAndroid Build Coastguard Worker 
2714*ec779b8eSAndroid Build Coastguard Worker     int rc = mDevicesFactoryHal->openDevice(name, &dev);
2715*ec779b8eSAndroid Build Coastguard Worker     if (rc) {
2716*ec779b8eSAndroid Build Coastguard Worker         ALOGE("loadHwModule() error %d loading module %s", rc, name);
2717*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
2718*ec779b8eSAndroid Build Coastguard Worker     }
2719*ec779b8eSAndroid Build Coastguard Worker     if (!mMelReporter->activateHalSoundDoseComputation(name, dev)) {
2720*ec779b8eSAndroid Build Coastguard Worker         ALOGW("loadHwModule() sound dose reporting is not available");
2721*ec779b8eSAndroid Build Coastguard Worker     }
2722*ec779b8eSAndroid Build Coastguard Worker 
2723*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_INIT;
2724*ec779b8eSAndroid Build Coastguard Worker     rc = dev->initCheck();
2725*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
2726*ec779b8eSAndroid Build Coastguard Worker     if (rc) {
2727*ec779b8eSAndroid Build Coastguard Worker         ALOGE("loadHwModule() init check error %d for module %s", rc, name);
2728*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
2729*ec779b8eSAndroid Build Coastguard Worker     }
2730*ec779b8eSAndroid Build Coastguard Worker 
2731*ec779b8eSAndroid Build Coastguard Worker     // Check and cache this HAL's level of support for master mute and master
2732*ec779b8eSAndroid Build Coastguard Worker     // volume.  If this is the first HAL opened, and it supports the get
2733*ec779b8eSAndroid Build Coastguard Worker     // methods, use the initial values provided by the HAL as the current
2734*ec779b8eSAndroid Build Coastguard Worker     // master mute and volume settings.
2735*ec779b8eSAndroid Build Coastguard Worker 
2736*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
2737*ec779b8eSAndroid Build Coastguard Worker     if (0 == mAudioHwDevs.size()) {
2738*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
2739*ec779b8eSAndroid Build Coastguard Worker         float mv;
2740*ec779b8eSAndroid Build Coastguard Worker         if (OK == dev->getMasterVolume(&mv)) {
2741*ec779b8eSAndroid Build Coastguard Worker             mMasterVolume = mv;
2742*ec779b8eSAndroid Build Coastguard Worker         }
2743*ec779b8eSAndroid Build Coastguard Worker 
2744*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
2745*ec779b8eSAndroid Build Coastguard Worker         bool mm;
2746*ec779b8eSAndroid Build Coastguard Worker         if (OK == dev->getMasterMute(&mm)) {
2747*ec779b8eSAndroid Build Coastguard Worker             mMasterMute = mm;
2748*ec779b8eSAndroid Build Coastguard Worker             ALOGI_IF(mMasterMute, "%s: applying mute from HAL %s", __func__, name);
2749*ec779b8eSAndroid Build Coastguard Worker         }
2750*ec779b8eSAndroid Build Coastguard Worker     }
2751*ec779b8eSAndroid Build Coastguard Worker 
2752*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
2753*ec779b8eSAndroid Build Coastguard Worker     if (OK == dev->setMasterVolume(mMasterVolume)) {
2754*ec779b8eSAndroid Build Coastguard Worker         flags = static_cast<AudioHwDevice::Flags>(flags |
2755*ec779b8eSAndroid Build Coastguard Worker                 AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
2756*ec779b8eSAndroid Build Coastguard Worker     }
2757*ec779b8eSAndroid Build Coastguard Worker 
2758*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
2759*ec779b8eSAndroid Build Coastguard Worker     if (OK == dev->setMasterMute(mMasterMute)) {
2760*ec779b8eSAndroid Build Coastguard Worker         flags = static_cast<AudioHwDevice::Flags>(flags |
2761*ec779b8eSAndroid Build Coastguard Worker                 AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
2762*ec779b8eSAndroid Build Coastguard Worker     }
2763*ec779b8eSAndroid Build Coastguard Worker 
2764*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
2765*ec779b8eSAndroid Build Coastguard Worker 
2766*ec779b8eSAndroid Build Coastguard Worker     if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
2767*ec779b8eSAndroid Build Coastguard Worker         // An MSD module is inserted before hardware modules in order to mix encoded streams.
2768*ec779b8eSAndroid Build Coastguard Worker         flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
2769*ec779b8eSAndroid Build Coastguard Worker     }
2770*ec779b8eSAndroid Build Coastguard Worker 
2771*ec779b8eSAndroid Build Coastguard Worker 
2772*ec779b8eSAndroid Build Coastguard Worker     if (bool supports = false;
2773*ec779b8eSAndroid Build Coastguard Worker             dev->supportsBluetoothVariableLatency(&supports) == NO_ERROR && supports) {
2774*ec779b8eSAndroid Build Coastguard Worker         flags = static_cast<AudioHwDevice::Flags>(flags |
2775*ec779b8eSAndroid Build Coastguard Worker                 AudioHwDevice::AHWD_SUPPORTS_BT_LATENCY_MODES);
2776*ec779b8eSAndroid Build Coastguard Worker     }
2777*ec779b8eSAndroid Build Coastguard Worker 
2778*ec779b8eSAndroid Build Coastguard Worker     audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
2779*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice *audioDevice = new AudioHwDevice(handle, name, dev, flags);
2780*ec779b8eSAndroid Build Coastguard Worker     if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
2781*ec779b8eSAndroid Build Coastguard Worker         mPrimaryHardwareDev = audioDevice;
2782*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_SET_MODE;
2783*ec779b8eSAndroid Build Coastguard Worker         mPrimaryHardwareDev.load()->hwDevice()->setMode(mMode);
2784*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_IDLE;
2785*ec779b8eSAndroid Build Coastguard Worker     }
2786*ec779b8eSAndroid Build Coastguard Worker 
2787*ec779b8eSAndroid Build Coastguard Worker     if (mDevicesFactoryHal->getHalVersion() > kMaxAAudioPropertyDeviceHalVersion) {
2788*ec779b8eSAndroid Build Coastguard Worker         if (int32_t mixerBursts = dev->getAAudioMixerBurstCount();
2789*ec779b8eSAndroid Build Coastguard Worker             mixerBursts > 0 && mixerBursts > mAAudioBurstsPerBuffer) {
2790*ec779b8eSAndroid Build Coastguard Worker             mAAudioBurstsPerBuffer = mixerBursts;
2791*ec779b8eSAndroid Build Coastguard Worker         }
2792*ec779b8eSAndroid Build Coastguard Worker         if (int32_t hwBurstMinMicros = dev->getAAudioHardwareBurstMinUsec();
2793*ec779b8eSAndroid Build Coastguard Worker             hwBurstMinMicros > 0
2794*ec779b8eSAndroid Build Coastguard Worker             && (hwBurstMinMicros < mAAudioHwBurstMinMicros || mAAudioHwBurstMinMicros == 0)) {
2795*ec779b8eSAndroid Build Coastguard Worker             mAAudioHwBurstMinMicros = hwBurstMinMicros;
2796*ec779b8eSAndroid Build Coastguard Worker         }
2797*ec779b8eSAndroid Build Coastguard Worker     }
2798*ec779b8eSAndroid Build Coastguard Worker 
2799*ec779b8eSAndroid Build Coastguard Worker     mAudioHwDevs.add(handle, audioDevice);
2800*ec779b8eSAndroid Build Coastguard Worker     if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_STUB) != 0) {
2801*ec779b8eSAndroid Build Coastguard Worker         mInputBufferSizeOrderedDevs.insert(audioDevice);
2802*ec779b8eSAndroid Build Coastguard Worker     }
2803*ec779b8eSAndroid Build Coastguard Worker 
2804*ec779b8eSAndroid Build Coastguard Worker     ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
2805*ec779b8eSAndroid Build Coastguard Worker 
2806*ec779b8eSAndroid Build Coastguard Worker     return audioDevice;
2807*ec779b8eSAndroid Build Coastguard Worker }
2808*ec779b8eSAndroid Build Coastguard Worker 
2809*ec779b8eSAndroid Build Coastguard Worker // Sort AudioHwDevice to be traversed in the getInputBufferSize call in the following order:
2810*ec779b8eSAndroid Build Coastguard Worker // Primary, Usb, Bluetooth, A2DP, other modules, remote submix.
2811*ec779b8eSAndroid Build Coastguard Worker /* static */
inputBufferSizeDevsCmp(const AudioHwDevice * lhs,const AudioHwDevice * rhs)2812*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::inputBufferSizeDevsCmp(const AudioHwDevice* lhs, const AudioHwDevice* rhs) {
2813*ec779b8eSAndroid Build Coastguard Worker     static const std::map<std::string_view, int> kPriorities = {
2814*ec779b8eSAndroid Build Coastguard Worker         { AUDIO_HARDWARE_MODULE_ID_PRIMARY, 0 }, { AUDIO_HARDWARE_MODULE_ID_USB, 1 },
2815*ec779b8eSAndroid Build Coastguard Worker         { AUDIO_HARDWARE_MODULE_ID_BLUETOOTH, 2 }, { AUDIO_HARDWARE_MODULE_ID_A2DP, 3 },
2816*ec779b8eSAndroid Build Coastguard Worker         { AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, std::numeric_limits<int>::max() }
2817*ec779b8eSAndroid Build Coastguard Worker     };
2818*ec779b8eSAndroid Build Coastguard Worker 
2819*ec779b8eSAndroid Build Coastguard Worker     const std::string_view lhsName = lhs->moduleName();
2820*ec779b8eSAndroid Build Coastguard Worker     const std::string_view rhsName = rhs->moduleName();
2821*ec779b8eSAndroid Build Coastguard Worker 
2822*ec779b8eSAndroid Build Coastguard Worker     auto lhsPriority = std::numeric_limits<int>::max() - 1;
2823*ec779b8eSAndroid Build Coastguard Worker     if (const auto lhsIt = kPriorities.find(lhsName); lhsIt != kPriorities.end()) {
2824*ec779b8eSAndroid Build Coastguard Worker         lhsPriority = lhsIt->second;
2825*ec779b8eSAndroid Build Coastguard Worker     }
2826*ec779b8eSAndroid Build Coastguard Worker     auto rhsPriority = std::numeric_limits<int>::max() - 1;
2827*ec779b8eSAndroid Build Coastguard Worker     if (const auto rhsIt = kPriorities.find(rhsName); rhsIt != kPriorities.end()) {
2828*ec779b8eSAndroid Build Coastguard Worker         rhsPriority = rhsIt->second;
2829*ec779b8eSAndroid Build Coastguard Worker     }
2830*ec779b8eSAndroid Build Coastguard Worker 
2831*ec779b8eSAndroid Build Coastguard Worker     if (lhsPriority != rhsPriority) {
2832*ec779b8eSAndroid Build Coastguard Worker         return lhsPriority < rhsPriority;
2833*ec779b8eSAndroid Build Coastguard Worker     }
2834*ec779b8eSAndroid Build Coastguard Worker     return lhsName < rhsName;
2835*ec779b8eSAndroid Build Coastguard Worker }
2836*ec779b8eSAndroid Build Coastguard Worker 
2837*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2838*ec779b8eSAndroid Build Coastguard Worker 
getPrimaryOutputSamplingRate() const2839*ec779b8eSAndroid Build Coastguard Worker uint32_t AudioFlinger::getPrimaryOutputSamplingRate() const
2840*ec779b8eSAndroid Build Coastguard Worker {
2841*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2842*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = fastPlaybackThread_l();
2843*ec779b8eSAndroid Build Coastguard Worker     return thread != NULL ? thread->sampleRate() : 0;
2844*ec779b8eSAndroid Build Coastguard Worker }
2845*ec779b8eSAndroid Build Coastguard Worker 
getPrimaryOutputFrameCount() const2846*ec779b8eSAndroid Build Coastguard Worker size_t AudioFlinger::getPrimaryOutputFrameCount() const
2847*ec779b8eSAndroid Build Coastguard Worker {
2848*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2849*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = fastPlaybackThread_l();
2850*ec779b8eSAndroid Build Coastguard Worker     return thread != NULL ? thread->frameCountHAL() : 0;
2851*ec779b8eSAndroid Build Coastguard Worker }
2852*ec779b8eSAndroid Build Coastguard Worker 
2853*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2854*ec779b8eSAndroid Build Coastguard Worker 
setLowRamDevice(bool isLowRamDevice,int64_t totalMemory)2855*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory)
2856*ec779b8eSAndroid Build Coastguard Worker {
2857*ec779b8eSAndroid Build Coastguard Worker     uid_t uid = IPCThreadState::self()->getCallingUid();
2858*ec779b8eSAndroid Build Coastguard Worker     if (!isAudioServerOrSystemServerUid(uid)) {
2859*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
2860*ec779b8eSAndroid Build Coastguard Worker     }
2861*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2862*ec779b8eSAndroid Build Coastguard Worker     if (mIsDeviceTypeKnown) {
2863*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
2864*ec779b8eSAndroid Build Coastguard Worker     }
2865*ec779b8eSAndroid Build Coastguard Worker     mIsLowRamDevice = isLowRamDevice;
2866*ec779b8eSAndroid Build Coastguard Worker     mTotalMemory = totalMemory;
2867*ec779b8eSAndroid Build Coastguard Worker     // mIsLowRamDevice and mTotalMemory are obtained through ActivityManager;
2868*ec779b8eSAndroid Build Coastguard Worker     // see ActivityManager.isLowRamDevice() and ActivityManager.getMemoryInfo().
2869*ec779b8eSAndroid Build Coastguard Worker     // mIsLowRamDevice generally represent devices with less than 1GB of memory,
2870*ec779b8eSAndroid Build Coastguard Worker     // though actual setting is determined through device configuration.
2871*ec779b8eSAndroid Build Coastguard Worker     constexpr int64_t GB = 1024 * 1024 * 1024;
2872*ec779b8eSAndroid Build Coastguard Worker     mClientSharedHeapSize =
2873*ec779b8eSAndroid Build Coastguard Worker             isLowRamDevice ? kMinimumClientSharedHeapSizeBytes
2874*ec779b8eSAndroid Build Coastguard Worker                     : mTotalMemory < 2 * GB ? 4 * kMinimumClientSharedHeapSizeBytes
2875*ec779b8eSAndroid Build Coastguard Worker                     : mTotalMemory < 3 * GB ? 8 * kMinimumClientSharedHeapSizeBytes
2876*ec779b8eSAndroid Build Coastguard Worker                     : mTotalMemory < 4 * GB ? 16 * kMinimumClientSharedHeapSizeBytes
2877*ec779b8eSAndroid Build Coastguard Worker                     : 32 * kMinimumClientSharedHeapSizeBytes;
2878*ec779b8eSAndroid Build Coastguard Worker     mIsDeviceTypeKnown = true;
2879*ec779b8eSAndroid Build Coastguard Worker 
2880*ec779b8eSAndroid Build Coastguard Worker     // TODO: Cache the client shared heap size in a persistent property.
2881*ec779b8eSAndroid Build Coastguard Worker     // It's possible that a native process or Java service or app accesses audioserver
2882*ec779b8eSAndroid Build Coastguard Worker     // after it is registered by system server, but before AudioService updates
2883*ec779b8eSAndroid Build Coastguard Worker     // the memory info.  This would occur immediately after boot or an audioserver
2884*ec779b8eSAndroid Build Coastguard Worker     // crash and restore. Before update from AudioService, the client would get the
2885*ec779b8eSAndroid Build Coastguard Worker     // minimum heap size.
2886*ec779b8eSAndroid Build Coastguard Worker 
2887*ec779b8eSAndroid Build Coastguard Worker     ALOGD("isLowRamDevice:%s totalMemory:%lld mClientSharedHeapSize:%zu",
2888*ec779b8eSAndroid Build Coastguard Worker             (isLowRamDevice ? "true" : "false"),
2889*ec779b8eSAndroid Build Coastguard Worker             (long long)mTotalMemory,
2890*ec779b8eSAndroid Build Coastguard Worker             mClientSharedHeapSize.load());
2891*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
2892*ec779b8eSAndroid Build Coastguard Worker }
2893*ec779b8eSAndroid Build Coastguard Worker 
getClientSharedHeapSize() const2894*ec779b8eSAndroid Build Coastguard Worker size_t AudioFlinger::getClientSharedHeapSize() const
2895*ec779b8eSAndroid Build Coastguard Worker {
2896*ec779b8eSAndroid Build Coastguard Worker     size_t heapSizeInBytes = property_get_int32("ro.af.client_heap_size_kbyte", 0) * 1024;
2897*ec779b8eSAndroid Build Coastguard Worker     if (heapSizeInBytes != 0) { // read-only property overrides all.
2898*ec779b8eSAndroid Build Coastguard Worker         return heapSizeInBytes;
2899*ec779b8eSAndroid Build Coastguard Worker     }
2900*ec779b8eSAndroid Build Coastguard Worker     return mClientSharedHeapSize;
2901*ec779b8eSAndroid Build Coastguard Worker }
2902*ec779b8eSAndroid Build Coastguard Worker 
setAudioPortConfig(const struct audio_port_config * config)2903*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config)
2904*ec779b8eSAndroid Build Coastguard Worker {
2905*ec779b8eSAndroid Build Coastguard Worker     ALOGV(__func__);
2906*ec779b8eSAndroid Build Coastguard Worker 
2907*ec779b8eSAndroid Build Coastguard Worker     status_t status = AudioValidator::validateAudioPortConfig(*config);
2908*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
2909*ec779b8eSAndroid Build Coastguard Worker         return status;
2910*ec779b8eSAndroid Build Coastguard Worker     }
2911*ec779b8eSAndroid Build Coastguard Worker 
2912*ec779b8eSAndroid Build Coastguard Worker     audio_module_handle_t module;
2913*ec779b8eSAndroid Build Coastguard Worker     if (config->type == AUDIO_PORT_TYPE_DEVICE) {
2914*ec779b8eSAndroid Build Coastguard Worker         module = config->ext.device.hw_module;
2915*ec779b8eSAndroid Build Coastguard Worker     } else {
2916*ec779b8eSAndroid Build Coastguard Worker         module = config->ext.mix.hw_module;
2917*ec779b8eSAndroid Build Coastguard Worker     }
2918*ec779b8eSAndroid Build Coastguard Worker 
2919*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2920*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
2921*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mAudioHwDevs.indexOfKey(module);
2922*ec779b8eSAndroid Build Coastguard Worker     if (index < 0) {
2923*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s() bad hw module %d", __func__, module);
2924*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
2925*ec779b8eSAndroid Build Coastguard Worker     }
2926*ec779b8eSAndroid Build Coastguard Worker 
2927*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(index);
2928*ec779b8eSAndroid Build Coastguard Worker     return audioHwDevice->hwDevice()->setAudioPortConfig(config);
2929*ec779b8eSAndroid Build Coastguard Worker }
2930*ec779b8eSAndroid Build Coastguard Worker 
getAudioHwSyncForSession(audio_session_t sessionId)2931*ec779b8eSAndroid Build Coastguard Worker audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
2932*ec779b8eSAndroid Build Coastguard Worker {
2933*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2934*ec779b8eSAndroid Build Coastguard Worker 
2935*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mHwAvSyncIds.indexOfKey(sessionId);
2936*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
2937*ec779b8eSAndroid Build Coastguard Worker         ALOGV("getAudioHwSyncForSession found ID %d for session %d",
2938*ec779b8eSAndroid Build Coastguard Worker               mHwAvSyncIds.valueAt(index), sessionId);
2939*ec779b8eSAndroid Build Coastguard Worker         return mHwAvSyncIds.valueAt(index);
2940*ec779b8eSAndroid Build Coastguard Worker     }
2941*ec779b8eSAndroid Build Coastguard Worker 
2942*ec779b8eSAndroid Build Coastguard Worker     sp<DeviceHalInterface> dev;
2943*ec779b8eSAndroid Build Coastguard Worker     {
2944*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard lock(hardwareMutex());
2945*ec779b8eSAndroid Build Coastguard Worker         if (mPrimaryHardwareDev == nullptr) {
2946*ec779b8eSAndroid Build Coastguard Worker             return AUDIO_HW_SYNC_INVALID;
2947*ec779b8eSAndroid Build Coastguard Worker         }
2948*ec779b8eSAndroid Build Coastguard Worker         dev = mPrimaryHardwareDev.load()->hwDevice();
2949*ec779b8eSAndroid Build Coastguard Worker     }
2950*ec779b8eSAndroid Build Coastguard Worker     if (dev == nullptr) {
2951*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_HW_SYNC_INVALID;
2952*ec779b8eSAndroid Build Coastguard Worker     }
2953*ec779b8eSAndroid Build Coastguard Worker 
2954*ec779b8eSAndroid Build Coastguard Worker     error::Result<audio_hw_sync_t> result = dev->getHwAvSync();
2955*ec779b8eSAndroid Build Coastguard Worker     if (!result.ok()) {
2956*ec779b8eSAndroid Build Coastguard Worker         ALOGW("getAudioHwSyncForSession error getting sync for session %d", sessionId);
2957*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_HW_SYNC_INVALID;
2958*ec779b8eSAndroid Build Coastguard Worker     }
2959*ec779b8eSAndroid Build Coastguard Worker     audio_hw_sync_t value = VALUE_OR_FATAL(result);
2960*ec779b8eSAndroid Build Coastguard Worker 
2961*ec779b8eSAndroid Build Coastguard Worker     // allow only one session for a given HW A/V sync ID.
2962*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mHwAvSyncIds.size(); i++) {
2963*ec779b8eSAndroid Build Coastguard Worker         if (mHwAvSyncIds.valueAt(i) == value) {
2964*ec779b8eSAndroid Build Coastguard Worker             ALOGV("getAudioHwSyncForSession removing ID %d for session %d",
2965*ec779b8eSAndroid Build Coastguard Worker                   value, mHwAvSyncIds.keyAt(i));
2966*ec779b8eSAndroid Build Coastguard Worker             mHwAvSyncIds.removeItemsAt(i);
2967*ec779b8eSAndroid Build Coastguard Worker             break;
2968*ec779b8eSAndroid Build Coastguard Worker         }
2969*ec779b8eSAndroid Build Coastguard Worker     }
2970*ec779b8eSAndroid Build Coastguard Worker 
2971*ec779b8eSAndroid Build Coastguard Worker     mHwAvSyncIds.add(sessionId, value);
2972*ec779b8eSAndroid Build Coastguard Worker 
2973*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
2974*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfPlaybackThread> thread = mPlaybackThreads.valueAt(i);
2975*ec779b8eSAndroid Build Coastguard Worker         uint32_t sessions = thread->hasAudioSession(sessionId);
2976*ec779b8eSAndroid Build Coastguard Worker         if (sessions & IAfThreadBase::TRACK_SESSION) {
2977*ec779b8eSAndroid Build Coastguard Worker             AudioParameter param = AudioParameter();
2978*ec779b8eSAndroid Build Coastguard Worker             param.addInt(String8(AudioParameter::keyStreamHwAvSync), value);
2979*ec779b8eSAndroid Build Coastguard Worker             String8 keyValuePairs = param.toString();
2980*ec779b8eSAndroid Build Coastguard Worker             thread->setParameters(keyValuePairs);
2981*ec779b8eSAndroid Build Coastguard Worker             forwardParametersToDownstreamPatches_l(thread->id(), keyValuePairs,
2982*ec779b8eSAndroid Build Coastguard Worker                     [](const sp<IAfPlaybackThread>& thread) { return thread->usesHwAvSync(); });
2983*ec779b8eSAndroid Build Coastguard Worker             break;
2984*ec779b8eSAndroid Build Coastguard Worker         }
2985*ec779b8eSAndroid Build Coastguard Worker     }
2986*ec779b8eSAndroid Build Coastguard Worker 
2987*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getAudioHwSyncForSession adding ID %d for session %d", value, sessionId);
2988*ec779b8eSAndroid Build Coastguard Worker     return (audio_hw_sync_t)value;
2989*ec779b8eSAndroid Build Coastguard Worker }
2990*ec779b8eSAndroid Build Coastguard Worker 
systemReady()2991*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::systemReady()
2992*ec779b8eSAndroid Build Coastguard Worker {
2993*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
2994*ec779b8eSAndroid Build Coastguard Worker     ALOGI("%s", __FUNCTION__);
2995*ec779b8eSAndroid Build Coastguard Worker     if (mSystemReady) {
2996*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s called twice", __FUNCTION__);
2997*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
2998*ec779b8eSAndroid Build Coastguard Worker     }
2999*ec779b8eSAndroid Build Coastguard Worker     mSystemReady = true;
3000*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3001*ec779b8eSAndroid Build Coastguard Worker         IAfThreadBase* const thread = mPlaybackThreads.valueAt(i).get();
3002*ec779b8eSAndroid Build Coastguard Worker         thread->systemReady();
3003*ec779b8eSAndroid Build Coastguard Worker     }
3004*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
3005*ec779b8eSAndroid Build Coastguard Worker         IAfThreadBase* const thread = mRecordThreads.valueAt(i).get();
3006*ec779b8eSAndroid Build Coastguard Worker         thread->systemReady();
3007*ec779b8eSAndroid Build Coastguard Worker     }
3008*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mMmapThreads.size(); i++) {
3009*ec779b8eSAndroid Build Coastguard Worker         IAfThreadBase* const thread = mMmapThreads.valueAt(i).get();
3010*ec779b8eSAndroid Build Coastguard Worker         thread->systemReady();
3011*ec779b8eSAndroid Build Coastguard Worker     }
3012*ec779b8eSAndroid Build Coastguard Worker 
3013*ec779b8eSAndroid Build Coastguard Worker     // Java services are ready, so we can create a reference to AudioService
3014*ec779b8eSAndroid Build Coastguard Worker     getOrCreateAudioManager();
3015*ec779b8eSAndroid Build Coastguard Worker 
3016*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
3017*ec779b8eSAndroid Build Coastguard Worker }
3018*ec779b8eSAndroid Build Coastguard Worker 
getOrCreateAudioManager()3019*ec779b8eSAndroid Build Coastguard Worker sp<IAudioManager> AudioFlinger::getOrCreateAudioManager()
3020*ec779b8eSAndroid Build Coastguard Worker {
3021*ec779b8eSAndroid Build Coastguard Worker     if (mAudioManager.load() == nullptr) {
3022*ec779b8eSAndroid Build Coastguard Worker         // use checkService() to avoid blocking
3023*ec779b8eSAndroid Build Coastguard Worker         sp<IBinder> binder =
3024*ec779b8eSAndroid Build Coastguard Worker             defaultServiceManager()->checkService(String16(kAudioServiceName));
3025*ec779b8eSAndroid Build Coastguard Worker         if (binder != nullptr) {
3026*ec779b8eSAndroid Build Coastguard Worker             mAudioManager = interface_cast<IAudioManager>(binder);
3027*ec779b8eSAndroid Build Coastguard Worker         } else {
3028*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s(): binding to audio service failed.", __func__);
3029*ec779b8eSAndroid Build Coastguard Worker         }
3030*ec779b8eSAndroid Build Coastguard Worker     }
3031*ec779b8eSAndroid Build Coastguard Worker     return mAudioManager.load();
3032*ec779b8eSAndroid Build Coastguard Worker }
3033*ec779b8eSAndroid Build Coastguard Worker 
getMicrophones(std::vector<media::MicrophoneInfoFw> * microphones) const3034*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const
3035*ec779b8eSAndroid Build Coastguard Worker {
3036*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard lock(hardwareMutex());
3037*ec779b8eSAndroid Build Coastguard Worker     status_t status = INVALID_OPERATION;
3038*ec779b8eSAndroid Build Coastguard Worker 
3039*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
3040*ec779b8eSAndroid Build Coastguard Worker         std::vector<audio_microphone_characteristic_t> mics;
3041*ec779b8eSAndroid Build Coastguard Worker         AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
3042*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_GET_MICROPHONES;
3043*ec779b8eSAndroid Build Coastguard Worker         status_t devStatus = dev->hwDevice()->getMicrophones(&mics);
3044*ec779b8eSAndroid Build Coastguard Worker         mHardwareStatus = AUDIO_HW_IDLE;
3045*ec779b8eSAndroid Build Coastguard Worker         if (devStatus == NO_ERROR) {
3046*ec779b8eSAndroid Build Coastguard Worker             // report success if at least one HW module supports the function.
3047*ec779b8eSAndroid Build Coastguard Worker             std::transform(mics.begin(), mics.end(), std::back_inserter(*microphones), [](auto& mic)
3048*ec779b8eSAndroid Build Coastguard Worker             {
3049*ec779b8eSAndroid Build Coastguard Worker                 auto microphone =
3050*ec779b8eSAndroid Build Coastguard Worker                         legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
3051*ec779b8eSAndroid Build Coastguard Worker                 return microphone.ok() ? microphone.value() : media::MicrophoneInfoFw{};
3052*ec779b8eSAndroid Build Coastguard Worker             });
3053*ec779b8eSAndroid Build Coastguard Worker             status = NO_ERROR;
3054*ec779b8eSAndroid Build Coastguard Worker         }
3055*ec779b8eSAndroid Build Coastguard Worker     }
3056*ec779b8eSAndroid Build Coastguard Worker 
3057*ec779b8eSAndroid Build Coastguard Worker     return status;
3058*ec779b8eSAndroid Build Coastguard Worker }
3059*ec779b8eSAndroid Build Coastguard Worker 
3060*ec779b8eSAndroid Build Coastguard Worker // setAudioHwSyncForSession_l() must be called with AudioFlinger::mutex() held
setAudioHwSyncForSession_l(IAfPlaybackThread * const thread,audio_session_t sessionId)3061*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::setAudioHwSyncForSession_l(
3062*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const thread, audio_session_t sessionId)
3063*ec779b8eSAndroid Build Coastguard Worker {
3064*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mHwAvSyncIds.indexOfKey(sessionId);
3065*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
3066*ec779b8eSAndroid Build Coastguard Worker         audio_hw_sync_t syncId = mHwAvSyncIds.valueAt(index);
3067*ec779b8eSAndroid Build Coastguard Worker         ALOGV("setAudioHwSyncForSession_l found ID %d for session %d", syncId, sessionId);
3068*ec779b8eSAndroid Build Coastguard Worker         AudioParameter param = AudioParameter();
3069*ec779b8eSAndroid Build Coastguard Worker         param.addInt(String8(AudioParameter::keyStreamHwAvSync), syncId);
3070*ec779b8eSAndroid Build Coastguard Worker         String8 keyValuePairs = param.toString();
3071*ec779b8eSAndroid Build Coastguard Worker         thread->setParameters(keyValuePairs);
3072*ec779b8eSAndroid Build Coastguard Worker         forwardParametersToDownstreamPatches_l(thread->id(), keyValuePairs,
3073*ec779b8eSAndroid Build Coastguard Worker                 [](const sp<IAfPlaybackThread>& thread) { return thread->usesHwAvSync(); });
3074*ec779b8eSAndroid Build Coastguard Worker     }
3075*ec779b8eSAndroid Build Coastguard Worker }
3076*ec779b8eSAndroid Build Coastguard Worker 
3077*ec779b8eSAndroid Build Coastguard Worker 
3078*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
3079*ec779b8eSAndroid Build Coastguard Worker 
3080*ec779b8eSAndroid Build Coastguard Worker 
openOutput_l(audio_module_handle_t module,audio_io_handle_t * output,audio_config_t * halConfig,audio_config_base_t * mixerConfig,audio_devices_t deviceType,const String8 & address,audio_output_flags_t * flags,const audio_attributes_t attributes)3081*ec779b8eSAndroid Build Coastguard Worker sp<IAfThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
3082*ec779b8eSAndroid Build Coastguard Worker                                                         audio_io_handle_t *output,
3083*ec779b8eSAndroid Build Coastguard Worker                                                         audio_config_t *halConfig,
3084*ec779b8eSAndroid Build Coastguard Worker                                                         audio_config_base_t *mixerConfig,
3085*ec779b8eSAndroid Build Coastguard Worker                                                         audio_devices_t deviceType,
3086*ec779b8eSAndroid Build Coastguard Worker                                                         const String8& address,
3087*ec779b8eSAndroid Build Coastguard Worker                                                         audio_output_flags_t *flags,
3088*ec779b8eSAndroid Build Coastguard Worker                                                         const audio_attributes_t attributes)
3089*ec779b8eSAndroid Build Coastguard Worker {
3090*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType);
3091*ec779b8eSAndroid Build Coastguard Worker     if (outHwDev == NULL) {
3092*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
3093*ec779b8eSAndroid Build Coastguard Worker     }
3094*ec779b8eSAndroid Build Coastguard Worker 
3095*ec779b8eSAndroid Build Coastguard Worker     if (*output == AUDIO_IO_HANDLE_NONE) {
3096*ec779b8eSAndroid Build Coastguard Worker         *output = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
3097*ec779b8eSAndroid Build Coastguard Worker     } else {
3098*ec779b8eSAndroid Build Coastguard Worker         // Audio Policy does not currently request a specific output handle.
3099*ec779b8eSAndroid Build Coastguard Worker         // If this is ever needed, see openInput_l() for example code.
3100*ec779b8eSAndroid Build Coastguard Worker         ALOGE("openOutput_l requested output handle %d is not AUDIO_IO_HANDLE_NONE", *output);
3101*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
3102*ec779b8eSAndroid Build Coastguard Worker     }
3103*ec779b8eSAndroid Build Coastguard Worker 
3104*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
3105*ec779b8eSAndroid Build Coastguard Worker     AudioStreamOut *outputStream = NULL;
3106*ec779b8eSAndroid Build Coastguard Worker 
3107*ec779b8eSAndroid Build Coastguard Worker     playback_track_metadata_v7_t trackMetadata;
3108*ec779b8eSAndroid Build Coastguard Worker     trackMetadata.base.usage = attributes.usage;
3109*ec779b8eSAndroid Build Coastguard Worker 
3110*ec779b8eSAndroid Build Coastguard Worker     status_t status = outHwDev->openOutputStream(
3111*ec779b8eSAndroid Build Coastguard Worker             &outputStream,
3112*ec779b8eSAndroid Build Coastguard Worker             *output,
3113*ec779b8eSAndroid Build Coastguard Worker             deviceType,
3114*ec779b8eSAndroid Build Coastguard Worker             flags,
3115*ec779b8eSAndroid Build Coastguard Worker             halConfig,
3116*ec779b8eSAndroid Build Coastguard Worker             address.c_str(),
3117*ec779b8eSAndroid Build Coastguard Worker             {trackMetadata});
3118*ec779b8eSAndroid Build Coastguard Worker 
3119*ec779b8eSAndroid Build Coastguard Worker     mHardwareStatus = AUDIO_HW_IDLE;
3120*ec779b8eSAndroid Build Coastguard Worker 
3121*ec779b8eSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
3122*ec779b8eSAndroid Build Coastguard Worker         if (*flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
3123*ec779b8eSAndroid Build Coastguard Worker             const sp<IAfMmapPlaybackThread> thread = IAfMmapPlaybackThread::create(
3124*ec779b8eSAndroid Build Coastguard Worker                     this, *output, outHwDev, outputStream, mSystemReady);
3125*ec779b8eSAndroid Build Coastguard Worker             mMmapThreads.add(*output, thread);
3126*ec779b8eSAndroid Build Coastguard Worker             ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
3127*ec779b8eSAndroid Build Coastguard Worker                   *output, thread.get());
3128*ec779b8eSAndroid Build Coastguard Worker             return thread;
3129*ec779b8eSAndroid Build Coastguard Worker         } else {
3130*ec779b8eSAndroid Build Coastguard Worker             sp<IAfPlaybackThread> thread;
3131*ec779b8eSAndroid Build Coastguard Worker             if (*flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
3132*ec779b8eSAndroid Build Coastguard Worker                 thread = IAfPlaybackThread::createBitPerfectThread(
3133*ec779b8eSAndroid Build Coastguard Worker                         this, outputStream, *output, mSystemReady);
3134*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("%s() created bit-perfect output: ID %d thread %p",
3135*ec779b8eSAndroid Build Coastguard Worker                       __func__, *output, thread.get());
3136*ec779b8eSAndroid Build Coastguard Worker             } else if (*flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
3137*ec779b8eSAndroid Build Coastguard Worker                 thread = IAfPlaybackThread::createSpatializerThread(this, outputStream, *output,
3138*ec779b8eSAndroid Build Coastguard Worker                                                     mSystemReady, mixerConfig);
3139*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("openOutput_l() created spatializer output: ID %d thread %p",
3140*ec779b8eSAndroid Build Coastguard Worker                       *output, thread.get());
3141*ec779b8eSAndroid Build Coastguard Worker             } else if (*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3142*ec779b8eSAndroid Build Coastguard Worker                 thread = IAfPlaybackThread::createOffloadThread(this, outputStream, *output,
3143*ec779b8eSAndroid Build Coastguard Worker                         mSystemReady, halConfig->offload_info);
3144*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("openOutput_l() created offload output: ID %d thread %p",
3145*ec779b8eSAndroid Build Coastguard Worker                       *output, thread.get());
3146*ec779b8eSAndroid Build Coastguard Worker             } else if ((*flags & AUDIO_OUTPUT_FLAG_DIRECT)
3147*ec779b8eSAndroid Build Coastguard Worker                     || !IAfThreadBase::isValidPcmSinkFormat(halConfig->format)
3148*ec779b8eSAndroid Build Coastguard Worker                     || !IAfThreadBase::isValidPcmSinkChannelMask(halConfig->channel_mask)) {
3149*ec779b8eSAndroid Build Coastguard Worker                 thread = IAfPlaybackThread::createDirectOutputThread(this, outputStream, *output,
3150*ec779b8eSAndroid Build Coastguard Worker                         mSystemReady, halConfig->offload_info);
3151*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("openOutput_l() created direct output: ID %d thread %p",
3152*ec779b8eSAndroid Build Coastguard Worker                       *output, thread.get());
3153*ec779b8eSAndroid Build Coastguard Worker             } else {
3154*ec779b8eSAndroid Build Coastguard Worker                 thread = IAfPlaybackThread::createMixerThread(
3155*ec779b8eSAndroid Build Coastguard Worker                         this, outputStream, *output, mSystemReady);
3156*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("openOutput_l() created mixer output: ID %d thread %p",
3157*ec779b8eSAndroid Build Coastguard Worker                       *output, thread.get());
3158*ec779b8eSAndroid Build Coastguard Worker             }
3159*ec779b8eSAndroid Build Coastguard Worker             mPlaybackThreads.add(*output, thread);
3160*ec779b8eSAndroid Build Coastguard Worker             struct audio_patch patch;
3161*ec779b8eSAndroid Build Coastguard Worker             mPatchPanel->notifyStreamOpened(outHwDev, *output, &patch);
3162*ec779b8eSAndroid Build Coastguard Worker             if (thread->isMsdDevice()) {
3163*ec779b8eSAndroid Build Coastguard Worker                 thread->setDownStreamPatch(&patch);
3164*ec779b8eSAndroid Build Coastguard Worker             }
3165*ec779b8eSAndroid Build Coastguard Worker             thread->setBluetoothVariableLatencyEnabled(mBluetoothLatencyModesEnabled.load());
3166*ec779b8eSAndroid Build Coastguard Worker             return thread;
3167*ec779b8eSAndroid Build Coastguard Worker         }
3168*ec779b8eSAndroid Build Coastguard Worker     }
3169*ec779b8eSAndroid Build Coastguard Worker 
3170*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
3171*ec779b8eSAndroid Build Coastguard Worker }
3172*ec779b8eSAndroid Build Coastguard Worker 
openOutput(const media::OpenOutputRequest & request,media::OpenOutputResponse * response)3173*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::openOutput(const media::OpenOutputRequest& request,
3174*ec779b8eSAndroid Build Coastguard Worker                                 media::OpenOutputResponse* response)
3175*ec779b8eSAndroid Build Coastguard Worker {
3176*ec779b8eSAndroid Build Coastguard Worker     audio_module_handle_t module = VALUE_OR_RETURN_STATUS(
3177*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_int32_t_audio_module_handle_t(request.module));
3178*ec779b8eSAndroid Build Coastguard Worker     audio_config_t halConfig = VALUE_OR_RETURN_STATUS(
3179*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_AudioConfig_audio_config_t(request.halConfig, false /*isInput*/));
3180*ec779b8eSAndroid Build Coastguard Worker     audio_config_base_t mixerConfig = VALUE_OR_RETURN_STATUS(
3181*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_AudioConfigBase_audio_config_base_t(request.mixerConfig, false/*isInput*/));
3182*ec779b8eSAndroid Build Coastguard Worker     sp<DeviceDescriptorBase> device = VALUE_OR_RETURN_STATUS(
3183*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_DeviceDescriptorBase(request.device));
3184*ec779b8eSAndroid Build Coastguard Worker     audio_output_flags_t flags = VALUE_OR_RETURN_STATUS(
3185*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_int32_t_audio_output_flags_t_mask(request.flags));
3186*ec779b8eSAndroid Build Coastguard Worker     audio_attributes_t attributes = VALUE_OR_RETURN_STATUS(
3187*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_AudioAttributes_audio_attributes_t(request.attributes));
3188*ec779b8eSAndroid Build Coastguard Worker 
3189*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t output;
3190*ec779b8eSAndroid Build Coastguard Worker 
3191*ec779b8eSAndroid Build Coastguard Worker     ALOGI("openOutput() this %p, module %d Device %s, SamplingRate %d, Format %#08x, "
3192*ec779b8eSAndroid Build Coastguard Worker               "Channels %#x, flags %#x",
3193*ec779b8eSAndroid Build Coastguard Worker               this, module,
3194*ec779b8eSAndroid Build Coastguard Worker               device->toString().c_str(),
3195*ec779b8eSAndroid Build Coastguard Worker               halConfig.sample_rate,
3196*ec779b8eSAndroid Build Coastguard Worker               halConfig.format,
3197*ec779b8eSAndroid Build Coastguard Worker               halConfig.channel_mask,
3198*ec779b8eSAndroid Build Coastguard Worker               flags);
3199*ec779b8eSAndroid Build Coastguard Worker 
3200*ec779b8eSAndroid Build Coastguard Worker     audio_devices_t deviceType = device->type();
3201*ec779b8eSAndroid Build Coastguard Worker     const String8 address = String8(device->address().c_str());
3202*ec779b8eSAndroid Build Coastguard Worker 
3203*ec779b8eSAndroid Build Coastguard Worker     if (deviceType == AUDIO_DEVICE_NONE) {
3204*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
3205*ec779b8eSAndroid Build Coastguard Worker     }
3206*ec779b8eSAndroid Build Coastguard Worker 
3207*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3208*ec779b8eSAndroid Build Coastguard Worker 
3209*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
3210*ec779b8eSAndroid Build Coastguard Worker             &mixerConfig, deviceType, address, &flags, attributes);
3211*ec779b8eSAndroid Build Coastguard Worker     if (thread != 0) {
3212*ec779b8eSAndroid Build Coastguard Worker         uint32_t latencyMs = 0;
3213*ec779b8eSAndroid Build Coastguard Worker         if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
3214*ec779b8eSAndroid Build Coastguard Worker             const auto playbackThread = thread->asIAfPlaybackThread();
3215*ec779b8eSAndroid Build Coastguard Worker             latencyMs = playbackThread->latency();
3216*ec779b8eSAndroid Build Coastguard Worker 
3217*ec779b8eSAndroid Build Coastguard Worker             // notify client processes of the new output creation
3218*ec779b8eSAndroid Build Coastguard Worker             playbackThread->ioConfigChanged_l(AUDIO_OUTPUT_OPENED);
3219*ec779b8eSAndroid Build Coastguard Worker 
3220*ec779b8eSAndroid Build Coastguard Worker             // the first primary output opened designates the primary hw device if no HW module
3221*ec779b8eSAndroid Build Coastguard Worker             // named "primary" was already loaded.
3222*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard lock(hardwareMutex());
3223*ec779b8eSAndroid Build Coastguard Worker             if ((mPrimaryHardwareDev == nullptr) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
3224*ec779b8eSAndroid Build Coastguard Worker                 ALOGI("Using module %d as the primary audio interface", module);
3225*ec779b8eSAndroid Build Coastguard Worker                 mPrimaryHardwareDev = playbackThread->getOutput()->audioHwDev;
3226*ec779b8eSAndroid Build Coastguard Worker 
3227*ec779b8eSAndroid Build Coastguard Worker                 mHardwareStatus = AUDIO_HW_SET_MODE;
3228*ec779b8eSAndroid Build Coastguard Worker                 mPrimaryHardwareDev.load()->hwDevice()->setMode(mMode);
3229*ec779b8eSAndroid Build Coastguard Worker                 mHardwareStatus = AUDIO_HW_IDLE;
3230*ec779b8eSAndroid Build Coastguard Worker             }
3231*ec779b8eSAndroid Build Coastguard Worker         } else {
3232*ec779b8eSAndroid Build Coastguard Worker             thread->ioConfigChanged_l(AUDIO_OUTPUT_OPENED);
3233*ec779b8eSAndroid Build Coastguard Worker         }
3234*ec779b8eSAndroid Build Coastguard Worker         response->output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
3235*ec779b8eSAndroid Build Coastguard Worker         response->config = VALUE_OR_RETURN_STATUS(
3236*ec779b8eSAndroid Build Coastguard Worker                 legacy2aidl_audio_config_t_AudioConfig(halConfig, false /*isInput*/));
3237*ec779b8eSAndroid Build Coastguard Worker         response->latencyMs = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(latencyMs));
3238*ec779b8eSAndroid Build Coastguard Worker         response->flags = VALUE_OR_RETURN_STATUS(
3239*ec779b8eSAndroid Build Coastguard Worker                 legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
3240*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
3241*ec779b8eSAndroid Build Coastguard Worker     }
3242*ec779b8eSAndroid Build Coastguard Worker 
3243*ec779b8eSAndroid Build Coastguard Worker     return NO_INIT;
3244*ec779b8eSAndroid Build Coastguard Worker }
3245*ec779b8eSAndroid Build Coastguard Worker 
openDuplicateOutput(audio_io_handle_t output1,audio_io_handle_t output2)3246*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
3247*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t output2)
3248*ec779b8eSAndroid Build Coastguard Worker {
3249*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3250*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread1 = checkMixerThread_l(output1);
3251*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread2 = checkMixerThread_l(output2);
3252*ec779b8eSAndroid Build Coastguard Worker 
3253*ec779b8eSAndroid Build Coastguard Worker     if (thread1 == NULL || thread2 == NULL) {
3254*ec779b8eSAndroid Build Coastguard Worker         ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
3255*ec779b8eSAndroid Build Coastguard Worker                 output2);
3256*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_IO_HANDLE_NONE;
3257*ec779b8eSAndroid Build Coastguard Worker     }
3258*ec779b8eSAndroid Build Coastguard Worker 
3259*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t id = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
3260*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfDuplicatingThread> thread = IAfDuplicatingThread::create(
3261*ec779b8eSAndroid Build Coastguard Worker             this, thread1, id, mSystemReady);
3262*ec779b8eSAndroid Build Coastguard Worker     thread->addOutputTrack(thread2);
3263*ec779b8eSAndroid Build Coastguard Worker     mPlaybackThreads.add(id, thread);
3264*ec779b8eSAndroid Build Coastguard Worker     // notify client processes of the new output creation
3265*ec779b8eSAndroid Build Coastguard Worker     thread->ioConfigChanged_l(AUDIO_OUTPUT_OPENED);
3266*ec779b8eSAndroid Build Coastguard Worker     return id;
3267*ec779b8eSAndroid Build Coastguard Worker }
3268*ec779b8eSAndroid Build Coastguard Worker 
closeOutput(audio_io_handle_t output)3269*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::closeOutput(audio_io_handle_t output)
3270*ec779b8eSAndroid Build Coastguard Worker {
3271*ec779b8eSAndroid Build Coastguard Worker     return closeOutput_nonvirtual(output);
3272*ec779b8eSAndroid Build Coastguard Worker }
3273*ec779b8eSAndroid Build Coastguard Worker 
closeOutput_nonvirtual(audio_io_handle_t output)3274*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
3275*ec779b8eSAndroid Build Coastguard Worker {
3276*ec779b8eSAndroid Build Coastguard Worker     // keep strong reference on the playback thread so that
3277*ec779b8eSAndroid Build Coastguard Worker     // it is not destroyed while exit() is executed
3278*ec779b8eSAndroid Build Coastguard Worker     sp<IAfPlaybackThread> playbackThread;
3279*ec779b8eSAndroid Build Coastguard Worker     sp<IAfMmapPlaybackThread> mmapThread;
3280*ec779b8eSAndroid Build Coastguard Worker     {
3281*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
3282*ec779b8eSAndroid Build Coastguard Worker         playbackThread = checkPlaybackThread_l(output);
3283*ec779b8eSAndroid Build Coastguard Worker         if (playbackThread != NULL) {
3284*ec779b8eSAndroid Build Coastguard Worker             ALOGV("closeOutput() %d", output);
3285*ec779b8eSAndroid Build Coastguard Worker 
3286*ec779b8eSAndroid Build Coastguard Worker             dumpToThreadLog_l(playbackThread);
3287*ec779b8eSAndroid Build Coastguard Worker 
3288*ec779b8eSAndroid Build Coastguard Worker             if (playbackThread->type() == IAfThreadBase::MIXER) {
3289*ec779b8eSAndroid Build Coastguard Worker                 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3290*ec779b8eSAndroid Build Coastguard Worker                     if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
3291*ec779b8eSAndroid Build Coastguard Worker                         IAfDuplicatingThread* const dupThread =
3292*ec779b8eSAndroid Build Coastguard Worker                                 mPlaybackThreads.valueAt(i)->asIAfDuplicatingThread().get();
3293*ec779b8eSAndroid Build Coastguard Worker                         dupThread->removeOutputTrack(playbackThread.get());
3294*ec779b8eSAndroid Build Coastguard Worker                     }
3295*ec779b8eSAndroid Build Coastguard Worker                 }
3296*ec779b8eSAndroid Build Coastguard Worker             }
3297*ec779b8eSAndroid Build Coastguard Worker 
3298*ec779b8eSAndroid Build Coastguard Worker 
3299*ec779b8eSAndroid Build Coastguard Worker             mPlaybackThreads.removeItem(output);
3300*ec779b8eSAndroid Build Coastguard Worker             // Save AUDIO_SESSION_OUTPUT_MIX effect to orphan chains
3301*ec779b8eSAndroid Build Coastguard Worker             // Output Mix Effect session is used to manage Music Effect by AudioPolicy Manager.
3302*ec779b8eSAndroid Build Coastguard Worker             // It exists across all playback threads.
3303*ec779b8eSAndroid Build Coastguard Worker             if (playbackThread->type() == IAfThreadBase::MIXER
3304*ec779b8eSAndroid Build Coastguard Worker                     || playbackThread->type() == IAfThreadBase::OFFLOAD
3305*ec779b8eSAndroid Build Coastguard Worker                     || playbackThread->type() == IAfThreadBase::SPATIALIZER) {
3306*ec779b8eSAndroid Build Coastguard Worker                 sp<IAfEffectChain> mixChain;
3307*ec779b8eSAndroid Build Coastguard Worker                 {
3308*ec779b8eSAndroid Build Coastguard Worker                     audio_utils::scoped_lock sl(playbackThread->mutex());
3309*ec779b8eSAndroid Build Coastguard Worker                     mixChain = playbackThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
3310*ec779b8eSAndroid Build Coastguard Worker                     if (mixChain != nullptr) {
3311*ec779b8eSAndroid Build Coastguard Worker                         ALOGW("%s() output %d moving mix session to orphans", __func__, output);
3312*ec779b8eSAndroid Build Coastguard Worker                         playbackThread->removeEffectChain_l(mixChain);
3313*ec779b8eSAndroid Build Coastguard Worker                     }
3314*ec779b8eSAndroid Build Coastguard Worker                 }
3315*ec779b8eSAndroid Build Coastguard Worker                 if (mixChain != nullptr) {
3316*ec779b8eSAndroid Build Coastguard Worker                     putOrphanEffectChain_l(mixChain);
3317*ec779b8eSAndroid Build Coastguard Worker                 }
3318*ec779b8eSAndroid Build Coastguard Worker             }
3319*ec779b8eSAndroid Build Coastguard Worker             // save all effects to the default thread
3320*ec779b8eSAndroid Build Coastguard Worker             if (mPlaybackThreads.size()) {
3321*ec779b8eSAndroid Build Coastguard Worker                 IAfPlaybackThread* const dstThread =
3322*ec779b8eSAndroid Build Coastguard Worker                         checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
3323*ec779b8eSAndroid Build Coastguard Worker                 if (dstThread != NULL) {
3324*ec779b8eSAndroid Build Coastguard Worker                     // audioflinger lock is held so order of thread lock acquisition doesn't matter
3325*ec779b8eSAndroid Build Coastguard Worker                     // Use scoped_lock to avoid deadlock order issues with duplicating threads.
3326*ec779b8eSAndroid Build Coastguard Worker                     audio_utils::scoped_lock sl(dstThread->mutex(), playbackThread->mutex());
3327*ec779b8eSAndroid Build Coastguard Worker                     Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l();
3328*ec779b8eSAndroid Build Coastguard Worker                     for (size_t i = 0; i < effectChains.size(); i ++) {
3329*ec779b8eSAndroid Build Coastguard Worker                         moveEffectChain_ll(effectChains[i]->sessionId(), playbackThread.get(),
3330*ec779b8eSAndroid Build Coastguard Worker                                 dstThread);
3331*ec779b8eSAndroid Build Coastguard Worker                     }
3332*ec779b8eSAndroid Build Coastguard Worker                 }
3333*ec779b8eSAndroid Build Coastguard Worker             }
3334*ec779b8eSAndroid Build Coastguard Worker         } else {
3335*ec779b8eSAndroid Build Coastguard Worker             const sp<IAfMmapThread> mt = checkMmapThread_l(output);
3336*ec779b8eSAndroid Build Coastguard Worker             mmapThread = mt ? mt->asIAfMmapPlaybackThread().get() : nullptr;
3337*ec779b8eSAndroid Build Coastguard Worker             if (mmapThread == 0) {
3338*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
3339*ec779b8eSAndroid Build Coastguard Worker             }
3340*ec779b8eSAndroid Build Coastguard Worker             dumpToThreadLog_l(mmapThread);
3341*ec779b8eSAndroid Build Coastguard Worker             mMmapThreads.removeItem(output);
3342*ec779b8eSAndroid Build Coastguard Worker             ALOGD("closing mmapThread %p", mmapThread.get());
3343*ec779b8eSAndroid Build Coastguard Worker         }
3344*ec779b8eSAndroid Build Coastguard Worker         ioConfigChanged_l(AUDIO_OUTPUT_CLOSED, sp<AudioIoDescriptor>::make(output));
3345*ec779b8eSAndroid Build Coastguard Worker         mPatchPanel->notifyStreamClosed(output);
3346*ec779b8eSAndroid Build Coastguard Worker     }
3347*ec779b8eSAndroid Build Coastguard Worker     // The thread entity (active unit of execution) is no longer running here,
3348*ec779b8eSAndroid Build Coastguard Worker     // but the IAfThreadBase container still exists.
3349*ec779b8eSAndroid Build Coastguard Worker 
3350*ec779b8eSAndroid Build Coastguard Worker     if (playbackThread != 0) {
3351*ec779b8eSAndroid Build Coastguard Worker         playbackThread->exit();
3352*ec779b8eSAndroid Build Coastguard Worker         if (!playbackThread->isDuplicating()) {
3353*ec779b8eSAndroid Build Coastguard Worker             closeOutputFinish(playbackThread);
3354*ec779b8eSAndroid Build Coastguard Worker         }
3355*ec779b8eSAndroid Build Coastguard Worker     } else if (mmapThread != 0) {
3356*ec779b8eSAndroid Build Coastguard Worker         ALOGD("mmapThread exit()");
3357*ec779b8eSAndroid Build Coastguard Worker         mmapThread->exit();
3358*ec779b8eSAndroid Build Coastguard Worker         AudioStreamOut *out = mmapThread->clearOutput();
3359*ec779b8eSAndroid Build Coastguard Worker         ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
3360*ec779b8eSAndroid Build Coastguard Worker         // from now on thread->mOutput is NULL
3361*ec779b8eSAndroid Build Coastguard Worker         delete out;
3362*ec779b8eSAndroid Build Coastguard Worker     }
3363*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
3364*ec779b8eSAndroid Build Coastguard Worker }
3365*ec779b8eSAndroid Build Coastguard Worker 
3366*ec779b8eSAndroid Build Coastguard Worker /* static */
closeOutputFinish(const sp<IAfPlaybackThread> & thread)3367*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::closeOutputFinish(const sp<IAfPlaybackThread>& thread)
3368*ec779b8eSAndroid Build Coastguard Worker {
3369*ec779b8eSAndroid Build Coastguard Worker     AudioStreamOut *out = thread->clearOutput();
3370*ec779b8eSAndroid Build Coastguard Worker     ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
3371*ec779b8eSAndroid Build Coastguard Worker     // from now on thread->mOutput is NULL
3372*ec779b8eSAndroid Build Coastguard Worker     delete out;
3373*ec779b8eSAndroid Build Coastguard Worker }
3374*ec779b8eSAndroid Build Coastguard Worker 
closeThreadInternal_l(const sp<IAfPlaybackThread> & thread)3375*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::closeThreadInternal_l(const sp<IAfPlaybackThread>& thread)
3376*ec779b8eSAndroid Build Coastguard Worker {
3377*ec779b8eSAndroid Build Coastguard Worker     mPlaybackThreads.removeItem(thread->id());
3378*ec779b8eSAndroid Build Coastguard Worker     thread->exit();
3379*ec779b8eSAndroid Build Coastguard Worker     closeOutputFinish(thread);
3380*ec779b8eSAndroid Build Coastguard Worker }
3381*ec779b8eSAndroid Build Coastguard Worker 
suspendOutput(audio_io_handle_t output)3382*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::suspendOutput(audio_io_handle_t output)
3383*ec779b8eSAndroid Build Coastguard Worker {
3384*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3385*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
3386*ec779b8eSAndroid Build Coastguard Worker 
3387*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
3388*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
3389*ec779b8eSAndroid Build Coastguard Worker     }
3390*ec779b8eSAndroid Build Coastguard Worker 
3391*ec779b8eSAndroid Build Coastguard Worker     ALOGV("suspendOutput() %d", output);
3392*ec779b8eSAndroid Build Coastguard Worker     thread->suspend();
3393*ec779b8eSAndroid Build Coastguard Worker 
3394*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
3395*ec779b8eSAndroid Build Coastguard Worker }
3396*ec779b8eSAndroid Build Coastguard Worker 
restoreOutput(audio_io_handle_t output)3397*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
3398*ec779b8eSAndroid Build Coastguard Worker {
3399*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3400*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
3401*ec779b8eSAndroid Build Coastguard Worker 
3402*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
3403*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
3404*ec779b8eSAndroid Build Coastguard Worker     }
3405*ec779b8eSAndroid Build Coastguard Worker 
3406*ec779b8eSAndroid Build Coastguard Worker     ALOGV("restoreOutput() %d", output);
3407*ec779b8eSAndroid Build Coastguard Worker 
3408*ec779b8eSAndroid Build Coastguard Worker     thread->restore();
3409*ec779b8eSAndroid Build Coastguard Worker 
3410*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
3411*ec779b8eSAndroid Build Coastguard Worker }
3412*ec779b8eSAndroid Build Coastguard Worker 
openInput(const media::OpenInputRequest & request,media::OpenInputResponse * response)3413*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::openInput(const media::OpenInputRequest& request,
3414*ec779b8eSAndroid Build Coastguard Worker                                  media::OpenInputResponse* response)
3415*ec779b8eSAndroid Build Coastguard Worker {
3416*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3417*ec779b8eSAndroid Build Coastguard Worker 
3418*ec779b8eSAndroid Build Coastguard Worker     AudioDeviceTypeAddr device = VALUE_OR_RETURN_STATUS(
3419*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_AudioDeviceTypeAddress(request.device));
3420*ec779b8eSAndroid Build Coastguard Worker     if (device.mType == AUDIO_DEVICE_NONE) {
3421*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
3422*ec779b8eSAndroid Build Coastguard Worker     }
3423*ec779b8eSAndroid Build Coastguard Worker 
3424*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t input = VALUE_OR_RETURN_STATUS(
3425*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_int32_t_audio_io_handle_t(request.input));
3426*ec779b8eSAndroid Build Coastguard Worker     audio_config_t config = VALUE_OR_RETURN_STATUS(
3427*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_AudioConfig_audio_config_t(request.config, true /*isInput*/));
3428*ec779b8eSAndroid Build Coastguard Worker 
3429*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfThreadBase> thread = openInput_l(
3430*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_module_handle_t(request.module)),
3431*ec779b8eSAndroid Build Coastguard Worker             &input,
3432*ec779b8eSAndroid Build Coastguard Worker             &config,
3433*ec779b8eSAndroid Build Coastguard Worker             device.mType,
3434*ec779b8eSAndroid Build Coastguard Worker             device.address().c_str(),
3435*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(aidl2legacy_AudioSource_audio_source_t(request.source)),
3436*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_input_flags_t_mask(request.flags)),
3437*ec779b8eSAndroid Build Coastguard Worker             AUDIO_DEVICE_NONE,
3438*ec779b8eSAndroid Build Coastguard Worker             String8{});
3439*ec779b8eSAndroid Build Coastguard Worker 
3440*ec779b8eSAndroid Build Coastguard Worker     response->input = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(input));
3441*ec779b8eSAndroid Build Coastguard Worker     response->config = VALUE_OR_RETURN_STATUS(
3442*ec779b8eSAndroid Build Coastguard Worker             legacy2aidl_audio_config_t_AudioConfig(config, true /*isInput*/));
3443*ec779b8eSAndroid Build Coastguard Worker     response->device = request.device;
3444*ec779b8eSAndroid Build Coastguard Worker 
3445*ec779b8eSAndroid Build Coastguard Worker     if (thread != 0) {
3446*ec779b8eSAndroid Build Coastguard Worker         // notify client processes of the new input creation
3447*ec779b8eSAndroid Build Coastguard Worker         thread->ioConfigChanged_l(AUDIO_INPUT_OPENED);
3448*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
3449*ec779b8eSAndroid Build Coastguard Worker     }
3450*ec779b8eSAndroid Build Coastguard Worker     return NO_INIT;
3451*ec779b8eSAndroid Build Coastguard Worker }
3452*ec779b8eSAndroid Build Coastguard Worker 
openInput_l(audio_module_handle_t module,audio_io_handle_t * input,audio_config_t * config,audio_devices_t devices,const char * address,audio_source_t source,audio_input_flags_t flags,audio_devices_t outputDevice,const String8 & outputDeviceAddress)3453*ec779b8eSAndroid Build Coastguard Worker sp<IAfThreadBase> AudioFlinger::openInput_l(audio_module_handle_t module,
3454*ec779b8eSAndroid Build Coastguard Worker                                                          audio_io_handle_t *input,
3455*ec779b8eSAndroid Build Coastguard Worker                                                          audio_config_t *config,
3456*ec779b8eSAndroid Build Coastguard Worker                                                          audio_devices_t devices,
3457*ec779b8eSAndroid Build Coastguard Worker                                                          const char* address,
3458*ec779b8eSAndroid Build Coastguard Worker                                                          audio_source_t source,
3459*ec779b8eSAndroid Build Coastguard Worker                                                          audio_input_flags_t flags,
3460*ec779b8eSAndroid Build Coastguard Worker                                                          audio_devices_t outputDevice,
3461*ec779b8eSAndroid Build Coastguard Worker                                                          const String8& outputDeviceAddress)
3462*ec779b8eSAndroid Build Coastguard Worker {
3463*ec779b8eSAndroid Build Coastguard Worker     AudioHwDevice *inHwDev = findSuitableHwDev_l(module, devices);
3464*ec779b8eSAndroid Build Coastguard Worker     if (inHwDev == NULL) {
3465*ec779b8eSAndroid Build Coastguard Worker         *input = AUDIO_IO_HANDLE_NONE;
3466*ec779b8eSAndroid Build Coastguard Worker         return 0;
3467*ec779b8eSAndroid Build Coastguard Worker     }
3468*ec779b8eSAndroid Build Coastguard Worker 
3469*ec779b8eSAndroid Build Coastguard Worker     // Audio Policy can request a specific handle for hardware hotword.
3470*ec779b8eSAndroid Build Coastguard Worker     // The goal here is not to re-open an already opened input.
3471*ec779b8eSAndroid Build Coastguard Worker     // It is to use a pre-assigned I/O handle.
3472*ec779b8eSAndroid Build Coastguard Worker     if (*input == AUDIO_IO_HANDLE_NONE) {
3473*ec779b8eSAndroid Build Coastguard Worker         *input = nextUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
3474*ec779b8eSAndroid Build Coastguard Worker     } else if (audio_unique_id_get_use(*input) != AUDIO_UNIQUE_ID_USE_INPUT) {
3475*ec779b8eSAndroid Build Coastguard Worker         ALOGE("openInput_l() requested input handle %d is invalid", *input);
3476*ec779b8eSAndroid Build Coastguard Worker         return 0;
3477*ec779b8eSAndroid Build Coastguard Worker     } else if (mRecordThreads.indexOfKey(*input) >= 0) {
3478*ec779b8eSAndroid Build Coastguard Worker         // This should not happen in a transient state with current design.
3479*ec779b8eSAndroid Build Coastguard Worker         ALOGE("openInput_l() requested input handle %d is already assigned", *input);
3480*ec779b8eSAndroid Build Coastguard Worker         return 0;
3481*ec779b8eSAndroid Build Coastguard Worker     }
3482*ec779b8eSAndroid Build Coastguard Worker 
3483*ec779b8eSAndroid Build Coastguard Worker     AudioStreamIn *inputStream = nullptr;
3484*ec779b8eSAndroid Build Coastguard Worker     status_t status = inHwDev->openInputStream(
3485*ec779b8eSAndroid Build Coastguard Worker             &inputStream,
3486*ec779b8eSAndroid Build Coastguard Worker             *input,
3487*ec779b8eSAndroid Build Coastguard Worker             devices,
3488*ec779b8eSAndroid Build Coastguard Worker             flags,
3489*ec779b8eSAndroid Build Coastguard Worker             config,
3490*ec779b8eSAndroid Build Coastguard Worker             address,
3491*ec779b8eSAndroid Build Coastguard Worker             source,
3492*ec779b8eSAndroid Build Coastguard Worker             outputDevice,
3493*ec779b8eSAndroid Build Coastguard Worker             outputDeviceAddress.c_str());
3494*ec779b8eSAndroid Build Coastguard Worker 
3495*ec779b8eSAndroid Build Coastguard Worker     if (status == NO_ERROR) {
3496*ec779b8eSAndroid Build Coastguard Worker         if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
3497*ec779b8eSAndroid Build Coastguard Worker             const sp<IAfMmapCaptureThread> thread =
3498*ec779b8eSAndroid Build Coastguard Worker                     IAfMmapCaptureThread::create(this, *input, inHwDev, inputStream, mSystemReady);
3499*ec779b8eSAndroid Build Coastguard Worker             mMmapThreads.add(*input, thread);
3500*ec779b8eSAndroid Build Coastguard Worker             ALOGV("openInput_l() created mmap capture thread: ID %d thread %p", *input,
3501*ec779b8eSAndroid Build Coastguard Worker                     thread.get());
3502*ec779b8eSAndroid Build Coastguard Worker             return thread;
3503*ec779b8eSAndroid Build Coastguard Worker         } else {
3504*ec779b8eSAndroid Build Coastguard Worker             // Start record thread
3505*ec779b8eSAndroid Build Coastguard Worker             // IAfRecordThread requires both input and output device indication
3506*ec779b8eSAndroid Build Coastguard Worker             // to forward to audio pre processing modules
3507*ec779b8eSAndroid Build Coastguard Worker             const sp<IAfRecordThread> thread =
3508*ec779b8eSAndroid Build Coastguard Worker                     IAfRecordThread::create(this, inputStream, *input, mSystemReady);
3509*ec779b8eSAndroid Build Coastguard Worker             mRecordThreads.add(*input, thread);
3510*ec779b8eSAndroid Build Coastguard Worker             ALOGV("openInput_l() created record thread: ID %d thread %p", *input, thread.get());
3511*ec779b8eSAndroid Build Coastguard Worker             return thread;
3512*ec779b8eSAndroid Build Coastguard Worker         }
3513*ec779b8eSAndroid Build Coastguard Worker     }
3514*ec779b8eSAndroid Build Coastguard Worker 
3515*ec779b8eSAndroid Build Coastguard Worker     *input = AUDIO_IO_HANDLE_NONE;
3516*ec779b8eSAndroid Build Coastguard Worker     return 0;
3517*ec779b8eSAndroid Build Coastguard Worker }
3518*ec779b8eSAndroid Build Coastguard Worker 
closeInput(audio_io_handle_t input)3519*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::closeInput(audio_io_handle_t input)
3520*ec779b8eSAndroid Build Coastguard Worker {
3521*ec779b8eSAndroid Build Coastguard Worker     return closeInput_nonvirtual(input);
3522*ec779b8eSAndroid Build Coastguard Worker }
3523*ec779b8eSAndroid Build Coastguard Worker 
closeInput_nonvirtual(audio_io_handle_t input)3524*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
3525*ec779b8eSAndroid Build Coastguard Worker {
3526*ec779b8eSAndroid Build Coastguard Worker     // keep strong reference on the record thread so that
3527*ec779b8eSAndroid Build Coastguard Worker     // it is not destroyed while exit() is executed
3528*ec779b8eSAndroid Build Coastguard Worker     sp<IAfRecordThread> recordThread;
3529*ec779b8eSAndroid Build Coastguard Worker     sp<IAfMmapCaptureThread> mmapThread;
3530*ec779b8eSAndroid Build Coastguard Worker     {
3531*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
3532*ec779b8eSAndroid Build Coastguard Worker         recordThread = checkRecordThread_l(input);
3533*ec779b8eSAndroid Build Coastguard Worker         if (recordThread != 0) {
3534*ec779b8eSAndroid Build Coastguard Worker             ALOGV("closeInput() %d", input);
3535*ec779b8eSAndroid Build Coastguard Worker 
3536*ec779b8eSAndroid Build Coastguard Worker             dumpToThreadLog_l(recordThread);
3537*ec779b8eSAndroid Build Coastguard Worker 
3538*ec779b8eSAndroid Build Coastguard Worker             // If we still have effect chains, it means that a client still holds a handle
3539*ec779b8eSAndroid Build Coastguard Worker             // on at least one effect. We must either move the chain to an existing thread with the
3540*ec779b8eSAndroid Build Coastguard Worker             // same session ID or put it aside in case a new record thread is opened for a
3541*ec779b8eSAndroid Build Coastguard Worker             // new capture on the same session
3542*ec779b8eSAndroid Build Coastguard Worker             sp<IAfEffectChain> chain;
3543*ec779b8eSAndroid Build Coastguard Worker             {
3544*ec779b8eSAndroid Build Coastguard Worker                 audio_utils::lock_guard _sl(recordThread->mutex());
3545*ec779b8eSAndroid Build Coastguard Worker                 const Vector<sp<IAfEffectChain>> effectChains = recordThread->getEffectChains_l();
3546*ec779b8eSAndroid Build Coastguard Worker                 // Note: maximum one chain per record thread
3547*ec779b8eSAndroid Build Coastguard Worker                 if (effectChains.size() != 0) {
3548*ec779b8eSAndroid Build Coastguard Worker                     chain = effectChains[0];
3549*ec779b8eSAndroid Build Coastguard Worker                 }
3550*ec779b8eSAndroid Build Coastguard Worker             }
3551*ec779b8eSAndroid Build Coastguard Worker             if (chain != 0) {
3552*ec779b8eSAndroid Build Coastguard Worker                 // first check if a record thread is already opened with a client on same session.
3553*ec779b8eSAndroid Build Coastguard Worker                 // This should only happen in case of overlap between one thread tear down and the
3554*ec779b8eSAndroid Build Coastguard Worker                 // creation of its replacement
3555*ec779b8eSAndroid Build Coastguard Worker                 size_t i;
3556*ec779b8eSAndroid Build Coastguard Worker                 for (i = 0; i < mRecordThreads.size(); i++) {
3557*ec779b8eSAndroid Build Coastguard Worker                     const sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
3558*ec779b8eSAndroid Build Coastguard Worker                     if (t == recordThread) {
3559*ec779b8eSAndroid Build Coastguard Worker                         continue;
3560*ec779b8eSAndroid Build Coastguard Worker                     }
3561*ec779b8eSAndroid Build Coastguard Worker                     if (t->hasAudioSession(chain->sessionId()) != 0) {
3562*ec779b8eSAndroid Build Coastguard Worker                         audio_utils::lock_guard _l2(t->mutex());
3563*ec779b8eSAndroid Build Coastguard Worker                         ALOGV("closeInput() found thread %d for effect session %d",
3564*ec779b8eSAndroid Build Coastguard Worker                               t->id(), chain->sessionId());
3565*ec779b8eSAndroid Build Coastguard Worker                         t->addEffectChain_l(chain);
3566*ec779b8eSAndroid Build Coastguard Worker                         break;
3567*ec779b8eSAndroid Build Coastguard Worker                     }
3568*ec779b8eSAndroid Build Coastguard Worker                 }
3569*ec779b8eSAndroid Build Coastguard Worker                 // put the chain aside if we could not find a record thread with the same session id
3570*ec779b8eSAndroid Build Coastguard Worker                 if (i == mRecordThreads.size()) {
3571*ec779b8eSAndroid Build Coastguard Worker                     putOrphanEffectChain_l(chain);
3572*ec779b8eSAndroid Build Coastguard Worker                 }
3573*ec779b8eSAndroid Build Coastguard Worker             }
3574*ec779b8eSAndroid Build Coastguard Worker             mRecordThreads.removeItem(input);
3575*ec779b8eSAndroid Build Coastguard Worker         } else {
3576*ec779b8eSAndroid Build Coastguard Worker             const sp<IAfMmapThread> mt = checkMmapThread_l(input);
3577*ec779b8eSAndroid Build Coastguard Worker             mmapThread = mt ? mt->asIAfMmapCaptureThread().get() : nullptr;
3578*ec779b8eSAndroid Build Coastguard Worker             if (mmapThread == 0) {
3579*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
3580*ec779b8eSAndroid Build Coastguard Worker             }
3581*ec779b8eSAndroid Build Coastguard Worker             dumpToThreadLog_l(mmapThread);
3582*ec779b8eSAndroid Build Coastguard Worker             mMmapThreads.removeItem(input);
3583*ec779b8eSAndroid Build Coastguard Worker         }
3584*ec779b8eSAndroid Build Coastguard Worker         ioConfigChanged_l(AUDIO_INPUT_CLOSED, sp<AudioIoDescriptor>::make(input));
3585*ec779b8eSAndroid Build Coastguard Worker     }
3586*ec779b8eSAndroid Build Coastguard Worker     // FIXME: calling thread->exit() without mutex() held should not be needed anymore now that
3587*ec779b8eSAndroid Build Coastguard Worker     // we have a different lock for notification client
3588*ec779b8eSAndroid Build Coastguard Worker     if (recordThread != 0) {
3589*ec779b8eSAndroid Build Coastguard Worker         closeInputFinish(recordThread);
3590*ec779b8eSAndroid Build Coastguard Worker     } else if (mmapThread != 0) {
3591*ec779b8eSAndroid Build Coastguard Worker         mmapThread->exit();
3592*ec779b8eSAndroid Build Coastguard Worker         AudioStreamIn *in = mmapThread->clearInput();
3593*ec779b8eSAndroid Build Coastguard Worker         ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
3594*ec779b8eSAndroid Build Coastguard Worker         // from now on thread->mInput is NULL
3595*ec779b8eSAndroid Build Coastguard Worker         delete in;
3596*ec779b8eSAndroid Build Coastguard Worker     }
3597*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
3598*ec779b8eSAndroid Build Coastguard Worker }
3599*ec779b8eSAndroid Build Coastguard Worker 
closeInputFinish(const sp<IAfRecordThread> & thread)3600*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::closeInputFinish(const sp<IAfRecordThread>& thread)
3601*ec779b8eSAndroid Build Coastguard Worker {
3602*ec779b8eSAndroid Build Coastguard Worker     thread->exit();
3603*ec779b8eSAndroid Build Coastguard Worker     AudioStreamIn *in = thread->clearInput();
3604*ec779b8eSAndroid Build Coastguard Worker     ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
3605*ec779b8eSAndroid Build Coastguard Worker     // from now on thread->mInput is NULL
3606*ec779b8eSAndroid Build Coastguard Worker     delete in;
3607*ec779b8eSAndroid Build Coastguard Worker }
3608*ec779b8eSAndroid Build Coastguard Worker 
closeThreadInternal_l(const sp<IAfRecordThread> & thread)3609*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::closeThreadInternal_l(const sp<IAfRecordThread>& thread)
3610*ec779b8eSAndroid Build Coastguard Worker {
3611*ec779b8eSAndroid Build Coastguard Worker     mRecordThreads.removeItem(thread->id());
3612*ec779b8eSAndroid Build Coastguard Worker     closeInputFinish(thread);
3613*ec779b8eSAndroid Build Coastguard Worker }
3614*ec779b8eSAndroid Build Coastguard Worker 
invalidateTracks(const std::vector<audio_port_handle_t> & portIds)3615*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> &portIds) {
3616*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3617*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s", __func__);
3618*ec779b8eSAndroid Build Coastguard Worker 
3619*ec779b8eSAndroid Build Coastguard Worker     std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end());
3620*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3621*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
3622*ec779b8eSAndroid Build Coastguard Worker         thread->invalidateTracks(portIdSet);
3623*ec779b8eSAndroid Build Coastguard Worker         if (portIdSet.empty()) {
3624*ec779b8eSAndroid Build Coastguard Worker             return NO_ERROR;
3625*ec779b8eSAndroid Build Coastguard Worker         }
3626*ec779b8eSAndroid Build Coastguard Worker     }
3627*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mMmapThreads.size(); i++) {
3628*ec779b8eSAndroid Build Coastguard Worker         mMmapThreads[i]->invalidateTracks(portIdSet);
3629*ec779b8eSAndroid Build Coastguard Worker         if (portIdSet.empty()) {
3630*ec779b8eSAndroid Build Coastguard Worker             return NO_ERROR;
3631*ec779b8eSAndroid Build Coastguard Worker         }
3632*ec779b8eSAndroid Build Coastguard Worker     }
3633*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
3634*ec779b8eSAndroid Build Coastguard Worker }
3635*ec779b8eSAndroid Build Coastguard Worker 
3636*ec779b8eSAndroid Build Coastguard Worker 
newAudioUniqueId(audio_unique_id_use_t use)3637*ec779b8eSAndroid Build Coastguard Worker audio_unique_id_t AudioFlinger::newAudioUniqueId(audio_unique_id_use_t use)
3638*ec779b8eSAndroid Build Coastguard Worker {
3639*ec779b8eSAndroid Build Coastguard Worker     // This is a binder API, so a malicious client could pass in a bad parameter.
3640*ec779b8eSAndroid Build Coastguard Worker     // Check for that before calling the internal API nextUniqueId().
3641*ec779b8eSAndroid Build Coastguard Worker     if ((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX) {
3642*ec779b8eSAndroid Build Coastguard Worker         ALOGE("newAudioUniqueId invalid use %d", use);
3643*ec779b8eSAndroid Build Coastguard Worker         return AUDIO_UNIQUE_ID_ALLOCATE;
3644*ec779b8eSAndroid Build Coastguard Worker     }
3645*ec779b8eSAndroid Build Coastguard Worker     return nextUniqueId(use);
3646*ec779b8eSAndroid Build Coastguard Worker }
3647*ec779b8eSAndroid Build Coastguard Worker 
acquireAudioSessionId(audio_session_t audioSession,pid_t pid,uid_t uid)3648*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::acquireAudioSessionId(
3649*ec779b8eSAndroid Build Coastguard Worker         audio_session_t audioSession, pid_t pid, uid_t uid)
3650*ec779b8eSAndroid Build Coastguard Worker {
3651*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
3652*ec779b8eSAndroid Build Coastguard Worker     pid_t caller = IPCThreadState::self()->getCallingPid();
3653*ec779b8eSAndroid Build Coastguard Worker     ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid);
3654*ec779b8eSAndroid Build Coastguard Worker     const uid_t callerUid = IPCThreadState::self()->getCallingUid();
3655*ec779b8eSAndroid Build Coastguard Worker     if (pid != (pid_t)-1 && isAudioServerOrMediaServerUid(callerUid)) {
3656*ec779b8eSAndroid Build Coastguard Worker         caller = pid;  // check must match releaseAudioSessionId()
3657*ec779b8eSAndroid Build Coastguard Worker     }
3658*ec779b8eSAndroid Build Coastguard Worker     if (uid == (uid_t)-1 || !isAudioServerOrMediaServerUid(callerUid)) {
3659*ec779b8eSAndroid Build Coastguard Worker         uid = callerUid;
3660*ec779b8eSAndroid Build Coastguard Worker     }
3661*ec779b8eSAndroid Build Coastguard Worker 
3662*ec779b8eSAndroid Build Coastguard Worker     {
3663*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _cl(clientMutex());
3664*ec779b8eSAndroid Build Coastguard Worker         // Ignore requests received from processes not known as notification client. The request
3665*ec779b8eSAndroid Build Coastguard Worker         // is likely proxied by mediaserver (e.g CameraService) and releaseAudioSessionId() can be
3666*ec779b8eSAndroid Build Coastguard Worker         // called from a different pid leaving a stale session reference.  Also we don't know how
3667*ec779b8eSAndroid Build Coastguard Worker         // to clear this reference if the client process dies.
3668*ec779b8eSAndroid Build Coastguard Worker         if (mNotificationClients.count(caller) == 0) {
3669*ec779b8eSAndroid Build Coastguard Worker             ALOGW("acquireAudioSessionId() unknown client %d for session %d", caller, audioSession);
3670*ec779b8eSAndroid Build Coastguard Worker             return;
3671*ec779b8eSAndroid Build Coastguard Worker         }
3672*ec779b8eSAndroid Build Coastguard Worker     }
3673*ec779b8eSAndroid Build Coastguard Worker 
3674*ec779b8eSAndroid Build Coastguard Worker     size_t num = mAudioSessionRefs.size();
3675*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < num; i++) {
3676*ec779b8eSAndroid Build Coastguard Worker         AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
3677*ec779b8eSAndroid Build Coastguard Worker         if (ref->mSessionid == audioSession && ref->mPid == caller) {
3678*ec779b8eSAndroid Build Coastguard Worker             ref->mCnt++;
3679*ec779b8eSAndroid Build Coastguard Worker             ALOGV(" incremented refcount to %d", ref->mCnt);
3680*ec779b8eSAndroid Build Coastguard Worker             return;
3681*ec779b8eSAndroid Build Coastguard Worker         }
3682*ec779b8eSAndroid Build Coastguard Worker     }
3683*ec779b8eSAndroid Build Coastguard Worker     mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller, uid));
3684*ec779b8eSAndroid Build Coastguard Worker     ALOGV(" added new entry for %d", audioSession);
3685*ec779b8eSAndroid Build Coastguard Worker }
3686*ec779b8eSAndroid Build Coastguard Worker 
releaseAudioSessionId(audio_session_t audioSession,pid_t pid)3687*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid)
3688*ec779b8eSAndroid Build Coastguard Worker {
3689*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<IAfEffectModule>> removedEffects;
3690*ec779b8eSAndroid Build Coastguard Worker     {
3691*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
3692*ec779b8eSAndroid Build Coastguard Worker         pid_t caller = IPCThreadState::self()->getCallingPid();
3693*ec779b8eSAndroid Build Coastguard Worker         ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
3694*ec779b8eSAndroid Build Coastguard Worker         const uid_t callerUid = IPCThreadState::self()->getCallingUid();
3695*ec779b8eSAndroid Build Coastguard Worker         if (pid != (pid_t)-1 && isAudioServerOrMediaServerUid(callerUid)) {
3696*ec779b8eSAndroid Build Coastguard Worker             caller = pid;  // check must match acquireAudioSessionId()
3697*ec779b8eSAndroid Build Coastguard Worker         }
3698*ec779b8eSAndroid Build Coastguard Worker         size_t num = mAudioSessionRefs.size();
3699*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < num; i++) {
3700*ec779b8eSAndroid Build Coastguard Worker             AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
3701*ec779b8eSAndroid Build Coastguard Worker             if (ref->mSessionid == audioSession && ref->mPid == caller) {
3702*ec779b8eSAndroid Build Coastguard Worker                 ref->mCnt--;
3703*ec779b8eSAndroid Build Coastguard Worker                 ALOGV(" decremented refcount to %d", ref->mCnt);
3704*ec779b8eSAndroid Build Coastguard Worker                 if (ref->mCnt == 0) {
3705*ec779b8eSAndroid Build Coastguard Worker                     mAudioSessionRefs.removeAt(i);
3706*ec779b8eSAndroid Build Coastguard Worker                     delete ref;
3707*ec779b8eSAndroid Build Coastguard Worker                     std::vector<sp<IAfEffectModule>> effects = purgeStaleEffects_l();
3708*ec779b8eSAndroid Build Coastguard Worker                     removedEffects.insert(removedEffects.end(), effects.begin(), effects.end());
3709*ec779b8eSAndroid Build Coastguard Worker                 }
3710*ec779b8eSAndroid Build Coastguard Worker                 goto Exit;
3711*ec779b8eSAndroid Build Coastguard Worker             }
3712*ec779b8eSAndroid Build Coastguard Worker         }
3713*ec779b8eSAndroid Build Coastguard Worker         // If the caller is audioserver it is likely that the session being released was acquired
3714*ec779b8eSAndroid Build Coastguard Worker         // on behalf of a process not in notification clients and we ignore the warning.
3715*ec779b8eSAndroid Build Coastguard Worker         ALOGW_IF(!isAudioServerUid(callerUid),
3716*ec779b8eSAndroid Build Coastguard Worker                  "session id %d not found for pid %d", audioSession, caller);
3717*ec779b8eSAndroid Build Coastguard Worker     }
3718*ec779b8eSAndroid Build Coastguard Worker 
3719*ec779b8eSAndroid Build Coastguard Worker Exit:
3720*ec779b8eSAndroid Build Coastguard Worker     for (auto& effect : removedEffects) {
3721*ec779b8eSAndroid Build Coastguard Worker         effect->updatePolicyState();
3722*ec779b8eSAndroid Build Coastguard Worker     }
3723*ec779b8eSAndroid Build Coastguard Worker }
3724*ec779b8eSAndroid Build Coastguard Worker 
isSessionAcquired_l(audio_session_t audioSession)3725*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession)
3726*ec779b8eSAndroid Build Coastguard Worker {
3727*ec779b8eSAndroid Build Coastguard Worker     size_t num = mAudioSessionRefs.size();
3728*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < num; i++) {
3729*ec779b8eSAndroid Build Coastguard Worker         AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
3730*ec779b8eSAndroid Build Coastguard Worker         if (ref->mSessionid == audioSession) {
3731*ec779b8eSAndroid Build Coastguard Worker             return true;
3732*ec779b8eSAndroid Build Coastguard Worker         }
3733*ec779b8eSAndroid Build Coastguard Worker     }
3734*ec779b8eSAndroid Build Coastguard Worker     return false;
3735*ec779b8eSAndroid Build Coastguard Worker }
3736*ec779b8eSAndroid Build Coastguard Worker 
purgeStaleEffects_l()3737*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() {
3738*ec779b8eSAndroid Build Coastguard Worker 
3739*ec779b8eSAndroid Build Coastguard Worker     ALOGV("purging stale effects");
3740*ec779b8eSAndroid Build Coastguard Worker 
3741*ec779b8eSAndroid Build Coastguard Worker     Vector<sp<IAfEffectChain>> chains;
3742*ec779b8eSAndroid Build Coastguard Worker     std::vector< sp<IAfEffectModule> > removedEffects;
3743*ec779b8eSAndroid Build Coastguard Worker 
3744*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3745*ec779b8eSAndroid Build Coastguard Worker         sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
3746*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(t->mutex());
3747*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
3748*ec779b8eSAndroid Build Coastguard Worker         for (size_t j = 0; j < threadChains.size(); j++) {
3749*ec779b8eSAndroid Build Coastguard Worker             sp<IAfEffectChain> ec = threadChains[j];
3750*ec779b8eSAndroid Build Coastguard Worker             if (!audio_is_global_session(ec->sessionId())) {
3751*ec779b8eSAndroid Build Coastguard Worker                 chains.push(ec);
3752*ec779b8eSAndroid Build Coastguard Worker             }
3753*ec779b8eSAndroid Build Coastguard Worker         }
3754*ec779b8eSAndroid Build Coastguard Worker     }
3755*ec779b8eSAndroid Build Coastguard Worker 
3756*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
3757*ec779b8eSAndroid Build Coastguard Worker         sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
3758*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(t->mutex());
3759*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
3760*ec779b8eSAndroid Build Coastguard Worker         for (size_t j = 0; j < threadChains.size(); j++) {
3761*ec779b8eSAndroid Build Coastguard Worker             sp<IAfEffectChain> ec = threadChains[j];
3762*ec779b8eSAndroid Build Coastguard Worker             chains.push(ec);
3763*ec779b8eSAndroid Build Coastguard Worker         }
3764*ec779b8eSAndroid Build Coastguard Worker     }
3765*ec779b8eSAndroid Build Coastguard Worker 
3766*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mMmapThreads.size(); i++) {
3767*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfMmapThread> t = mMmapThreads.valueAt(i);
3768*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(t->mutex());
3769*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
3770*ec779b8eSAndroid Build Coastguard Worker         for (size_t j = 0; j < threadChains.size(); j++) {
3771*ec779b8eSAndroid Build Coastguard Worker             sp<IAfEffectChain> ec = threadChains[j];
3772*ec779b8eSAndroid Build Coastguard Worker             chains.push(ec);
3773*ec779b8eSAndroid Build Coastguard Worker         }
3774*ec779b8eSAndroid Build Coastguard Worker     }
3775*ec779b8eSAndroid Build Coastguard Worker 
3776*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < chains.size(); i++) {
3777*ec779b8eSAndroid Build Coastguard Worker          // clang-tidy suggests const ref
3778*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> ec = chains[i];  // NOLINT(performance-unnecessary-copy-initialization)
3779*ec779b8eSAndroid Build Coastguard Worker         int sessionid = ec->sessionId();
3780*ec779b8eSAndroid Build Coastguard Worker         const auto t = ec->thread().promote();
3781*ec779b8eSAndroid Build Coastguard Worker         if (t == 0) {
3782*ec779b8eSAndroid Build Coastguard Worker             continue;
3783*ec779b8eSAndroid Build Coastguard Worker         }
3784*ec779b8eSAndroid Build Coastguard Worker         size_t numsessionrefs = mAudioSessionRefs.size();
3785*ec779b8eSAndroid Build Coastguard Worker         bool found = false;
3786*ec779b8eSAndroid Build Coastguard Worker         for (size_t k = 0; k < numsessionrefs; k++) {
3787*ec779b8eSAndroid Build Coastguard Worker             AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
3788*ec779b8eSAndroid Build Coastguard Worker             if (ref->mSessionid == sessionid) {
3789*ec779b8eSAndroid Build Coastguard Worker                 ALOGV(" session %d still exists for %d with %d refs",
3790*ec779b8eSAndroid Build Coastguard Worker                     sessionid, ref->mPid, ref->mCnt);
3791*ec779b8eSAndroid Build Coastguard Worker                 found = true;
3792*ec779b8eSAndroid Build Coastguard Worker                 break;
3793*ec779b8eSAndroid Build Coastguard Worker             }
3794*ec779b8eSAndroid Build Coastguard Worker         }
3795*ec779b8eSAndroid Build Coastguard Worker         if (!found) {
3796*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _l(t->mutex());
3797*ec779b8eSAndroid Build Coastguard Worker             // remove all effects from the chain
3798*ec779b8eSAndroid Build Coastguard Worker             while (ec->numberOfEffects()) {
3799*ec779b8eSAndroid Build Coastguard Worker                 sp<IAfEffectModule> effect = ec->getEffectModule(0);
3800*ec779b8eSAndroid Build Coastguard Worker                 effect->unPin();
3801*ec779b8eSAndroid Build Coastguard Worker                 t->removeEffect_l(effect, /*release*/ true);
3802*ec779b8eSAndroid Build Coastguard Worker                 if (effect->purgeHandles()) {
3803*ec779b8eSAndroid Build Coastguard Worker                     effect->checkSuspendOnEffectEnabled(false, true /*threadLocked*/);
3804*ec779b8eSAndroid Build Coastguard Worker                 }
3805*ec779b8eSAndroid Build Coastguard Worker                 removedEffects.push_back(effect);
3806*ec779b8eSAndroid Build Coastguard Worker             }
3807*ec779b8eSAndroid Build Coastguard Worker         }
3808*ec779b8eSAndroid Build Coastguard Worker     }
3809*ec779b8eSAndroid Build Coastguard Worker     return removedEffects;
3810*ec779b8eSAndroid Build Coastguard Worker }
3811*ec779b8eSAndroid Build Coastguard Worker 
purgeOrphanEffectChains_l()3812*ec779b8eSAndroid Build Coastguard Worker std::vector< sp<IAfEffectModule> > AudioFlinger::purgeOrphanEffectChains_l()
3813*ec779b8eSAndroid Build Coastguard Worker {
3814*ec779b8eSAndroid Build Coastguard Worker     ALOGV("purging stale effects from orphan chains");
3815*ec779b8eSAndroid Build Coastguard Worker     std::vector< sp<IAfEffectModule> > removedEffects;
3816*ec779b8eSAndroid Build Coastguard Worker     for (size_t index = 0; index < mOrphanEffectChains.size(); index++) {
3817*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> chain = mOrphanEffectChains.valueAt(index);
3818*ec779b8eSAndroid Build Coastguard Worker         audio_session_t session = mOrphanEffectChains.keyAt(index);
3819*ec779b8eSAndroid Build Coastguard Worker         if (session == AUDIO_SESSION_OUTPUT_MIX || session == AUDIO_SESSION_DEVICE
3820*ec779b8eSAndroid Build Coastguard Worker                 || session == AUDIO_SESSION_OUTPUT_STAGE) {
3821*ec779b8eSAndroid Build Coastguard Worker             continue;
3822*ec779b8eSAndroid Build Coastguard Worker         }
3823*ec779b8eSAndroid Build Coastguard Worker         size_t numSessionRefs = mAudioSessionRefs.size();
3824*ec779b8eSAndroid Build Coastguard Worker         bool found = false;
3825*ec779b8eSAndroid Build Coastguard Worker         for (size_t k = 0; k < numSessionRefs; k++) {
3826*ec779b8eSAndroid Build Coastguard Worker             AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
3827*ec779b8eSAndroid Build Coastguard Worker             if (ref->mSessionid == session) {
3828*ec779b8eSAndroid Build Coastguard Worker                 ALOGV(" session %d still exists for %d with %d refs", session, ref->mPid,
3829*ec779b8eSAndroid Build Coastguard Worker                         ref->mCnt);
3830*ec779b8eSAndroid Build Coastguard Worker                 found = true;
3831*ec779b8eSAndroid Build Coastguard Worker                 break;
3832*ec779b8eSAndroid Build Coastguard Worker             }
3833*ec779b8eSAndroid Build Coastguard Worker         }
3834*ec779b8eSAndroid Build Coastguard Worker         if (!found) {
3835*ec779b8eSAndroid Build Coastguard Worker             for (size_t i = 0; i < chain->numberOfEffects(); i++) {
3836*ec779b8eSAndroid Build Coastguard Worker                 sp<IAfEffectModule> effect = chain->getEffectModule(i);
3837*ec779b8eSAndroid Build Coastguard Worker                 removedEffects.push_back(effect);
3838*ec779b8eSAndroid Build Coastguard Worker             }
3839*ec779b8eSAndroid Build Coastguard Worker         }
3840*ec779b8eSAndroid Build Coastguard Worker     }
3841*ec779b8eSAndroid Build Coastguard Worker     for (auto& effect : removedEffects) {
3842*ec779b8eSAndroid Build Coastguard Worker         effect->unPin();
3843*ec779b8eSAndroid Build Coastguard Worker         updateOrphanEffectChains_l(effect);
3844*ec779b8eSAndroid Build Coastguard Worker     }
3845*ec779b8eSAndroid Build Coastguard Worker     return removedEffects;
3846*ec779b8eSAndroid Build Coastguard Worker }
3847*ec779b8eSAndroid Build Coastguard Worker 
3848*ec779b8eSAndroid Build Coastguard Worker // dumpToThreadLog_l() must be called with AudioFlinger::mutex() held
dumpToThreadLog_l(const sp<IAfThreadBase> & thread)3849*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::dumpToThreadLog_l(const sp<IAfThreadBase> &thread)
3850*ec779b8eSAndroid Build Coastguard Worker {
3851*ec779b8eSAndroid Build Coastguard Worker     constexpr int THREAD_DUMP_TIMEOUT_MS = 2;
3852*ec779b8eSAndroid Build Coastguard Worker     constexpr auto PREFIX = "- ";
3853*ec779b8eSAndroid Build Coastguard Worker     if (com::android::media::audioserver::fdtostring_timeout_fix()) {
3854*ec779b8eSAndroid Build Coastguard Worker         using ::android::audio_utils::FdToString;
3855*ec779b8eSAndroid Build Coastguard Worker 
3856*ec779b8eSAndroid Build Coastguard Worker         auto writer = OR_RETURN(FdToString::createWriter(PREFIX));
3857*ec779b8eSAndroid Build Coastguard Worker         thread->dump(writer.borrowFdUnsafe(), {} /* args */);
3858*ec779b8eSAndroid Build Coastguard Worker         mThreadLog.logs(-1 /* time */, FdToString::closeWriterAndGetString(std::move(writer)));
3859*ec779b8eSAndroid Build Coastguard Worker     } else {
3860*ec779b8eSAndroid Build Coastguard Worker         audio_utils::FdToStringOldImpl fdToString("- ", THREAD_DUMP_TIMEOUT_MS);
3861*ec779b8eSAndroid Build Coastguard Worker         const int fd = fdToString.borrowFdUnsafe();
3862*ec779b8eSAndroid Build Coastguard Worker         if (fd >= 0) {
3863*ec779b8eSAndroid Build Coastguard Worker             thread->dump(fd, {} /* args */);
3864*ec779b8eSAndroid Build Coastguard Worker             mThreadLog.logs(-1 /* time */, fdToString.closeAndGetString());
3865*ec779b8eSAndroid Build Coastguard Worker         }
3866*ec779b8eSAndroid Build Coastguard Worker     }
3867*ec779b8eSAndroid Build Coastguard Worker }
3868*ec779b8eSAndroid Build Coastguard Worker 
3869*ec779b8eSAndroid Build Coastguard Worker // checkThread_l() must be called with AudioFlinger::mutex() held
checkThread_l(audio_io_handle_t ioHandle) const3870*ec779b8eSAndroid Build Coastguard Worker IAfThreadBase* AudioFlinger::checkThread_l(audio_io_handle_t ioHandle) const
3871*ec779b8eSAndroid Build Coastguard Worker {
3872*ec779b8eSAndroid Build Coastguard Worker     IAfThreadBase* thread = checkMmapThread_l(ioHandle);
3873*ec779b8eSAndroid Build Coastguard Worker     if (thread == 0) {
3874*ec779b8eSAndroid Build Coastguard Worker         switch (audio_unique_id_get_use(ioHandle)) {
3875*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_UNIQUE_ID_USE_OUTPUT:
3876*ec779b8eSAndroid Build Coastguard Worker             thread = checkPlaybackThread_l(ioHandle);
3877*ec779b8eSAndroid Build Coastguard Worker             break;
3878*ec779b8eSAndroid Build Coastguard Worker         case AUDIO_UNIQUE_ID_USE_INPUT:
3879*ec779b8eSAndroid Build Coastguard Worker             thread = checkRecordThread_l(ioHandle);
3880*ec779b8eSAndroid Build Coastguard Worker             break;
3881*ec779b8eSAndroid Build Coastguard Worker         default:
3882*ec779b8eSAndroid Build Coastguard Worker             break;
3883*ec779b8eSAndroid Build Coastguard Worker         }
3884*ec779b8eSAndroid Build Coastguard Worker     }
3885*ec779b8eSAndroid Build Coastguard Worker     return thread;
3886*ec779b8eSAndroid Build Coastguard Worker }
3887*ec779b8eSAndroid Build Coastguard Worker 
3888*ec779b8eSAndroid Build Coastguard Worker // checkOutputThread_l() must be called with AudioFlinger::mutex() held
checkOutputThread_l(audio_io_handle_t ioHandle) const3889*ec779b8eSAndroid Build Coastguard Worker sp<IAfThreadBase> AudioFlinger::checkOutputThread_l(audio_io_handle_t ioHandle) const
3890*ec779b8eSAndroid Build Coastguard Worker {
3891*ec779b8eSAndroid Build Coastguard Worker     if (audio_unique_id_get_use(ioHandle) != AUDIO_UNIQUE_ID_USE_OUTPUT) {
3892*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
3893*ec779b8eSAndroid Build Coastguard Worker     }
3894*ec779b8eSAndroid Build Coastguard Worker 
3895*ec779b8eSAndroid Build Coastguard Worker     sp<IAfThreadBase> thread = mPlaybackThreads.valueFor(ioHandle);
3896*ec779b8eSAndroid Build Coastguard Worker     if (thread == nullptr) {
3897*ec779b8eSAndroid Build Coastguard Worker         thread = mMmapThreads.valueFor(ioHandle);
3898*ec779b8eSAndroid Build Coastguard Worker     }
3899*ec779b8eSAndroid Build Coastguard Worker     return thread;
3900*ec779b8eSAndroid Build Coastguard Worker }
3901*ec779b8eSAndroid Build Coastguard Worker 
3902*ec779b8eSAndroid Build Coastguard Worker // checkPlaybackThread_l() must be called with AudioFlinger::mutex() held
checkPlaybackThread_l(audio_io_handle_t output) const3903*ec779b8eSAndroid Build Coastguard Worker IAfPlaybackThread* AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
3904*ec779b8eSAndroid Build Coastguard Worker {
3905*ec779b8eSAndroid Build Coastguard Worker     return mPlaybackThreads.valueFor(output).get();
3906*ec779b8eSAndroid Build Coastguard Worker }
3907*ec779b8eSAndroid Build Coastguard Worker 
3908*ec779b8eSAndroid Build Coastguard Worker // checkMixerThread_l() must be called with AudioFlinger::mutex() held
checkMixerThread_l(audio_io_handle_t output) const3909*ec779b8eSAndroid Build Coastguard Worker IAfPlaybackThread* AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
3910*ec779b8eSAndroid Build Coastguard Worker {
3911*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread * const thread = checkPlaybackThread_l(output);
3912*ec779b8eSAndroid Build Coastguard Worker     return thread != nullptr && thread->type() != IAfThreadBase::DIRECT ? thread : nullptr;
3913*ec779b8eSAndroid Build Coastguard Worker }
3914*ec779b8eSAndroid Build Coastguard Worker 
3915*ec779b8eSAndroid Build Coastguard Worker // checkRecordThread_l() must be called with AudioFlinger::mutex() held
checkRecordThread_l(audio_io_handle_t input) const3916*ec779b8eSAndroid Build Coastguard Worker IAfRecordThread* AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
3917*ec779b8eSAndroid Build Coastguard Worker {
3918*ec779b8eSAndroid Build Coastguard Worker     return mRecordThreads.valueFor(input).get();
3919*ec779b8eSAndroid Build Coastguard Worker }
3920*ec779b8eSAndroid Build Coastguard Worker 
3921*ec779b8eSAndroid Build Coastguard Worker // checkMmapThread_l() must be called with AudioFlinger::mutex() held
checkMmapThread_l(audio_io_handle_t io) const3922*ec779b8eSAndroid Build Coastguard Worker IAfMmapThread* AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
3923*ec779b8eSAndroid Build Coastguard Worker {
3924*ec779b8eSAndroid Build Coastguard Worker     return mMmapThreads.valueFor(io).get();
3925*ec779b8eSAndroid Build Coastguard Worker }
3926*ec779b8eSAndroid Build Coastguard Worker 
3927*ec779b8eSAndroid Build Coastguard Worker 
3928*ec779b8eSAndroid Build Coastguard Worker // checkPlaybackThread_l() must be called with AudioFlinger::mutex() held
getVolumeInterface_l(audio_io_handle_t output) const3929*ec779b8eSAndroid Build Coastguard Worker sp<VolumeInterface> AudioFlinger::getVolumeInterface_l(audio_io_handle_t output) const {
3930*ec779b8eSAndroid Build Coastguard Worker     sp<VolumeInterface> volumeInterface = mPlaybackThreads.valueFor(output).get();
3931*ec779b8eSAndroid Build Coastguard Worker     if (volumeInterface == nullptr) {
3932*ec779b8eSAndroid Build Coastguard Worker         IAfMmapThread* const mmapThread = mMmapThreads.valueFor(output).get();
3933*ec779b8eSAndroid Build Coastguard Worker         if (mmapThread != nullptr) {
3934*ec779b8eSAndroid Build Coastguard Worker             if (mmapThread->isOutput()) {
3935*ec779b8eSAndroid Build Coastguard Worker                 IAfMmapPlaybackThread* const mmapPlaybackThread =
3936*ec779b8eSAndroid Build Coastguard Worker                         mmapThread->asIAfMmapPlaybackThread().get();
3937*ec779b8eSAndroid Build Coastguard Worker                 volumeInterface = mmapPlaybackThread;
3938*ec779b8eSAndroid Build Coastguard Worker             }
3939*ec779b8eSAndroid Build Coastguard Worker         }
3940*ec779b8eSAndroid Build Coastguard Worker     }
3941*ec779b8eSAndroid Build Coastguard Worker     return volumeInterface;
3942*ec779b8eSAndroid Build Coastguard Worker }
3943*ec779b8eSAndroid Build Coastguard Worker 
getAllVolumeInterfaces_l() const3944*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<VolumeInterface>> AudioFlinger::getAllVolumeInterfaces_l() const
3945*ec779b8eSAndroid Build Coastguard Worker {
3946*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<VolumeInterface>> volumeInterfaces;
3947*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3948*ec779b8eSAndroid Build Coastguard Worker         volumeInterfaces.push_back(mPlaybackThreads.valueAt(i).get());
3949*ec779b8eSAndroid Build Coastguard Worker     }
3950*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mMmapThreads.size(); i++) {
3951*ec779b8eSAndroid Build Coastguard Worker         if (mMmapThreads.valueAt(i)->isOutput()) {
3952*ec779b8eSAndroid Build Coastguard Worker             IAfMmapPlaybackThread* const mmapPlaybackThread =
3953*ec779b8eSAndroid Build Coastguard Worker                     mMmapThreads.valueAt(i)->asIAfMmapPlaybackThread().get();
3954*ec779b8eSAndroid Build Coastguard Worker             volumeInterfaces.push_back(mmapPlaybackThread);
3955*ec779b8eSAndroid Build Coastguard Worker         }
3956*ec779b8eSAndroid Build Coastguard Worker     }
3957*ec779b8eSAndroid Build Coastguard Worker     return volumeInterfaces;
3958*ec779b8eSAndroid Build Coastguard Worker }
3959*ec779b8eSAndroid Build Coastguard Worker 
nextUniqueId(audio_unique_id_use_t use)3960*ec779b8eSAndroid Build Coastguard Worker audio_unique_id_t AudioFlinger::nextUniqueId(audio_unique_id_use_t use)
3961*ec779b8eSAndroid Build Coastguard Worker {
3962*ec779b8eSAndroid Build Coastguard Worker     // This is the internal API, so it is OK to assert on bad parameter.
3963*ec779b8eSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX);
3964*ec779b8eSAndroid Build Coastguard Worker     const int maxRetries = use == AUDIO_UNIQUE_ID_USE_SESSION ? 3 : 1;
3965*ec779b8eSAndroid Build Coastguard Worker     for (int retry = 0; retry < maxRetries; retry++) {
3966*ec779b8eSAndroid Build Coastguard Worker         // The cast allows wraparound from max positive to min negative instead of abort
3967*ec779b8eSAndroid Build Coastguard Worker         uint32_t base = (uint32_t) atomic_fetch_add_explicit(&mNextUniqueIds[use],
3968*ec779b8eSAndroid Build Coastguard Worker                 (uint_fast32_t) AUDIO_UNIQUE_ID_USE_MAX, memory_order_acq_rel);
3969*ec779b8eSAndroid Build Coastguard Worker         ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
3970*ec779b8eSAndroid Build Coastguard Worker         // allow wrap by skipping 0 and -1 for session ids
3971*ec779b8eSAndroid Build Coastguard Worker         if (!(base == 0 || base == (~0u & ~AUDIO_UNIQUE_ID_USE_MASK))) {
3972*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(retry != 0, "unique ID overflow for use %d", use);
3973*ec779b8eSAndroid Build Coastguard Worker             return (audio_unique_id_t) (base | use);
3974*ec779b8eSAndroid Build Coastguard Worker         }
3975*ec779b8eSAndroid Build Coastguard Worker     }
3976*ec779b8eSAndroid Build Coastguard Worker     // We have no way of recovering from wraparound
3977*ec779b8eSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL("unique ID overflow for use %d", use);
3978*ec779b8eSAndroid Build Coastguard Worker     // TODO Use a floor after wraparound.  This may need a mutex.
3979*ec779b8eSAndroid Build Coastguard Worker }
3980*ec779b8eSAndroid Build Coastguard Worker 
primaryPlaybackThread_l() const3981*ec779b8eSAndroid Build Coastguard Worker IAfPlaybackThread* AudioFlinger::primaryPlaybackThread_l() const
3982*ec779b8eSAndroid Build Coastguard Worker {
3983*ec779b8eSAndroid Build Coastguard Worker     // The atomic ptr mPrimaryHardwareDev requires both the
3984*ec779b8eSAndroid Build Coastguard Worker     // AudioFlinger and the Hardware mutex for modification.
3985*ec779b8eSAndroid Build Coastguard Worker     // As we hold the AudioFlinger mutex, we access it
3986*ec779b8eSAndroid Build Coastguard Worker     // safely without the Hardware mutex, to avoid mutex order
3987*ec779b8eSAndroid Build Coastguard Worker     // inversion with Thread methods and the ThreadBase mutex.
3988*ec779b8eSAndroid Build Coastguard Worker     if (mPrimaryHardwareDev == nullptr) {
3989*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
3990*ec779b8eSAndroid Build Coastguard Worker     }
3991*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3992*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
3993*ec779b8eSAndroid Build Coastguard Worker         if(thread->isDuplicating()) {
3994*ec779b8eSAndroid Build Coastguard Worker             continue;
3995*ec779b8eSAndroid Build Coastguard Worker         }
3996*ec779b8eSAndroid Build Coastguard Worker         AudioStreamOut *output = thread->getOutput();
3997*ec779b8eSAndroid Build Coastguard Worker         if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
3998*ec779b8eSAndroid Build Coastguard Worker             return thread;
3999*ec779b8eSAndroid Build Coastguard Worker         }
4000*ec779b8eSAndroid Build Coastguard Worker     }
4001*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
4002*ec779b8eSAndroid Build Coastguard Worker }
4003*ec779b8eSAndroid Build Coastguard Worker 
primaryOutputDevice_l() const4004*ec779b8eSAndroid Build Coastguard Worker DeviceTypeSet AudioFlinger::primaryOutputDevice_l() const
4005*ec779b8eSAndroid Build Coastguard Worker {
4006*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* const thread = primaryPlaybackThread_l();
4007*ec779b8eSAndroid Build Coastguard Worker 
4008*ec779b8eSAndroid Build Coastguard Worker     if (thread == NULL) {
4009*ec779b8eSAndroid Build Coastguard Worker         return {};
4010*ec779b8eSAndroid Build Coastguard Worker     }
4011*ec779b8eSAndroid Build Coastguard Worker 
4012*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard l(thread->mutex());
4013*ec779b8eSAndroid Build Coastguard Worker     return thread->outDeviceTypes_l();
4014*ec779b8eSAndroid Build Coastguard Worker }
4015*ec779b8eSAndroid Build Coastguard Worker 
fastPlaybackThread_l() const4016*ec779b8eSAndroid Build Coastguard Worker IAfPlaybackThread* AudioFlinger::fastPlaybackThread_l() const
4017*ec779b8eSAndroid Build Coastguard Worker {
4018*ec779b8eSAndroid Build Coastguard Worker     size_t minFrameCount = 0;
4019*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* minThread = nullptr;
4020*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
4021*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
4022*ec779b8eSAndroid Build Coastguard Worker         if (!thread->isDuplicating()) {
4023*ec779b8eSAndroid Build Coastguard Worker             size_t frameCount = thread->frameCountHAL();
4024*ec779b8eSAndroid Build Coastguard Worker             if (frameCount != 0 && (minFrameCount == 0 || frameCount < minFrameCount ||
4025*ec779b8eSAndroid Build Coastguard Worker                     (frameCount == minFrameCount && thread->hasFastMixer() &&
4026*ec779b8eSAndroid Build Coastguard Worker                     /*minThread != NULL &&*/ !minThread->hasFastMixer()))) {
4027*ec779b8eSAndroid Build Coastguard Worker                 minFrameCount = frameCount;
4028*ec779b8eSAndroid Build Coastguard Worker                 minThread = thread;
4029*ec779b8eSAndroid Build Coastguard Worker             }
4030*ec779b8eSAndroid Build Coastguard Worker         }
4031*ec779b8eSAndroid Build Coastguard Worker     }
4032*ec779b8eSAndroid Build Coastguard Worker     return minThread;
4033*ec779b8eSAndroid Build Coastguard Worker }
4034*ec779b8eSAndroid Build Coastguard Worker 
hapticPlaybackThread_l() const4035*ec779b8eSAndroid Build Coastguard Worker IAfThreadBase* AudioFlinger::hapticPlaybackThread_l() const {
4036*ec779b8eSAndroid Build Coastguard Worker     for (size_t i  = 0; i < mPlaybackThreads.size(); ++i) {
4037*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
4038*ec779b8eSAndroid Build Coastguard Worker         if (thread->hapticChannelMask() != AUDIO_CHANNEL_NONE) {
4039*ec779b8eSAndroid Build Coastguard Worker             return thread;
4040*ec779b8eSAndroid Build Coastguard Worker         }
4041*ec779b8eSAndroid Build Coastguard Worker     }
4042*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
4043*ec779b8eSAndroid Build Coastguard Worker }
4044*ec779b8eSAndroid Build Coastguard Worker 
updateSecondaryOutputsForTrack_l(IAfTrack * track,IAfPlaybackThread * thread,const std::vector<audio_io_handle_t> & secondaryOutputs) const4045*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::updateSecondaryOutputsForTrack_l(
4046*ec779b8eSAndroid Build Coastguard Worker         IAfTrack* track,
4047*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* thread,
4048*ec779b8eSAndroid Build Coastguard Worker         const std::vector<audio_io_handle_t> &secondaryOutputs) const {
4049*ec779b8eSAndroid Build Coastguard Worker     TeePatches teePatches;
4050*ec779b8eSAndroid Build Coastguard Worker     for (audio_io_handle_t secondaryOutput : secondaryOutputs) {
4051*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* const secondaryThread = checkPlaybackThread_l(secondaryOutput);
4052*ec779b8eSAndroid Build Coastguard Worker         if (secondaryThread == nullptr) {
4053*ec779b8eSAndroid Build Coastguard Worker             ALOGE("no playback thread found for secondary output %d", thread->id());
4054*ec779b8eSAndroid Build Coastguard Worker             continue;
4055*ec779b8eSAndroid Build Coastguard Worker         }
4056*ec779b8eSAndroid Build Coastguard Worker 
4057*ec779b8eSAndroid Build Coastguard Worker         size_t sourceFrameCount = thread->frameCount() * track->sampleRate()
4058*ec779b8eSAndroid Build Coastguard Worker                                   / thread->sampleRate();
4059*ec779b8eSAndroid Build Coastguard Worker         size_t sinkFrameCount = secondaryThread->frameCount() * track->sampleRate()
4060*ec779b8eSAndroid Build Coastguard Worker                                   / secondaryThread->sampleRate();
4061*ec779b8eSAndroid Build Coastguard Worker         // If the secondary output has just been opened, the first secondaryThread write
4062*ec779b8eSAndroid Build Coastguard Worker         // will not block as it will fill the empty startup buffer of the HAL,
4063*ec779b8eSAndroid Build Coastguard Worker         // so a second sink buffer needs to be ready for the immediate next blocking write.
4064*ec779b8eSAndroid Build Coastguard Worker         // Additionally, have a margin of one main thread buffer as the scheduling jitter
4065*ec779b8eSAndroid Build Coastguard Worker         // can reorder the writes (eg if thread A&B have the same write intervale,
4066*ec779b8eSAndroid Build Coastguard Worker         // the scheduler could schedule AB...BA)
4067*ec779b8eSAndroid Build Coastguard Worker         size_t frameCountToBeReady = 2 * sinkFrameCount + sourceFrameCount;
4068*ec779b8eSAndroid Build Coastguard Worker         // Total secondary output buffer must be at least as the read frames plus
4069*ec779b8eSAndroid Build Coastguard Worker         // the margin of a few buffers on both sides in case the
4070*ec779b8eSAndroid Build Coastguard Worker         // threads scheduling has some jitter.
4071*ec779b8eSAndroid Build Coastguard Worker         // That value should not impact latency as the secondary track is started before
4072*ec779b8eSAndroid Build Coastguard Worker         // its buffer is full, see frameCountToBeReady.
4073*ec779b8eSAndroid Build Coastguard Worker         size_t frameCount = frameCountToBeReady + 2 * (sourceFrameCount + sinkFrameCount);
4074*ec779b8eSAndroid Build Coastguard Worker         // The frameCount should also not be smaller than the secondary thread min frame
4075*ec779b8eSAndroid Build Coastguard Worker         // count
4076*ec779b8eSAndroid Build Coastguard Worker         size_t minFrameCount = AudioSystem::calculateMinFrameCount(
4077*ec779b8eSAndroid Build Coastguard Worker                     [&] { audio_utils::lock_guard _l(secondaryThread->mutex());
4078*ec779b8eSAndroid Build Coastguard Worker                           return secondaryThread->latency_l(); }(),
4079*ec779b8eSAndroid Build Coastguard Worker                     secondaryThread->frameCount(), // normal frame count
4080*ec779b8eSAndroid Build Coastguard Worker                     secondaryThread->sampleRate(),
4081*ec779b8eSAndroid Build Coastguard Worker                     track->sampleRate(),
4082*ec779b8eSAndroid Build Coastguard Worker                     track->getSpeed());
4083*ec779b8eSAndroid Build Coastguard Worker         frameCount = std::max(frameCount, minFrameCount);
4084*ec779b8eSAndroid Build Coastguard Worker 
4085*ec779b8eSAndroid Build Coastguard Worker         using namespace std::chrono_literals;
4086*ec779b8eSAndroid Build Coastguard Worker         auto inChannelMask = audio_channel_mask_out_to_in(track->channelMask());
4087*ec779b8eSAndroid Build Coastguard Worker         if (inChannelMask == AUDIO_CHANNEL_INVALID) {
4088*ec779b8eSAndroid Build Coastguard Worker             // The downstream PatchTrack has the proper output channel mask,
4089*ec779b8eSAndroid Build Coastguard Worker             // so if there is no input channel mask equivalent, we can just
4090*ec779b8eSAndroid Build Coastguard Worker             // use an index mask here to create the PatchRecord.
4091*ec779b8eSAndroid Build Coastguard Worker             inChannelMask = audio_channel_mask_out_to_in_index_mask(track->channelMask());
4092*ec779b8eSAndroid Build Coastguard Worker         }
4093*ec779b8eSAndroid Build Coastguard Worker         sp<IAfPatchRecord> patchRecord = IAfPatchRecord::create(nullptr /* thread */,
4094*ec779b8eSAndroid Build Coastguard Worker                                                        track->sampleRate(),
4095*ec779b8eSAndroid Build Coastguard Worker                                                        inChannelMask,
4096*ec779b8eSAndroid Build Coastguard Worker                                                        track->format(),
4097*ec779b8eSAndroid Build Coastguard Worker                                                        frameCount,
4098*ec779b8eSAndroid Build Coastguard Worker                                                        nullptr /* buffer */,
4099*ec779b8eSAndroid Build Coastguard Worker                                                        (size_t)0 /* bufferSize */,
4100*ec779b8eSAndroid Build Coastguard Worker                                                        AUDIO_INPUT_FLAG_DIRECT,
4101*ec779b8eSAndroid Build Coastguard Worker                                                        0ns /* timeout */);
4102*ec779b8eSAndroid Build Coastguard Worker         status_t status = patchRecord->initCheck();
4103*ec779b8eSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
4104*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Secondary output patchRecord init failed: %d", status);
4105*ec779b8eSAndroid Build Coastguard Worker             continue;
4106*ec779b8eSAndroid Build Coastguard Worker         }
4107*ec779b8eSAndroid Build Coastguard Worker 
4108*ec779b8eSAndroid Build Coastguard Worker         // TODO: We could check compatibility of the secondaryThread with the PatchTrack
4109*ec779b8eSAndroid Build Coastguard Worker         // for fast usage: thread has fast mixer, sample rate matches, etc.;
4110*ec779b8eSAndroid Build Coastguard Worker         // for now, we exclude fast tracks by removing the Fast flag.
4111*ec779b8eSAndroid Build Coastguard Worker         constexpr audio_output_flags_t kIncompatiblePatchTrackFlags =
4112*ec779b8eSAndroid Build Coastguard Worker                 static_cast<audio_output_flags_t>(AUDIO_OUTPUT_FLAG_FAST
4113*ec779b8eSAndroid Build Coastguard Worker                         | AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
4114*ec779b8eSAndroid Build Coastguard Worker 
4115*ec779b8eSAndroid Build Coastguard Worker         const audio_output_flags_t outputFlags =
4116*ec779b8eSAndroid Build Coastguard Worker                 (audio_output_flags_t)(track->getOutputFlags() & ~kIncompatiblePatchTrackFlags);
4117*ec779b8eSAndroid Build Coastguard Worker         sp<IAfPatchTrack> patchTrack = IAfPatchTrack::create(secondaryThread,
4118*ec779b8eSAndroid Build Coastguard Worker                                                        track->streamType(),
4119*ec779b8eSAndroid Build Coastguard Worker                                                        track->sampleRate(),
4120*ec779b8eSAndroid Build Coastguard Worker                                                        track->channelMask(),
4121*ec779b8eSAndroid Build Coastguard Worker                                                        track->format(),
4122*ec779b8eSAndroid Build Coastguard Worker                                                        frameCount,
4123*ec779b8eSAndroid Build Coastguard Worker                                                        patchRecord->buffer(),
4124*ec779b8eSAndroid Build Coastguard Worker                                                        patchRecord->bufferSize(),
4125*ec779b8eSAndroid Build Coastguard Worker                                                        outputFlags,
4126*ec779b8eSAndroid Build Coastguard Worker                                                        0ns /* timeout */,
4127*ec779b8eSAndroid Build Coastguard Worker                                                        frameCountToBeReady,
4128*ec779b8eSAndroid Build Coastguard Worker                                                        track->getSpeed(),
4129*ec779b8eSAndroid Build Coastguard Worker                                                        1.f /* volume */,
4130*ec779b8eSAndroid Build Coastguard Worker                                                        false /* muted */);
4131*ec779b8eSAndroid Build Coastguard Worker         status = patchTrack->initCheck();
4132*ec779b8eSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
4133*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Secondary output patchTrack init failed: %d", status);
4134*ec779b8eSAndroid Build Coastguard Worker             continue;
4135*ec779b8eSAndroid Build Coastguard Worker         }
4136*ec779b8eSAndroid Build Coastguard Worker         teePatches.push_back({patchRecord, patchTrack});
4137*ec779b8eSAndroid Build Coastguard Worker         secondaryThread->addPatchTrack(patchTrack);
4138*ec779b8eSAndroid Build Coastguard Worker         // In case the downstream patchTrack on the secondaryThread temporarily outlives
4139*ec779b8eSAndroid Build Coastguard Worker         // our created track, ensure the corresponding patchRecord is still alive.
4140*ec779b8eSAndroid Build Coastguard Worker         patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
4141*ec779b8eSAndroid Build Coastguard Worker         patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
4142*ec779b8eSAndroid Build Coastguard Worker     }
4143*ec779b8eSAndroid Build Coastguard Worker     track->setTeePatchesToUpdate_l(std::move(teePatches));
4144*ec779b8eSAndroid Build Coastguard Worker }
4145*ec779b8eSAndroid Build Coastguard Worker 
createSyncEvent(AudioSystem::sync_event_t type,audio_session_t triggerSession,audio_session_t listenerSession,const audioflinger::SyncEventCallback & callBack,const wp<IAfTrackBase> & cookie)4146*ec779b8eSAndroid Build Coastguard Worker sp<audioflinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
4147*ec779b8eSAndroid Build Coastguard Worker                                     audio_session_t triggerSession,
4148*ec779b8eSAndroid Build Coastguard Worker                                     audio_session_t listenerSession,
4149*ec779b8eSAndroid Build Coastguard Worker                                     const audioflinger::SyncEventCallback& callBack,
4150*ec779b8eSAndroid Build Coastguard Worker                                     const wp<IAfTrackBase>& cookie)
4151*ec779b8eSAndroid Build Coastguard Worker {
4152*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4153*ec779b8eSAndroid Build Coastguard Worker 
4154*ec779b8eSAndroid Build Coastguard Worker     auto event = sp<audioflinger::SyncEvent>::make(
4155*ec779b8eSAndroid Build Coastguard Worker             type, triggerSession, listenerSession, callBack, cookie);
4156*ec779b8eSAndroid Build Coastguard Worker     status_t playStatus = NAME_NOT_FOUND;
4157*ec779b8eSAndroid Build Coastguard Worker     status_t recStatus = NAME_NOT_FOUND;
4158*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
4159*ec779b8eSAndroid Build Coastguard Worker         playStatus = mPlaybackThreads.valueAt(i)->setSyncEvent(event);
4160*ec779b8eSAndroid Build Coastguard Worker         if (playStatus == NO_ERROR) {
4161*ec779b8eSAndroid Build Coastguard Worker             return event;
4162*ec779b8eSAndroid Build Coastguard Worker         }
4163*ec779b8eSAndroid Build Coastguard Worker     }
4164*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mRecordThreads.size(); i++) {
4165*ec779b8eSAndroid Build Coastguard Worker         recStatus = mRecordThreads.valueAt(i)->setSyncEvent(event);
4166*ec779b8eSAndroid Build Coastguard Worker         if (recStatus == NO_ERROR) {
4167*ec779b8eSAndroid Build Coastguard Worker             return event;
4168*ec779b8eSAndroid Build Coastguard Worker         }
4169*ec779b8eSAndroid Build Coastguard Worker     }
4170*ec779b8eSAndroid Build Coastguard Worker     if (playStatus == NAME_NOT_FOUND || recStatus == NAME_NOT_FOUND) {
4171*ec779b8eSAndroid Build Coastguard Worker         mPendingSyncEvents.emplace_back(event);
4172*ec779b8eSAndroid Build Coastguard Worker     } else {
4173*ec779b8eSAndroid Build Coastguard Worker         ALOGV("createSyncEvent() invalid event %d", event->type());
4174*ec779b8eSAndroid Build Coastguard Worker         event.clear();
4175*ec779b8eSAndroid Build Coastguard Worker     }
4176*ec779b8eSAndroid Build Coastguard Worker     return event;
4177*ec779b8eSAndroid Build Coastguard Worker }
4178*ec779b8eSAndroid Build Coastguard Worker 
4179*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4180*ec779b8eSAndroid Build Coastguard Worker //  Effect management
4181*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4182*ec779b8eSAndroid Build Coastguard Worker 
getEffectsFactory()4183*ec779b8eSAndroid Build Coastguard Worker sp<EffectsFactoryHalInterface> AudioFlinger::getEffectsFactory() {
4184*ec779b8eSAndroid Build Coastguard Worker     return mEffectsFactoryHal;
4185*ec779b8eSAndroid Build Coastguard Worker }
4186*ec779b8eSAndroid Build Coastguard Worker 
queryNumberEffects(uint32_t * numEffects) const4187*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
4188*ec779b8eSAndroid Build Coastguard Worker {
4189*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4190*ec779b8eSAndroid Build Coastguard Worker     if (mEffectsFactoryHal.get()) {
4191*ec779b8eSAndroid Build Coastguard Worker         return mEffectsFactoryHal->queryNumberEffects(numEffects);
4192*ec779b8eSAndroid Build Coastguard Worker     } else {
4193*ec779b8eSAndroid Build Coastguard Worker         return -ENODEV;
4194*ec779b8eSAndroid Build Coastguard Worker     }
4195*ec779b8eSAndroid Build Coastguard Worker }
4196*ec779b8eSAndroid Build Coastguard Worker 
queryEffect(uint32_t index,effect_descriptor_t * descriptor) const4197*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
4198*ec779b8eSAndroid Build Coastguard Worker {
4199*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4200*ec779b8eSAndroid Build Coastguard Worker     if (mEffectsFactoryHal.get()) {
4201*ec779b8eSAndroid Build Coastguard Worker         return mEffectsFactoryHal->getDescriptor(index, descriptor);
4202*ec779b8eSAndroid Build Coastguard Worker     } else {
4203*ec779b8eSAndroid Build Coastguard Worker         return -ENODEV;
4204*ec779b8eSAndroid Build Coastguard Worker     }
4205*ec779b8eSAndroid Build Coastguard Worker }
4206*ec779b8eSAndroid Build Coastguard Worker 
getEffectDescriptor(const effect_uuid_t * pUuid,const effect_uuid_t * pTypeUuid,uint32_t preferredTypeFlag,effect_descriptor_t * descriptor) const4207*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
4208*ec779b8eSAndroid Build Coastguard Worker                                            const effect_uuid_t *pTypeUuid,
4209*ec779b8eSAndroid Build Coastguard Worker                                            uint32_t preferredTypeFlag,
4210*ec779b8eSAndroid Build Coastguard Worker                                            effect_descriptor_t *descriptor) const
4211*ec779b8eSAndroid Build Coastguard Worker {
4212*ec779b8eSAndroid Build Coastguard Worker     if (pUuid == NULL || pTypeUuid == NULL || descriptor == NULL) {
4213*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
4214*ec779b8eSAndroid Build Coastguard Worker     }
4215*ec779b8eSAndroid Build Coastguard Worker 
4216*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4217*ec779b8eSAndroid Build Coastguard Worker 
4218*ec779b8eSAndroid Build Coastguard Worker     if (!mEffectsFactoryHal.get()) {
4219*ec779b8eSAndroid Build Coastguard Worker         return -ENODEV;
4220*ec779b8eSAndroid Build Coastguard Worker     }
4221*ec779b8eSAndroid Build Coastguard Worker 
4222*ec779b8eSAndroid Build Coastguard Worker     status_t status = NO_ERROR;
4223*ec779b8eSAndroid Build Coastguard Worker     if (!EffectsFactoryHalInterface::isNullUuid(pUuid)) {
4224*ec779b8eSAndroid Build Coastguard Worker         // If uuid is specified, request effect descriptor from that.
4225*ec779b8eSAndroid Build Coastguard Worker         status = mEffectsFactoryHal->getDescriptor(pUuid, descriptor);
4226*ec779b8eSAndroid Build Coastguard Worker     } else if (!EffectsFactoryHalInterface::isNullUuid(pTypeUuid)) {
4227*ec779b8eSAndroid Build Coastguard Worker         // If uuid is not specified, look for an available implementation
4228*ec779b8eSAndroid Build Coastguard Worker         // of the required type instead.
4229*ec779b8eSAndroid Build Coastguard Worker 
4230*ec779b8eSAndroid Build Coastguard Worker         // Use a temporary descriptor to avoid modifying |descriptor| in the failure case.
4231*ec779b8eSAndroid Build Coastguard Worker         effect_descriptor_t desc;
4232*ec779b8eSAndroid Build Coastguard Worker         desc.flags = 0; // prevent compiler warning
4233*ec779b8eSAndroid Build Coastguard Worker 
4234*ec779b8eSAndroid Build Coastguard Worker         uint32_t numEffects = 0;
4235*ec779b8eSAndroid Build Coastguard Worker         status = mEffectsFactoryHal->queryNumberEffects(&numEffects);
4236*ec779b8eSAndroid Build Coastguard Worker         if (status < 0) {
4237*ec779b8eSAndroid Build Coastguard Worker             ALOGW("getEffectDescriptor() error %d from FactoryHal queryNumberEffects", status);
4238*ec779b8eSAndroid Build Coastguard Worker             return status;
4239*ec779b8eSAndroid Build Coastguard Worker         }
4240*ec779b8eSAndroid Build Coastguard Worker 
4241*ec779b8eSAndroid Build Coastguard Worker         bool found = false;
4242*ec779b8eSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < numEffects; i++) {
4243*ec779b8eSAndroid Build Coastguard Worker             status = mEffectsFactoryHal->getDescriptor(i, &desc);
4244*ec779b8eSAndroid Build Coastguard Worker             if (status < 0) {
4245*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("getEffectDescriptor() error %d from FactoryHal getDescriptor", status);
4246*ec779b8eSAndroid Build Coastguard Worker                 continue;
4247*ec779b8eSAndroid Build Coastguard Worker             }
4248*ec779b8eSAndroid Build Coastguard Worker             if (memcmp(&desc.type, pTypeUuid, sizeof(effect_uuid_t)) == 0) {
4249*ec779b8eSAndroid Build Coastguard Worker                 // If matching type found save effect descriptor.
4250*ec779b8eSAndroid Build Coastguard Worker                 found = true;
4251*ec779b8eSAndroid Build Coastguard Worker                 *descriptor = desc;
4252*ec779b8eSAndroid Build Coastguard Worker 
4253*ec779b8eSAndroid Build Coastguard Worker                 // If there's no preferred flag or this descriptor matches the preferred
4254*ec779b8eSAndroid Build Coastguard Worker                 // flag, success! If this descriptor doesn't match the preferred
4255*ec779b8eSAndroid Build Coastguard Worker                 // flag, continue enumeration in case a better matching version of this
4256*ec779b8eSAndroid Build Coastguard Worker                 // effect type is available. Note that this means if no effect with a
4257*ec779b8eSAndroid Build Coastguard Worker                 // correct flag is found, the descriptor returned will correspond to the
4258*ec779b8eSAndroid Build Coastguard Worker                 // last effect that at least had a matching type uuid (if any).
4259*ec779b8eSAndroid Build Coastguard Worker                 if (preferredTypeFlag == EFFECT_FLAG_TYPE_MASK ||
4260*ec779b8eSAndroid Build Coastguard Worker                     (desc.flags & EFFECT_FLAG_TYPE_MASK) == preferredTypeFlag) {
4261*ec779b8eSAndroid Build Coastguard Worker                     break;
4262*ec779b8eSAndroid Build Coastguard Worker                 }
4263*ec779b8eSAndroid Build Coastguard Worker             }
4264*ec779b8eSAndroid Build Coastguard Worker         }
4265*ec779b8eSAndroid Build Coastguard Worker 
4266*ec779b8eSAndroid Build Coastguard Worker         if (!found) {
4267*ec779b8eSAndroid Build Coastguard Worker             status = NAME_NOT_FOUND;
4268*ec779b8eSAndroid Build Coastguard Worker             ALOGW("getEffectDescriptor(): Effect not found by type.");
4269*ec779b8eSAndroid Build Coastguard Worker         }
4270*ec779b8eSAndroid Build Coastguard Worker     } else {
4271*ec779b8eSAndroid Build Coastguard Worker         status = BAD_VALUE;
4272*ec779b8eSAndroid Build Coastguard Worker         ALOGE("getEffectDescriptor(): Either uuid or type uuid must be non-null UUIDs.");
4273*ec779b8eSAndroid Build Coastguard Worker     }
4274*ec779b8eSAndroid Build Coastguard Worker     return status;
4275*ec779b8eSAndroid Build Coastguard Worker }
4276*ec779b8eSAndroid Build Coastguard Worker 
createEffect(const media::CreateEffectRequest & request,media::CreateEffectResponse * response)4277*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
4278*ec779b8eSAndroid Build Coastguard Worker                                     media::CreateEffectResponse* response) {
4279*ec779b8eSAndroid Build Coastguard Worker     const sp<IEffectClient>& effectClient = request.client;
4280*ec779b8eSAndroid Build Coastguard Worker     const int32_t priority = request.priority;
4281*ec779b8eSAndroid Build Coastguard Worker     const AudioDeviceTypeAddr device = VALUE_OR_RETURN_STATUS(
4282*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_AudioDeviceTypeAddress(request.device));
4283*ec779b8eSAndroid Build Coastguard Worker     AttributionSourceState adjAttributionSource = request.attributionSource;
4284*ec779b8eSAndroid Build Coastguard Worker     const audio_session_t sessionId = VALUE_OR_RETURN_STATUS(
4285*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_int32_t_audio_session_t(request.sessionId));
4286*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t io = VALUE_OR_RETURN_STATUS(
4287*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_int32_t_audio_io_handle_t(request.output));
4288*ec779b8eSAndroid Build Coastguard Worker     const effect_descriptor_t descIn = VALUE_OR_RETURN_STATUS(
4289*ec779b8eSAndroid Build Coastguard Worker             aidl2legacy_EffectDescriptor_effect_descriptor_t(request.desc));
4290*ec779b8eSAndroid Build Coastguard Worker     const bool probe = request.probe;
4291*ec779b8eSAndroid Build Coastguard Worker 
4292*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectHandle> handle;
4293*ec779b8eSAndroid Build Coastguard Worker     effect_descriptor_t descOut;
4294*ec779b8eSAndroid Build Coastguard Worker     int enabledOut = 0;
4295*ec779b8eSAndroid Build Coastguard Worker     int idOut = -1;
4296*ec779b8eSAndroid Build Coastguard Worker 
4297*ec779b8eSAndroid Build Coastguard Worker     status_t lStatus = NO_ERROR;
4298*ec779b8eSAndroid Build Coastguard Worker     uid_t callingUid = IPCThreadState::self()->getCallingUid();
4299*ec779b8eSAndroid Build Coastguard Worker     pid_t currentPid;
4300*ec779b8eSAndroid Build Coastguard Worker     if (!com::android::media::audio::audioserver_permissions()) {
4301*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
4302*ec779b8eSAndroid Build Coastguard Worker         currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid));
4303*ec779b8eSAndroid Build Coastguard Worker         if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
4304*ec779b8eSAndroid Build Coastguard Worker             const pid_t callingPid = IPCThreadState::self()->getCallingPid();
4305*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(currentPid != -1 && currentPid != callingPid,
4306*ec779b8eSAndroid Build Coastguard Worker                      "%s uid %d pid %d tried to pass itself off as pid %d",
4307*ec779b8eSAndroid Build Coastguard Worker                      __func__, callingUid, callingPid, currentPid);
4308*ec779b8eSAndroid Build Coastguard Worker             adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
4309*ec779b8eSAndroid Build Coastguard Worker                     legacy2aidl_pid_t_int32_t(callingPid));
4310*ec779b8eSAndroid Build Coastguard Worker             currentPid = callingPid;
4311*ec779b8eSAndroid Build Coastguard Worker         }
4312*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource);
4313*ec779b8eSAndroid Build Coastguard Worker     } else {
4314*ec779b8eSAndroid Build Coastguard Worker         auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
4315*ec779b8eSAndroid Build Coastguard Worker                 validateAttributionFromContextOrTrustedCaller(request.attributionSource,
4316*ec779b8eSAndroid Build Coastguard Worker                 getPermissionProvider()
4317*ec779b8eSAndroid Build Coastguard Worker                 ));
4318*ec779b8eSAndroid Build Coastguard Worker         // TODO pass wrapped object around
4319*ec779b8eSAndroid Build Coastguard Worker         adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
4320*ec779b8eSAndroid Build Coastguard Worker         currentPid = adjAttributionSource.pid;
4321*ec779b8eSAndroid Build Coastguard Worker     }
4322*ec779b8eSAndroid Build Coastguard Worker 
4323*ec779b8eSAndroid Build Coastguard Worker 
4324*ec779b8eSAndroid Build Coastguard Worker     ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
4325*ec779b8eSAndroid Build Coastguard Worker           adjAttributionSource.pid, effectClient.get(), priority, sessionId, io,
4326*ec779b8eSAndroid Build Coastguard Worker           mEffectsFactoryHal.get());
4327*ec779b8eSAndroid Build Coastguard Worker 
4328*ec779b8eSAndroid Build Coastguard Worker     if (mEffectsFactoryHal == 0) {
4329*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: no effects factory hal", __func__);
4330*ec779b8eSAndroid Build Coastguard Worker         lStatus = NO_INIT;
4331*ec779b8eSAndroid Build Coastguard Worker         goto Exit;
4332*ec779b8eSAndroid Build Coastguard Worker     }
4333*ec779b8eSAndroid Build Coastguard Worker 
4334*ec779b8eSAndroid Build Coastguard Worker     // check audio settings permission for global effects
4335*ec779b8eSAndroid Build Coastguard Worker     if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
4336*ec779b8eSAndroid Build Coastguard Worker         if (!settingsAllowed()) {
4337*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: no permission for AUDIO_SESSION_OUTPUT_MIX", __func__);
4338*ec779b8eSAndroid Build Coastguard Worker             lStatus = PERMISSION_DENIED;
4339*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4340*ec779b8eSAndroid Build Coastguard Worker         }
4341*ec779b8eSAndroid Build Coastguard Worker     } else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
4342*ec779b8eSAndroid Build Coastguard Worker         if (io == AUDIO_IO_HANDLE_NONE) {
4343*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: APM must specify output when using AUDIO_SESSION_OUTPUT_STAGE", __func__);
4344*ec779b8eSAndroid Build Coastguard Worker             lStatus = BAD_VALUE;
4345*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4346*ec779b8eSAndroid Build Coastguard Worker         }
4347*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* thread;
4348*ec779b8eSAndroid Build Coastguard Worker         {
4349*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard l(mutex());
4350*ec779b8eSAndroid Build Coastguard Worker             thread = checkPlaybackThread_l(io);
4351*ec779b8eSAndroid Build Coastguard Worker         }
4352*ec779b8eSAndroid Build Coastguard Worker         if (thread == nullptr) {
4353*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: invalid output %d specified for AUDIO_SESSION_OUTPUT_STAGE", __func__, io);
4354*ec779b8eSAndroid Build Coastguard Worker             lStatus = BAD_VALUE;
4355*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4356*ec779b8eSAndroid Build Coastguard Worker         }
4357*ec779b8eSAndroid Build Coastguard Worker         if (!modifyDefaultAudioEffectsAllowed(adjAttributionSource)
4358*ec779b8eSAndroid Build Coastguard Worker                 && !isAudioServerUid(callingUid)) {
4359*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: effect on AUDIO_SESSION_OUTPUT_STAGE not granted for uid %d",
4360*ec779b8eSAndroid Build Coastguard Worker                     __func__, callingUid);
4361*ec779b8eSAndroid Build Coastguard Worker             lStatus = PERMISSION_DENIED;
4362*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4363*ec779b8eSAndroid Build Coastguard Worker         }
4364*ec779b8eSAndroid Build Coastguard Worker     } else if (sessionId == AUDIO_SESSION_DEVICE) {
4365*ec779b8eSAndroid Build Coastguard Worker         if (!modifyDefaultAudioEffectsAllowed(adjAttributionSource)) {
4366*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: device effect permission denied for uid %d", __func__, callingUid);
4367*ec779b8eSAndroid Build Coastguard Worker             lStatus = PERMISSION_DENIED;
4368*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4369*ec779b8eSAndroid Build Coastguard Worker         }
4370*ec779b8eSAndroid Build Coastguard Worker         if (io != AUDIO_IO_HANDLE_NONE) {
4371*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: io handle should not be specified for device effect", __func__);
4372*ec779b8eSAndroid Build Coastguard Worker             lStatus = BAD_VALUE;
4373*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4374*ec779b8eSAndroid Build Coastguard Worker         }
4375*ec779b8eSAndroid Build Coastguard Worker     } else {
4376*ec779b8eSAndroid Build Coastguard Worker         // general sessionId.
4377*ec779b8eSAndroid Build Coastguard Worker 
4378*ec779b8eSAndroid Build Coastguard Worker         if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
4379*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: invalid sessionId %d", __func__, sessionId);
4380*ec779b8eSAndroid Build Coastguard Worker             lStatus = BAD_VALUE;
4381*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4382*ec779b8eSAndroid Build Coastguard Worker         }
4383*ec779b8eSAndroid Build Coastguard Worker 
4384*ec779b8eSAndroid Build Coastguard Worker         // TODO: should we check if the callingUid (limited to pid) is in mAudioSessionRefs
4385*ec779b8eSAndroid Build Coastguard Worker         // to prevent creating an effect when one doesn't actually have track with that session?
4386*ec779b8eSAndroid Build Coastguard Worker     }
4387*ec779b8eSAndroid Build Coastguard Worker 
4388*ec779b8eSAndroid Build Coastguard Worker     {
4389*ec779b8eSAndroid Build Coastguard Worker         // Get the full effect descriptor from the uuid/type.
4390*ec779b8eSAndroid Build Coastguard Worker         // If the session is the output mix, prefer an auxiliary effect,
4391*ec779b8eSAndroid Build Coastguard Worker         // otherwise no preference.
4392*ec779b8eSAndroid Build Coastguard Worker         uint32_t preferredType = (sessionId == AUDIO_SESSION_OUTPUT_MIX ?
4393*ec779b8eSAndroid Build Coastguard Worker                                   EFFECT_FLAG_TYPE_AUXILIARY : EFFECT_FLAG_TYPE_MASK);
4394*ec779b8eSAndroid Build Coastguard Worker         lStatus = getEffectDescriptor(&descIn.uuid, &descIn.type, preferredType, &descOut);
4395*ec779b8eSAndroid Build Coastguard Worker         if (lStatus < 0) {
4396*ec779b8eSAndroid Build Coastguard Worker             ALOGW("createEffect() error %d from getEffectDescriptor", lStatus);
4397*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4398*ec779b8eSAndroid Build Coastguard Worker         }
4399*ec779b8eSAndroid Build Coastguard Worker 
4400*ec779b8eSAndroid Build Coastguard Worker         // Do not allow auxiliary effects on a session different from 0 (output mix)
4401*ec779b8eSAndroid Build Coastguard Worker         if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
4402*ec779b8eSAndroid Build Coastguard Worker              (descOut.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
4403*ec779b8eSAndroid Build Coastguard Worker             lStatus = INVALID_OPERATION;
4404*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4405*ec779b8eSAndroid Build Coastguard Worker         }
4406*ec779b8eSAndroid Build Coastguard Worker 
4407*ec779b8eSAndroid Build Coastguard Worker         // check recording permission for visualizer
4408*ec779b8eSAndroid Build Coastguard Worker         if ((memcmp(&descOut.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
4409*ec779b8eSAndroid Build Coastguard Worker             // TODO: Do we need to start/stop op - i.e. is there recording being performed?
4410*ec779b8eSAndroid Build Coastguard Worker             !recordingAllowed(adjAttributionSource)) {
4411*ec779b8eSAndroid Build Coastguard Worker             lStatus = PERMISSION_DENIED;
4412*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4413*ec779b8eSAndroid Build Coastguard Worker         }
4414*ec779b8eSAndroid Build Coastguard Worker 
4415*ec779b8eSAndroid Build Coastguard Worker         const bool hapticPlaybackRequired = IAfEffectModule::isHapticGenerator(&descOut.type);
4416*ec779b8eSAndroid Build Coastguard Worker         if (hapticPlaybackRequired
4417*ec779b8eSAndroid Build Coastguard Worker                 && (sessionId == AUDIO_SESSION_DEVICE
4418*ec779b8eSAndroid Build Coastguard Worker                         || sessionId == AUDIO_SESSION_OUTPUT_MIX
4419*ec779b8eSAndroid Build Coastguard Worker                         || sessionId == AUDIO_SESSION_OUTPUT_STAGE)) {
4420*ec779b8eSAndroid Build Coastguard Worker             // haptic-generating effect is only valid when the session id is a general session id
4421*ec779b8eSAndroid Build Coastguard Worker             lStatus = INVALID_OPERATION;
4422*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4423*ec779b8eSAndroid Build Coastguard Worker         }
4424*ec779b8eSAndroid Build Coastguard Worker 
4425*ec779b8eSAndroid Build Coastguard Worker         // Only audio policy service can create a spatializer effect
4426*ec779b8eSAndroid Build Coastguard Worker         if (IAfEffectModule::isSpatializer(&descOut.type) &&
4427*ec779b8eSAndroid Build Coastguard Worker             (callingUid != AID_AUDIOSERVER || currentPid != getpid())) {
4428*ec779b8eSAndroid Build Coastguard Worker             ALOGW("%s: attempt to create a spatializer effect from uid/pid %d/%d",
4429*ec779b8eSAndroid Build Coastguard Worker                     __func__, callingUid, currentPid);
4430*ec779b8eSAndroid Build Coastguard Worker             lStatus = PERMISSION_DENIED;
4431*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4432*ec779b8eSAndroid Build Coastguard Worker         }
4433*ec779b8eSAndroid Build Coastguard Worker 
4434*ec779b8eSAndroid Build Coastguard Worker         if (io == AUDIO_IO_HANDLE_NONE && sessionId == AUDIO_SESSION_OUTPUT_MIX) {
4435*ec779b8eSAndroid Build Coastguard Worker             // if the output returned by getOutputForEffect() is removed before we lock the
4436*ec779b8eSAndroid Build Coastguard Worker             // mutex below, the call to checkPlaybackThread_l(io) below will detect it
4437*ec779b8eSAndroid Build Coastguard Worker             // and we will exit safely
4438*ec779b8eSAndroid Build Coastguard Worker             io = AudioSystem::getOutputForEffect(&descOut);
4439*ec779b8eSAndroid Build Coastguard Worker             ALOGV("createEffect got output %d", io);
4440*ec779b8eSAndroid Build Coastguard Worker         }
4441*ec779b8eSAndroid Build Coastguard Worker 
4442*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
4443*ec779b8eSAndroid Build Coastguard Worker 
4444*ec779b8eSAndroid Build Coastguard Worker         if (sessionId == AUDIO_SESSION_DEVICE) {
4445*ec779b8eSAndroid Build Coastguard Worker             sp<Client> client = registerClient(currentPid, adjAttributionSource.uid);
4446*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s device type %#x address %s", __func__, device.mType, device.getAddress());
4447*ec779b8eSAndroid Build Coastguard Worker             handle = mDeviceEffectManager->createEffect_l(
4448*ec779b8eSAndroid Build Coastguard Worker                     &descOut, device, client, effectClient, mPatchPanel->patches_l(),
4449*ec779b8eSAndroid Build Coastguard Worker                     &enabledOut, &lStatus, probe, request.notifyFramesProcessed);
4450*ec779b8eSAndroid Build Coastguard Worker             if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
4451*ec779b8eSAndroid Build Coastguard Worker                 // remove local strong reference to Client with clientMutex() held
4452*ec779b8eSAndroid Build Coastguard Worker                 audio_utils::lock_guard _cl(clientMutex());
4453*ec779b8eSAndroid Build Coastguard Worker                 client.clear();
4454*ec779b8eSAndroid Build Coastguard Worker             } else {
4455*ec779b8eSAndroid Build Coastguard Worker                 // handle must be valid here, but check again to be safe.
4456*ec779b8eSAndroid Build Coastguard Worker                 if (handle.get() != nullptr) idOut = handle->id();
4457*ec779b8eSAndroid Build Coastguard Worker             }
4458*ec779b8eSAndroid Build Coastguard Worker             goto Register;
4459*ec779b8eSAndroid Build Coastguard Worker         }
4460*ec779b8eSAndroid Build Coastguard Worker 
4461*ec779b8eSAndroid Build Coastguard Worker         // If output is not specified try to find a matching audio session ID in one of the
4462*ec779b8eSAndroid Build Coastguard Worker         // output threads.
4463*ec779b8eSAndroid Build Coastguard Worker         // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
4464*ec779b8eSAndroid Build Coastguard Worker         // because of code checking output when entering the function.
4465*ec779b8eSAndroid Build Coastguard Worker         // Note: io is never AUDIO_IO_HANDLE_NONE when creating an effect on an input by APM.
4466*ec779b8eSAndroid Build Coastguard Worker         // An AudioEffect created from the Java API will have io as AUDIO_IO_HANDLE_NONE.
4467*ec779b8eSAndroid Build Coastguard Worker         if (io == AUDIO_IO_HANDLE_NONE) {
4468*ec779b8eSAndroid Build Coastguard Worker             // look for the thread where the specified audio session is present
4469*ec779b8eSAndroid Build Coastguard Worker             io = findIoHandleBySessionId_l(sessionId, mPlaybackThreads);
4470*ec779b8eSAndroid Build Coastguard Worker             if (io == AUDIO_IO_HANDLE_NONE) {
4471*ec779b8eSAndroid Build Coastguard Worker                 io = findIoHandleBySessionId_l(sessionId, mRecordThreads);
4472*ec779b8eSAndroid Build Coastguard Worker             }
4473*ec779b8eSAndroid Build Coastguard Worker             if (io == AUDIO_IO_HANDLE_NONE) {
4474*ec779b8eSAndroid Build Coastguard Worker                 io = findIoHandleBySessionId_l(sessionId, mMmapThreads);
4475*ec779b8eSAndroid Build Coastguard Worker             }
4476*ec779b8eSAndroid Build Coastguard Worker 
4477*ec779b8eSAndroid Build Coastguard Worker             // If you wish to create a Record preprocessing AudioEffect in Java,
4478*ec779b8eSAndroid Build Coastguard Worker             // you MUST create an AudioRecord first and keep it alive so it is picked up above.
4479*ec779b8eSAndroid Build Coastguard Worker             // Otherwise it will fail when created on a Playback thread by legacy
4480*ec779b8eSAndroid Build Coastguard Worker             // handling below.  Ditto with Mmap, the associated Mmap track must be created
4481*ec779b8eSAndroid Build Coastguard Worker             // before creating the AudioEffect or the io handle must be specified.
4482*ec779b8eSAndroid Build Coastguard Worker             //
4483*ec779b8eSAndroid Build Coastguard Worker             // Detect if the effect is created after an AudioRecord is destroyed.
4484*ec779b8eSAndroid Build Coastguard Worker             if (sessionId != AUDIO_SESSION_OUTPUT_MIX
4485*ec779b8eSAndroid Build Coastguard Worker                   && ((descOut.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)
4486*ec779b8eSAndroid Build Coastguard Worker                   && getOrphanEffectChain_l(sessionId).get() != nullptr) {
4487*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: effect %s with no specified io handle is denied because the AudioRecord"
4488*ec779b8eSAndroid Build Coastguard Worker                       " for session %d no longer exists",
4489*ec779b8eSAndroid Build Coastguard Worker                       __func__, descOut.name, sessionId);
4490*ec779b8eSAndroid Build Coastguard Worker                 lStatus = PERMISSION_DENIED;
4491*ec779b8eSAndroid Build Coastguard Worker                 goto Exit;
4492*ec779b8eSAndroid Build Coastguard Worker             }
4493*ec779b8eSAndroid Build Coastguard Worker 
4494*ec779b8eSAndroid Build Coastguard Worker             // Legacy handling of creating an effect on an expired or made-up
4495*ec779b8eSAndroid Build Coastguard Worker             // session id.  We think that it is a Playback effect.
4496*ec779b8eSAndroid Build Coastguard Worker             //
4497*ec779b8eSAndroid Build Coastguard Worker             // If no output thread contains the requested session ID, park the effect to
4498*ec779b8eSAndroid Build Coastguard Worker             // the orphan chains. The effect chain will be moved to the correct output
4499*ec779b8eSAndroid Build Coastguard Worker             // thread when a track with the same session ID is created.
4500*ec779b8eSAndroid Build Coastguard Worker             if (io == AUDIO_IO_HANDLE_NONE) {
4501*ec779b8eSAndroid Build Coastguard Worker                 if (probe) {
4502*ec779b8eSAndroid Build Coastguard Worker                     // In probe mode, as no compatible thread found, exit with error.
4503*ec779b8eSAndroid Build Coastguard Worker                     lStatus = BAD_VALUE;
4504*ec779b8eSAndroid Build Coastguard Worker                     goto Exit;
4505*ec779b8eSAndroid Build Coastguard Worker                 }
4506*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("%s() got io %d for effect %s", __func__, io, descOut.name);
4507*ec779b8eSAndroid Build Coastguard Worker                 sp<Client> client = registerClient(currentPid, adjAttributionSource.uid);
4508*ec779b8eSAndroid Build Coastguard Worker                 bool pinned = !audio_is_global_session(sessionId) && isSessionAcquired_l(sessionId);
4509*ec779b8eSAndroid Build Coastguard Worker                 handle = createOrphanEffect_l(client, effectClient, priority, sessionId,
4510*ec779b8eSAndroid Build Coastguard Worker                                               &descOut, &enabledOut, &lStatus, pinned,
4511*ec779b8eSAndroid Build Coastguard Worker                                               request.notifyFramesProcessed);
4512*ec779b8eSAndroid Build Coastguard Worker                 if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
4513*ec779b8eSAndroid Build Coastguard Worker                     // remove local strong reference to Client with clientMutex() held
4514*ec779b8eSAndroid Build Coastguard Worker                     audio_utils::lock_guard _cl(clientMutex());
4515*ec779b8eSAndroid Build Coastguard Worker                     client.clear();
4516*ec779b8eSAndroid Build Coastguard Worker                 }
4517*ec779b8eSAndroid Build Coastguard Worker                 goto Register;
4518*ec779b8eSAndroid Build Coastguard Worker             }
4519*ec779b8eSAndroid Build Coastguard Worker             ALOGV("createEffect() got io %d for effect %s", io, descOut.name);
4520*ec779b8eSAndroid Build Coastguard Worker         } else if (checkPlaybackThread_l(io) != nullptr
4521*ec779b8eSAndroid Build Coastguard Worker                         && sessionId != AUDIO_SESSION_OUTPUT_STAGE) {
4522*ec779b8eSAndroid Build Coastguard Worker             // allow only one effect chain per sessionId on mPlaybackThreads.
4523*ec779b8eSAndroid Build Coastguard Worker             for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
4524*ec779b8eSAndroid Build Coastguard Worker                 const audio_io_handle_t checkIo = mPlaybackThreads.keyAt(i);
4525*ec779b8eSAndroid Build Coastguard Worker                 if (io == checkIo) {
4526*ec779b8eSAndroid Build Coastguard Worker                     if (hapticPlaybackRequired
4527*ec779b8eSAndroid Build Coastguard Worker                             && mPlaybackThreads.valueAt(i)
4528*ec779b8eSAndroid Build Coastguard Worker                                     ->hapticChannelMask() == AUDIO_CHANNEL_NONE) {
4529*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("%s: haptic playback thread is required while the required playback "
4530*ec779b8eSAndroid Build Coastguard Worker                               "thread(io=%d) doesn't support", __func__, (int)io);
4531*ec779b8eSAndroid Build Coastguard Worker                         lStatus = BAD_VALUE;
4532*ec779b8eSAndroid Build Coastguard Worker                         goto Exit;
4533*ec779b8eSAndroid Build Coastguard Worker                     }
4534*ec779b8eSAndroid Build Coastguard Worker                     continue;
4535*ec779b8eSAndroid Build Coastguard Worker                 }
4536*ec779b8eSAndroid Build Coastguard Worker                 const uint32_t sessionType =
4537*ec779b8eSAndroid Build Coastguard Worker                         mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
4538*ec779b8eSAndroid Build Coastguard Worker                 if ((sessionType & IAfThreadBase::EFFECT_SESSION) != 0) {
4539*ec779b8eSAndroid Build Coastguard Worker                     ALOGE("%s: effect %s io %d denied because session %d effect exists on io %d",
4540*ec779b8eSAndroid Build Coastguard Worker                           __func__, descOut.name, (int) io, (int) sessionId, (int) checkIo);
4541*ec779b8eSAndroid Build Coastguard Worker                     android_errorWriteLog(0x534e4554, "123237974");
4542*ec779b8eSAndroid Build Coastguard Worker                     lStatus = BAD_VALUE;
4543*ec779b8eSAndroid Build Coastguard Worker                     goto Exit;
4544*ec779b8eSAndroid Build Coastguard Worker                 }
4545*ec779b8eSAndroid Build Coastguard Worker             }
4546*ec779b8eSAndroid Build Coastguard Worker         }
4547*ec779b8eSAndroid Build Coastguard Worker         IAfThreadBase* thread = checkRecordThread_l(io);
4548*ec779b8eSAndroid Build Coastguard Worker         if (thread == NULL) {
4549*ec779b8eSAndroid Build Coastguard Worker             thread = checkPlaybackThread_l(io);
4550*ec779b8eSAndroid Build Coastguard Worker             if (thread == NULL) {
4551*ec779b8eSAndroid Build Coastguard Worker                 thread = checkMmapThread_l(io);
4552*ec779b8eSAndroid Build Coastguard Worker                 if (thread == NULL) {
4553*ec779b8eSAndroid Build Coastguard Worker                     ALOGE("createEffect() unknown output thread");
4554*ec779b8eSAndroid Build Coastguard Worker                     lStatus = BAD_VALUE;
4555*ec779b8eSAndroid Build Coastguard Worker                     goto Exit;
4556*ec779b8eSAndroid Build Coastguard Worker                 }
4557*ec779b8eSAndroid Build Coastguard Worker             }
4558*ec779b8eSAndroid Build Coastguard Worker         }
4559*ec779b8eSAndroid Build Coastguard Worker         if (thread->type() == IAfThreadBase::RECORD || sessionId == AUDIO_SESSION_OUTPUT_MIX) {
4560*ec779b8eSAndroid Build Coastguard Worker             // Check if one effect chain was awaiting for an effect to be created on this
4561*ec779b8eSAndroid Build Coastguard Worker             // session and used it instead of creating a new one.
4562*ec779b8eSAndroid Build Coastguard Worker             sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
4563*ec779b8eSAndroid Build Coastguard Worker             if (chain != 0) {
4564*ec779b8eSAndroid Build Coastguard Worker                 audio_utils::lock_guard _l2(thread->mutex());
4565*ec779b8eSAndroid Build Coastguard Worker                 thread->addEffectChain_l(chain);
4566*ec779b8eSAndroid Build Coastguard Worker             }
4567*ec779b8eSAndroid Build Coastguard Worker         }
4568*ec779b8eSAndroid Build Coastguard Worker 
4569*ec779b8eSAndroid Build Coastguard Worker         sp<Client> client = registerClient(currentPid, adjAttributionSource.uid);
4570*ec779b8eSAndroid Build Coastguard Worker 
4571*ec779b8eSAndroid Build Coastguard Worker         // create effect on selected output thread
4572*ec779b8eSAndroid Build Coastguard Worker         bool pinned = !audio_is_global_session(sessionId) && isSessionAcquired_l(sessionId);
4573*ec779b8eSAndroid Build Coastguard Worker         IAfThreadBase* oriThread = nullptr;
4574*ec779b8eSAndroid Build Coastguard Worker         if (hapticPlaybackRequired && thread->hapticChannelMask() == AUDIO_CHANNEL_NONE) {
4575*ec779b8eSAndroid Build Coastguard Worker             IAfThreadBase* const hapticThread = hapticPlaybackThread_l();
4576*ec779b8eSAndroid Build Coastguard Worker             if (hapticThread == nullptr) {
4577*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s haptic thread not found while it is required", __func__);
4578*ec779b8eSAndroid Build Coastguard Worker                 lStatus = INVALID_OPERATION;
4579*ec779b8eSAndroid Build Coastguard Worker                 goto Exit;
4580*ec779b8eSAndroid Build Coastguard Worker             }
4581*ec779b8eSAndroid Build Coastguard Worker             if (hapticThread != thread) {
4582*ec779b8eSAndroid Build Coastguard Worker                 // Force to use haptic thread for haptic-generating effect.
4583*ec779b8eSAndroid Build Coastguard Worker                 oriThread = thread;
4584*ec779b8eSAndroid Build Coastguard Worker                 thread = hapticThread;
4585*ec779b8eSAndroid Build Coastguard Worker             }
4586*ec779b8eSAndroid Build Coastguard Worker         }
4587*ec779b8eSAndroid Build Coastguard Worker         handle = thread->createEffect_l(client, effectClient, priority, sessionId,
4588*ec779b8eSAndroid Build Coastguard Worker                                         &descOut, &enabledOut, &lStatus, pinned, probe,
4589*ec779b8eSAndroid Build Coastguard Worker                                         request.notifyFramesProcessed);
4590*ec779b8eSAndroid Build Coastguard Worker         if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
4591*ec779b8eSAndroid Build Coastguard Worker             // remove local strong reference to Client with clientMutex() held
4592*ec779b8eSAndroid Build Coastguard Worker             audio_utils::lock_guard _cl(clientMutex());
4593*ec779b8eSAndroid Build Coastguard Worker             client.clear();
4594*ec779b8eSAndroid Build Coastguard Worker         } else {
4595*ec779b8eSAndroid Build Coastguard Worker             // handle must be valid here, but check again to be safe.
4596*ec779b8eSAndroid Build Coastguard Worker             if (handle.get() != nullptr) idOut = handle->id();
4597*ec779b8eSAndroid Build Coastguard Worker             // Invalidate audio session when haptic playback is created.
4598*ec779b8eSAndroid Build Coastguard Worker             if (hapticPlaybackRequired && oriThread != nullptr) {
4599*ec779b8eSAndroid Build Coastguard Worker                 // invalidateTracksForAudioSession will trigger locking the thread.
4600*ec779b8eSAndroid Build Coastguard Worker                 oriThread->invalidateTracksForAudioSession(sessionId);
4601*ec779b8eSAndroid Build Coastguard Worker             }
4602*ec779b8eSAndroid Build Coastguard Worker         }
4603*ec779b8eSAndroid Build Coastguard Worker     }
4604*ec779b8eSAndroid Build Coastguard Worker 
4605*ec779b8eSAndroid Build Coastguard Worker Register:
4606*ec779b8eSAndroid Build Coastguard Worker     if (!probe && (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS)) {
4607*ec779b8eSAndroid Build Coastguard Worker         if (lStatus == ALREADY_EXISTS) {
4608*ec779b8eSAndroid Build Coastguard Worker             response->alreadyExists = true;
4609*ec779b8eSAndroid Build Coastguard Worker             lStatus = NO_ERROR;
4610*ec779b8eSAndroid Build Coastguard Worker         } else {
4611*ec779b8eSAndroid Build Coastguard Worker             response->alreadyExists = false;
4612*ec779b8eSAndroid Build Coastguard Worker         }
4613*ec779b8eSAndroid Build Coastguard Worker         // Check CPU and memory usage
4614*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectBase> effect = handle->effect().promote();
4615*ec779b8eSAndroid Build Coastguard Worker         if (effect != nullptr) {
4616*ec779b8eSAndroid Build Coastguard Worker             status_t rStatus = effect->updatePolicyState();
4617*ec779b8eSAndroid Build Coastguard Worker             if (rStatus != NO_ERROR) {
4618*ec779b8eSAndroid Build Coastguard Worker                 lStatus = rStatus;
4619*ec779b8eSAndroid Build Coastguard Worker             }
4620*ec779b8eSAndroid Build Coastguard Worker         }
4621*ec779b8eSAndroid Build Coastguard Worker     } else {
4622*ec779b8eSAndroid Build Coastguard Worker         handle.clear();
4623*ec779b8eSAndroid Build Coastguard Worker     }
4624*ec779b8eSAndroid Build Coastguard Worker 
4625*ec779b8eSAndroid Build Coastguard Worker     response->id = idOut;
4626*ec779b8eSAndroid Build Coastguard Worker     response->enabled = enabledOut != 0;
4627*ec779b8eSAndroid Build Coastguard Worker     response->effect = handle.get() ? handle->asIEffect() : nullptr;
4628*ec779b8eSAndroid Build Coastguard Worker     response->desc = VALUE_OR_RETURN_STATUS(
4629*ec779b8eSAndroid Build Coastguard Worker             legacy2aidl_effect_descriptor_t_EffectDescriptor(descOut));
4630*ec779b8eSAndroid Build Coastguard Worker 
4631*ec779b8eSAndroid Build Coastguard Worker Exit:
4632*ec779b8eSAndroid Build Coastguard Worker     return lStatus;
4633*ec779b8eSAndroid Build Coastguard Worker }
4634*ec779b8eSAndroid Build Coastguard Worker 
createOrphanEffect_l(const sp<Client> & client,const sp<IEffectClient> & effectClient,int32_t priority,audio_session_t sessionId,effect_descriptor_t * desc,int * enabled,status_t * status,bool pinned,bool notifyFramesProcessed)4635*ec779b8eSAndroid Build Coastguard Worker sp<IAfEffectHandle> AudioFlinger::createOrphanEffect_l(
4636*ec779b8eSAndroid Build Coastguard Worker         const sp<Client>& client,
4637*ec779b8eSAndroid Build Coastguard Worker         const sp<IEffectClient>& effectClient,
4638*ec779b8eSAndroid Build Coastguard Worker         int32_t priority,
4639*ec779b8eSAndroid Build Coastguard Worker         audio_session_t sessionId,
4640*ec779b8eSAndroid Build Coastguard Worker         effect_descriptor_t *desc,
4641*ec779b8eSAndroid Build Coastguard Worker         int *enabled,
4642*ec779b8eSAndroid Build Coastguard Worker         status_t *status,
4643*ec779b8eSAndroid Build Coastguard Worker         bool pinned,
4644*ec779b8eSAndroid Build Coastguard Worker         bool notifyFramesProcessed)
4645*ec779b8eSAndroid Build Coastguard Worker {
4646*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s effectClient %p, priority %d, sessionId %d, factory %p",
4647*ec779b8eSAndroid Build Coastguard Worker           __func__, effectClient.get(), priority, sessionId, mEffectsFactoryHal.get());
4648*ec779b8eSAndroid Build Coastguard Worker 
4649*ec779b8eSAndroid Build Coastguard Worker     // Check if an orphan effect chain exists for this session or create new chain for this session
4650*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectModule> effect;
4651*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
4652*ec779b8eSAndroid Build Coastguard Worker     bool chainCreated = false;
4653*ec779b8eSAndroid Build Coastguard Worker     if (chain == nullptr) {
4654*ec779b8eSAndroid Build Coastguard Worker         chain = IAfEffectChain::create(/* ThreadBase= */ nullptr, sessionId, this);
4655*ec779b8eSAndroid Build Coastguard Worker         chainCreated = true;
4656*ec779b8eSAndroid Build Coastguard Worker     } else {
4657*ec779b8eSAndroid Build Coastguard Worker         effect = chain->getEffectFromDesc(desc);
4658*ec779b8eSAndroid Build Coastguard Worker     }
4659*ec779b8eSAndroid Build Coastguard Worker     bool effectCreated = false;
4660*ec779b8eSAndroid Build Coastguard Worker     if (effect == nullptr) {
4661*ec779b8eSAndroid Build Coastguard Worker         audio_unique_id_t effectId = nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
4662*ec779b8eSAndroid Build Coastguard Worker         // create a new effect module if none present in the chain
4663*ec779b8eSAndroid Build Coastguard Worker         status_t llStatus =
4664*ec779b8eSAndroid Build Coastguard Worker                 chain->createEffect(effect, desc, effectId, sessionId, pinned);
4665*ec779b8eSAndroid Build Coastguard Worker         if (llStatus != NO_ERROR) {
4666*ec779b8eSAndroid Build Coastguard Worker             *status = llStatus;
4667*ec779b8eSAndroid Build Coastguard Worker             // if the effect chain was not created here, put it back
4668*ec779b8eSAndroid Build Coastguard Worker             if (!chainCreated) {
4669*ec779b8eSAndroid Build Coastguard Worker                 putOrphanEffectChain_l(chain);
4670*ec779b8eSAndroid Build Coastguard Worker             }
4671*ec779b8eSAndroid Build Coastguard Worker             return nullptr;
4672*ec779b8eSAndroid Build Coastguard Worker         }
4673*ec779b8eSAndroid Build Coastguard Worker         effect->setMode(getMode());
4674*ec779b8eSAndroid Build Coastguard Worker 
4675*ec779b8eSAndroid Build Coastguard Worker         if (effect->isHapticGenerator()) {
4676*ec779b8eSAndroid Build Coastguard Worker             // TODO(b/184194057): Use the vibrator information from the vibrator that will be used
4677*ec779b8eSAndroid Build Coastguard Worker             // for the HapticGenerator.
4678*ec779b8eSAndroid Build Coastguard Worker             const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
4679*ec779b8eSAndroid Build Coastguard Worker                     getDefaultVibratorInfo_l();
4680*ec779b8eSAndroid Build Coastguard Worker             if (defaultVibratorInfo) {
4681*ec779b8eSAndroid Build Coastguard Worker                 // Only set the vibrator info when it is a valid one.
4682*ec779b8eSAndroid Build Coastguard Worker                 audio_utils::lock_guard _cl(chain->mutex());
4683*ec779b8eSAndroid Build Coastguard Worker                 effect->setVibratorInfo_l(*defaultVibratorInfo);
4684*ec779b8eSAndroid Build Coastguard Worker             }
4685*ec779b8eSAndroid Build Coastguard Worker         }
4686*ec779b8eSAndroid Build Coastguard Worker         effectCreated = true;
4687*ec779b8eSAndroid Build Coastguard Worker     }
4688*ec779b8eSAndroid Build Coastguard Worker     // create effect handle and connect it to effect module
4689*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectHandle> handle =
4690*ec779b8eSAndroid Build Coastguard Worker             IAfEffectHandle::create(effect, client, effectClient, priority, notifyFramesProcessed);
4691*ec779b8eSAndroid Build Coastguard Worker     status_t lStatus = handle->initCheck();
4692*ec779b8eSAndroid Build Coastguard Worker     if (lStatus == OK) {
4693*ec779b8eSAndroid Build Coastguard Worker         lStatus = effect->addHandle(handle.get());
4694*ec779b8eSAndroid Build Coastguard Worker     }
4695*ec779b8eSAndroid Build Coastguard Worker     // in case of lStatus error, EffectHandle will still return and caller should do the clear
4696*ec779b8eSAndroid Build Coastguard Worker     if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
4697*ec779b8eSAndroid Build Coastguard Worker         if (effectCreated) {
4698*ec779b8eSAndroid Build Coastguard Worker             chain->removeEffect(effect);
4699*ec779b8eSAndroid Build Coastguard Worker         }
4700*ec779b8eSAndroid Build Coastguard Worker         // if the effect chain was not created here, put it back
4701*ec779b8eSAndroid Build Coastguard Worker         if (!chainCreated) {
4702*ec779b8eSAndroid Build Coastguard Worker             putOrphanEffectChain_l(chain);
4703*ec779b8eSAndroid Build Coastguard Worker         }
4704*ec779b8eSAndroid Build Coastguard Worker     } else {
4705*ec779b8eSAndroid Build Coastguard Worker         if (enabled != NULL) {
4706*ec779b8eSAndroid Build Coastguard Worker             *enabled = (int)effect->isEnabled();
4707*ec779b8eSAndroid Build Coastguard Worker         }
4708*ec779b8eSAndroid Build Coastguard Worker         putOrphanEffectChain_l(chain);
4709*ec779b8eSAndroid Build Coastguard Worker     }
4710*ec779b8eSAndroid Build Coastguard Worker     *status = lStatus;
4711*ec779b8eSAndroid Build Coastguard Worker     return handle;
4712*ec779b8eSAndroid Build Coastguard Worker }
4713*ec779b8eSAndroid Build Coastguard Worker 
moveEffects(audio_session_t sessionId,audio_io_handle_t srcIo,audio_io_handle_t dstIo)4714*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t srcIo,
4715*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t dstIo)
4716*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS
4717*ec779b8eSAndroid Build Coastguard Worker {
4718*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s() session %d, srcIo %d, dstIo %d", __func__, sessionId, srcIo, dstIo);
4719*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4720*ec779b8eSAndroid Build Coastguard Worker     if (srcIo == dstIo) {
4721*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s() same dst and src outputs %d", __func__, dstIo);
4722*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
4723*ec779b8eSAndroid Build Coastguard Worker     }
4724*ec779b8eSAndroid Build Coastguard Worker     IAfRecordThread* const srcRecordThread = checkRecordThread_l(srcIo);
4725*ec779b8eSAndroid Build Coastguard Worker     IAfRecordThread* const dstRecordThread = checkRecordThread_l(dstIo);
4726*ec779b8eSAndroid Build Coastguard Worker     if (srcRecordThread != nullptr || dstRecordThread != nullptr) {
4727*ec779b8eSAndroid Build Coastguard Worker         if (srcRecordThread != nullptr) {
4728*ec779b8eSAndroid Build Coastguard Worker             srcRecordThread->mutex().lock();
4729*ec779b8eSAndroid Build Coastguard Worker         }
4730*ec779b8eSAndroid Build Coastguard Worker         if (dstRecordThread != nullptr) {
4731*ec779b8eSAndroid Build Coastguard Worker             dstRecordThread->mutex().lock();
4732*ec779b8eSAndroid Build Coastguard Worker         }
4733*ec779b8eSAndroid Build Coastguard Worker         status_t ret = moveEffectChain_ll(sessionId, srcRecordThread, dstRecordThread);
4734*ec779b8eSAndroid Build Coastguard Worker         if (srcRecordThread != nullptr) {
4735*ec779b8eSAndroid Build Coastguard Worker             srcRecordThread->mutex().unlock();
4736*ec779b8eSAndroid Build Coastguard Worker         }
4737*ec779b8eSAndroid Build Coastguard Worker         if (dstRecordThread != nullptr) {
4738*ec779b8eSAndroid Build Coastguard Worker             dstRecordThread->mutex().unlock();
4739*ec779b8eSAndroid Build Coastguard Worker         }
4740*ec779b8eSAndroid Build Coastguard Worker         return ret;
4741*ec779b8eSAndroid Build Coastguard Worker     }
4742*ec779b8eSAndroid Build Coastguard Worker 
4743*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* dstThread = checkPlaybackThread_l(dstIo);
4744*ec779b8eSAndroid Build Coastguard Worker     if (dstThread == nullptr) {
4745*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s() bad dstIo %d", __func__, dstIo);
4746*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
4747*ec779b8eSAndroid Build Coastguard Worker     }
4748*ec779b8eSAndroid Build Coastguard Worker 
4749*ec779b8eSAndroid Build Coastguard Worker     IAfPlaybackThread* srcThread = checkPlaybackThread_l(srcIo);
4750*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectChain> orphanChain = getOrphanEffectChain_l(sessionId);
4751*ec779b8eSAndroid Build Coastguard Worker     if (srcThread == nullptr && orphanChain == nullptr && sessionId == AUDIO_SESSION_OUTPUT_MIX) {
4752*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s() AUDIO_SESSION_OUTPUT_MIX not found in orphans, checking other mix", __func__);
4753*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
4754*ec779b8eSAndroid Build Coastguard Worker             const sp<IAfPlaybackThread> pt = mPlaybackThreads.valueAt(i);
4755*ec779b8eSAndroid Build Coastguard Worker             const uint32_t sessionType = pt->hasAudioSession(AUDIO_SESSION_OUTPUT_MIX);
4756*ec779b8eSAndroid Build Coastguard Worker             if ((pt->type() == IAfThreadBase::MIXER || pt->type() == IAfThreadBase::OFFLOAD) &&
4757*ec779b8eSAndroid Build Coastguard Worker                     ((sessionType & IAfThreadBase::EFFECT_SESSION) != 0)) {
4758*ec779b8eSAndroid Build Coastguard Worker                 srcThread = pt.get();
4759*ec779b8eSAndroid Build Coastguard Worker                 if (srcThread == dstThread) {
4760*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("%s() same dst and src threads, ignoring move", __func__);
4761*ec779b8eSAndroid Build Coastguard Worker                     return NO_ERROR;
4762*ec779b8eSAndroid Build Coastguard Worker                 }
4763*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("%s() found srcOutput %d hosting AUDIO_SESSION_OUTPUT_MIX", __func__,
4764*ec779b8eSAndroid Build Coastguard Worker                       pt->id());
4765*ec779b8eSAndroid Build Coastguard Worker                 break;
4766*ec779b8eSAndroid Build Coastguard Worker             }
4767*ec779b8eSAndroid Build Coastguard Worker         }
4768*ec779b8eSAndroid Build Coastguard Worker     }
4769*ec779b8eSAndroid Build Coastguard Worker     if (srcThread == nullptr && orphanChain == nullptr) {
4770*ec779b8eSAndroid Build Coastguard Worker         ALOGW("moveEffects() bad srcIo %d", srcIo);
4771*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
4772*ec779b8eSAndroid Build Coastguard Worker     }
4773*ec779b8eSAndroid Build Coastguard Worker     // dstThread pointer validity has already been checked
4774*ec779b8eSAndroid Build Coastguard Worker     if (orphanChain != nullptr) {
4775*ec779b8eSAndroid Build Coastguard Worker         audio_utils::scoped_lock _ll(dstThread->mutex());
4776*ec779b8eSAndroid Build Coastguard Worker         return moveEffectChain_ll(sessionId, nullptr, dstThread, orphanChain.get());
4777*ec779b8eSAndroid Build Coastguard Worker     }
4778*ec779b8eSAndroid Build Coastguard Worker     // srcThread pointer validity has already been checked
4779*ec779b8eSAndroid Build Coastguard Worker     audio_utils::scoped_lock _ll(dstThread->mutex(), srcThread->mutex());
4780*ec779b8eSAndroid Build Coastguard Worker     return moveEffectChain_ll(sessionId, srcThread, dstThread);
4781*ec779b8eSAndroid Build Coastguard Worker }
4782*ec779b8eSAndroid Build Coastguard Worker 
4783*ec779b8eSAndroid Build Coastguard Worker 
setEffectSuspended(int effectId,audio_session_t sessionId,bool suspended)4784*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::setEffectSuspended(int effectId,
4785*ec779b8eSAndroid Build Coastguard Worker                                 audio_session_t sessionId,
4786*ec779b8eSAndroid Build Coastguard Worker                                 bool suspended)
4787*ec779b8eSAndroid Build Coastguard Worker {
4788*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4789*ec779b8eSAndroid Build Coastguard Worker 
4790*ec779b8eSAndroid Build Coastguard Worker     sp<IAfThreadBase> thread = getEffectThread_l(sessionId, effectId);
4791*ec779b8eSAndroid Build Coastguard Worker     if (thread == nullptr) {
4792*ec779b8eSAndroid Build Coastguard Worker         return;
4793*ec779b8eSAndroid Build Coastguard Worker     }
4794*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _sl(thread->mutex());
4795*ec779b8eSAndroid Build Coastguard Worker     if (const auto& effect = thread->getEffect_l(sessionId, effectId)) {
4796*ec779b8eSAndroid Build Coastguard Worker         thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
4797*ec779b8eSAndroid Build Coastguard Worker     }
4798*ec779b8eSAndroid Build Coastguard Worker }
4799*ec779b8eSAndroid Build Coastguard Worker 
4800*ec779b8eSAndroid Build Coastguard Worker 
4801*ec779b8eSAndroid Build Coastguard Worker // moveEffectChain_ll must be called with the AudioFlinger::mutex()
4802*ec779b8eSAndroid Build Coastguard Worker // and both srcThread and dstThread mutex()s held
moveEffectChain_ll(audio_session_t sessionId,IAfPlaybackThread * srcThread,IAfPlaybackThread * dstThread,IAfEffectChain * srcChain)4803*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId,
4804*ec779b8eSAndroid Build Coastguard Worker         IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread,
4805*ec779b8eSAndroid Build Coastguard Worker         IAfEffectChain* srcChain)
4806*ec779b8eSAndroid Build Coastguard Worker {
4807*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: session %d from thread %p to thread %p %s",
4808*ec779b8eSAndroid Build Coastguard Worker             __func__, sessionId, srcThread, dstThread,
4809*ec779b8eSAndroid Build Coastguard Worker             (srcChain != nullptr ? "from specific chain" : ""));
4810*ec779b8eSAndroid Build Coastguard Worker     ALOG_ASSERT((srcThread != nullptr) != (srcChain != nullptr),
4811*ec779b8eSAndroid Build Coastguard Worker                 "no source provided for source chain");
4812*ec779b8eSAndroid Build Coastguard Worker 
4813*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectChain> chain =
4814*ec779b8eSAndroid Build Coastguard Worker           srcChain != nullptr ? srcChain : srcThread->getEffectChain_l(sessionId);
4815*ec779b8eSAndroid Build Coastguard Worker     if (chain == 0) {
4816*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: effect chain for session %d not on source thread %p",
4817*ec779b8eSAndroid Build Coastguard Worker                 __func__, sessionId, srcThread);
4818*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
4819*ec779b8eSAndroid Build Coastguard Worker     }
4820*ec779b8eSAndroid Build Coastguard Worker 
4821*ec779b8eSAndroid Build Coastguard Worker     // Check whether the destination thread and all effects in the chain are compatible
4822*ec779b8eSAndroid Build Coastguard Worker     if (!chain->isCompatibleWithThread_l(dstThread)) {
4823*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: effect chain failed because"
4824*ec779b8eSAndroid Build Coastguard Worker                 " destination thread %p is not compatible with effects in the chain",
4825*ec779b8eSAndroid Build Coastguard Worker                 __func__, dstThread);
4826*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
4827*ec779b8eSAndroid Build Coastguard Worker     }
4828*ec779b8eSAndroid Build Coastguard Worker 
4829*ec779b8eSAndroid Build Coastguard Worker     // remove chain first. This is useful only if reconfiguring effect chain on same output thread,
4830*ec779b8eSAndroid Build Coastguard Worker     // so that a new chain is created with correct parameters when first effect is added. This is
4831*ec779b8eSAndroid Build Coastguard Worker     // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is
4832*ec779b8eSAndroid Build Coastguard Worker     // removed.
4833*ec779b8eSAndroid Build Coastguard Worker     // TODO(b/216875016): consider holding the effect chain locks for the duration of the move.
4834*ec779b8eSAndroid Build Coastguard Worker     if (srcThread != nullptr) {
4835*ec779b8eSAndroid Build Coastguard Worker         srcThread->removeEffectChain_l(chain);
4836*ec779b8eSAndroid Build Coastguard Worker     }
4837*ec779b8eSAndroid Build Coastguard Worker     // transfer all effects one by one so that new effect chain is created on new thread with
4838*ec779b8eSAndroid Build Coastguard Worker     // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
4839*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectChain> dstChain;
4840*ec779b8eSAndroid Build Coastguard Worker     Vector<sp<IAfEffectModule>> removed;
4841*ec779b8eSAndroid Build Coastguard Worker     status_t status = NO_ERROR;
4842*ec779b8eSAndroid Build Coastguard Worker     std::string errorString;
4843*ec779b8eSAndroid Build Coastguard Worker     // process effects one by one.
4844*ec779b8eSAndroid Build Coastguard Worker     for (sp<IAfEffectModule> effect = chain->getEffectFromId_l(0); effect != nullptr;
4845*ec779b8eSAndroid Build Coastguard Worker             effect = chain->getEffectFromId_l(0)) {
4846*ec779b8eSAndroid Build Coastguard Worker         if (srcThread != nullptr) {
4847*ec779b8eSAndroid Build Coastguard Worker             srcThread->removeEffect_l(effect);
4848*ec779b8eSAndroid Build Coastguard Worker         } else {
4849*ec779b8eSAndroid Build Coastguard Worker             chain->removeEffect(effect);
4850*ec779b8eSAndroid Build Coastguard Worker         }
4851*ec779b8eSAndroid Build Coastguard Worker         removed.add(effect);
4852*ec779b8eSAndroid Build Coastguard Worker         status = dstThread->addEffect_ll(effect);
4853*ec779b8eSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
4854*ec779b8eSAndroid Build Coastguard Worker             errorString = StringPrintf(
4855*ec779b8eSAndroid Build Coastguard Worker                     "cannot add effect %p to destination thread", effect.get());
4856*ec779b8eSAndroid Build Coastguard Worker             break;
4857*ec779b8eSAndroid Build Coastguard Worker         }
4858*ec779b8eSAndroid Build Coastguard Worker         // if the move request is not received from audio policy manager, the effect must be
4859*ec779b8eSAndroid Build Coastguard Worker         // re-registered with the new strategy and output.
4860*ec779b8eSAndroid Build Coastguard Worker 
4861*ec779b8eSAndroid Build Coastguard Worker         // We obtain the dstChain once the effect is on the new thread.
4862*ec779b8eSAndroid Build Coastguard Worker         if (dstChain == nullptr) {
4863*ec779b8eSAndroid Build Coastguard Worker             dstChain = effect->getCallback()->chain().promote();
4864*ec779b8eSAndroid Build Coastguard Worker             if (dstChain == nullptr) {
4865*ec779b8eSAndroid Build Coastguard Worker                 errorString = StringPrintf("cannot get chain from effect %p", effect.get());
4866*ec779b8eSAndroid Build Coastguard Worker                 status = NO_INIT;
4867*ec779b8eSAndroid Build Coastguard Worker                 break;
4868*ec779b8eSAndroid Build Coastguard Worker             }
4869*ec779b8eSAndroid Build Coastguard Worker         }
4870*ec779b8eSAndroid Build Coastguard Worker     }
4871*ec779b8eSAndroid Build Coastguard Worker 
4872*ec779b8eSAndroid Build Coastguard Worker     size_t restored = 0;
4873*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
4874*ec779b8eSAndroid Build Coastguard Worker         dstChain.clear(); // dstChain is now from the srcThread (could be recreated).
4875*ec779b8eSAndroid Build Coastguard Worker         for (const auto& effect : removed) {
4876*ec779b8eSAndroid Build Coastguard Worker             dstThread->removeEffect_l(effect); // Note: Depending on error location, the last
4877*ec779b8eSAndroid Build Coastguard Worker                                                // effect may not have been placed on dstThread.
4878*ec779b8eSAndroid Build Coastguard Worker             if (srcThread != nullptr && srcThread->addEffect_ll(effect) == NO_ERROR) {
4879*ec779b8eSAndroid Build Coastguard Worker                 ++restored;
4880*ec779b8eSAndroid Build Coastguard Worker                 if (dstChain == nullptr) {
4881*ec779b8eSAndroid Build Coastguard Worker                     dstChain = effect->getCallback()->chain().promote();
4882*ec779b8eSAndroid Build Coastguard Worker                 }
4883*ec779b8eSAndroid Build Coastguard Worker             }
4884*ec779b8eSAndroid Build Coastguard Worker         }
4885*ec779b8eSAndroid Build Coastguard Worker     }
4886*ec779b8eSAndroid Build Coastguard Worker 
4887*ec779b8eSAndroid Build Coastguard Worker     // After all the effects have been moved to new thread (or put back) we restart the effects
4888*ec779b8eSAndroid Build Coastguard Worker     // because removeEffect_l() has stopped the effect if it is currently active.
4889*ec779b8eSAndroid Build Coastguard Worker     size_t started = 0;
4890*ec779b8eSAndroid Build Coastguard Worker     if (dstChain != nullptr && !removed.empty()) {
4891*ec779b8eSAndroid Build Coastguard Worker         // If we do not take the dstChain lock, it is possible that processing is ongoing
4892*ec779b8eSAndroid Build Coastguard Worker         // while we are starting the effect.  This can cause glitches with volume,
4893*ec779b8eSAndroid Build Coastguard Worker         // see b/202360137.
4894*ec779b8eSAndroid Build Coastguard Worker         dstChain->mutex().lock();
4895*ec779b8eSAndroid Build Coastguard Worker         for (const auto& effect : removed) {
4896*ec779b8eSAndroid Build Coastguard Worker             if (effect->state() == IAfEffectModule::ACTIVE ||
4897*ec779b8eSAndroid Build Coastguard Worker                     effect->state() == IAfEffectModule::STOPPING) {
4898*ec779b8eSAndroid Build Coastguard Worker                 ++started;
4899*ec779b8eSAndroid Build Coastguard Worker                 effect->start_l();
4900*ec779b8eSAndroid Build Coastguard Worker             }
4901*ec779b8eSAndroid Build Coastguard Worker         }
4902*ec779b8eSAndroid Build Coastguard Worker         dstChain->mutex().unlock();
4903*ec779b8eSAndroid Build Coastguard Worker     }
4904*ec779b8eSAndroid Build Coastguard Worker 
4905*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
4906*ec779b8eSAndroid Build Coastguard Worker         if (errorString.empty()) {
4907*ec779b8eSAndroid Build Coastguard Worker             errorString = StringPrintf("%s: failed status %d", __func__, status);
4908*ec779b8eSAndroid Build Coastguard Worker         }
4909*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: %s unsuccessful move of session %d from %s %p to dstThread %p "
4910*ec779b8eSAndroid Build Coastguard Worker                 "(%zu effects removed from srcThread, %zu effects restored to srcThread, "
4911*ec779b8eSAndroid Build Coastguard Worker                 "%zu effects started)",
4912*ec779b8eSAndroid Build Coastguard Worker                 __func__, errorString.c_str(), sessionId,
4913*ec779b8eSAndroid Build Coastguard Worker                 (srcThread != nullptr ? "srcThread" : "srcChain"),
4914*ec779b8eSAndroid Build Coastguard Worker                 (srcThread != nullptr ? (void*) srcThread : (void*) srcChain), dstThread,
4915*ec779b8eSAndroid Build Coastguard Worker                 removed.size(), restored, started);
4916*ec779b8eSAndroid Build Coastguard Worker     } else {
4917*ec779b8eSAndroid Build Coastguard Worker         ALOGD("%s: successful move of session %d from %s %p to dstThread %p "
4918*ec779b8eSAndroid Build Coastguard Worker                 "(%zu effects moved, %zu effects started)",
4919*ec779b8eSAndroid Build Coastguard Worker                 __func__, sessionId, (srcThread != nullptr ? "srcThread" : "srcChain"),
4920*ec779b8eSAndroid Build Coastguard Worker                 (srcThread != nullptr ? (void*) srcThread : (void*) srcChain), dstThread,
4921*ec779b8eSAndroid Build Coastguard Worker                 removed.size(), started);
4922*ec779b8eSAndroid Build Coastguard Worker     }
4923*ec779b8eSAndroid Build Coastguard Worker     return status;
4924*ec779b8eSAndroid Build Coastguard Worker }
4925*ec779b8eSAndroid Build Coastguard Worker 
4926*ec779b8eSAndroid Build Coastguard Worker 
4927*ec779b8eSAndroid Build Coastguard Worker // moveEffectChain_ll must be called with both srcThread (if not null) and dstThread (if not null)
4928*ec779b8eSAndroid Build Coastguard Worker // mutex()s held
moveEffectChain_ll(audio_session_t sessionId,IAfRecordThread * srcThread,IAfRecordThread * dstThread)4929*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId,
4930*ec779b8eSAndroid Build Coastguard Worker         IAfRecordThread* srcThread, IAfRecordThread* dstThread)
4931*ec779b8eSAndroid Build Coastguard Worker {
4932*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectChain> chain = nullptr;
4933*ec779b8eSAndroid Build Coastguard Worker     if (srcThread != 0) {
4934*ec779b8eSAndroid Build Coastguard Worker         const Vector<sp<IAfEffectChain>> effectChains = srcThread->getEffectChains_l();
4935*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < effectChains.size(); i ++) {
4936*ec779b8eSAndroid Build Coastguard Worker              if (effectChains[i]->sessionId() == sessionId) {
4937*ec779b8eSAndroid Build Coastguard Worker                  chain = effectChains[i];
4938*ec779b8eSAndroid Build Coastguard Worker                  break;
4939*ec779b8eSAndroid Build Coastguard Worker              }
4940*ec779b8eSAndroid Build Coastguard Worker         }
4941*ec779b8eSAndroid Build Coastguard Worker         ALOGV_IF(effectChains.size() == 0, "%s: no effect chain on io=%d", __func__,
4942*ec779b8eSAndroid Build Coastguard Worker                 srcThread->id());
4943*ec779b8eSAndroid Build Coastguard Worker         if (chain == nullptr) {
4944*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s wrong session id %d", __func__, sessionId);
4945*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
4946*ec779b8eSAndroid Build Coastguard Worker         }
4947*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s: removing effect chain for session=%d io=%d", __func__, sessionId,
4948*ec779b8eSAndroid Build Coastguard Worker                 srcThread->id());
4949*ec779b8eSAndroid Build Coastguard Worker         srcThread->removeEffectChain_l(chain);
4950*ec779b8eSAndroid Build Coastguard Worker     } else {
4951*ec779b8eSAndroid Build Coastguard Worker         chain = getOrphanEffectChain_l(sessionId);
4952*ec779b8eSAndroid Build Coastguard Worker         if (chain == nullptr) {
4953*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: no orphan effect chain found for session=%d", __func__, sessionId);
4954*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
4955*ec779b8eSAndroid Build Coastguard Worker         }
4956*ec779b8eSAndroid Build Coastguard Worker     }
4957*ec779b8eSAndroid Build Coastguard Worker     if (dstThread != 0) {
4958*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s: adding effect chain for session=%d on io=%d", __func__, sessionId,
4959*ec779b8eSAndroid Build Coastguard Worker                 dstThread->id());
4960*ec779b8eSAndroid Build Coastguard Worker         dstThread->addEffectChain_l(chain);
4961*ec779b8eSAndroid Build Coastguard Worker         return NO_ERROR;
4962*ec779b8eSAndroid Build Coastguard Worker     }
4963*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: parking to orphan effect chain for session=%d", __func__, sessionId);
4964*ec779b8eSAndroid Build Coastguard Worker     putOrphanEffectChain_l(chain);
4965*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
4966*ec779b8eSAndroid Build Coastguard Worker }
4967*ec779b8eSAndroid Build Coastguard Worker 
moveAuxEffectToIo(int EffectId,const sp<IAfPlaybackThread> & dstThread,sp<IAfPlaybackThread> * srcThread)4968*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::moveAuxEffectToIo(int EffectId,
4969*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfPlaybackThread>& dstThread, sp<IAfPlaybackThread>* srcThread)
4970*ec779b8eSAndroid Build Coastguard Worker {
4971*ec779b8eSAndroid Build Coastguard Worker     status_t status = NO_ERROR;
4972*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
4973*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfThreadBase> threadBase = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
4974*ec779b8eSAndroid Build Coastguard Worker     const sp<IAfPlaybackThread> thread = threadBase ? threadBase->asIAfPlaybackThread() : nullptr;
4975*ec779b8eSAndroid Build Coastguard Worker 
4976*ec779b8eSAndroid Build Coastguard Worker     if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
4977*ec779b8eSAndroid Build Coastguard Worker         audio_utils::scoped_lock _ll(dstThread->mutex(), thread->mutex());
4978*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
4979*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> dstChain;
4980*ec779b8eSAndroid Build Coastguard Worker         if (srcChain == 0) {
4981*ec779b8eSAndroid Build Coastguard Worker             return INVALID_OPERATION;
4982*ec779b8eSAndroid Build Coastguard Worker         }
4983*ec779b8eSAndroid Build Coastguard Worker 
4984*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectModule> effect = srcChain->getEffectFromId_l(EffectId);
4985*ec779b8eSAndroid Build Coastguard Worker         if (effect == 0) {
4986*ec779b8eSAndroid Build Coastguard Worker             return INVALID_OPERATION;
4987*ec779b8eSAndroid Build Coastguard Worker         }
4988*ec779b8eSAndroid Build Coastguard Worker         thread->removeEffect_l(effect);
4989*ec779b8eSAndroid Build Coastguard Worker         status = dstThread->addEffect_ll(effect);
4990*ec779b8eSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
4991*ec779b8eSAndroid Build Coastguard Worker             thread->addEffect_ll(effect);
4992*ec779b8eSAndroid Build Coastguard Worker             status = INVALID_OPERATION;
4993*ec779b8eSAndroid Build Coastguard Worker             goto Exit;
4994*ec779b8eSAndroid Build Coastguard Worker         }
4995*ec779b8eSAndroid Build Coastguard Worker 
4996*ec779b8eSAndroid Build Coastguard Worker         dstChain = effect->getCallback()->chain().promote();
4997*ec779b8eSAndroid Build Coastguard Worker         if (dstChain == 0) {
4998*ec779b8eSAndroid Build Coastguard Worker             thread->addEffect_ll(effect);
4999*ec779b8eSAndroid Build Coastguard Worker             status = INVALID_OPERATION;
5000*ec779b8eSAndroid Build Coastguard Worker         }
5001*ec779b8eSAndroid Build Coastguard Worker 
5002*ec779b8eSAndroid Build Coastguard Worker Exit:
5003*ec779b8eSAndroid Build Coastguard Worker         // removeEffect_l() has stopped the effect if it was active so it must be restarted
5004*ec779b8eSAndroid Build Coastguard Worker         if (effect->state() == IAfEffectModule::ACTIVE ||
5005*ec779b8eSAndroid Build Coastguard Worker             effect->state() == IAfEffectModule::STOPPING) {
5006*ec779b8eSAndroid Build Coastguard Worker             effect->start_l();
5007*ec779b8eSAndroid Build Coastguard Worker         }
5008*ec779b8eSAndroid Build Coastguard Worker     }
5009*ec779b8eSAndroid Build Coastguard Worker 
5010*ec779b8eSAndroid Build Coastguard Worker     if (status == NO_ERROR && srcThread != nullptr) {
5011*ec779b8eSAndroid Build Coastguard Worker         *srcThread = thread;
5012*ec779b8eSAndroid Build Coastguard Worker     }
5013*ec779b8eSAndroid Build Coastguard Worker     return status;
5014*ec779b8eSAndroid Build Coastguard Worker }
5015*ec779b8eSAndroid Build Coastguard Worker 
isNonOffloadableGlobalEffectEnabled_l() const5016*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const
5017*ec779b8eSAndroid Build Coastguard Worker {
5018*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
5019*ec779b8eSAndroid Build Coastguard Worker         const auto thread = mPlaybackThreads.valueAt(i);
5020*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard l(thread->mutex());
5021*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfEffectChain> ec = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
5022*ec779b8eSAndroid Build Coastguard Worker         if (ec != 0 && ec->isNonOffloadableEnabled()) {
5023*ec779b8eSAndroid Build Coastguard Worker             return true;
5024*ec779b8eSAndroid Build Coastguard Worker         }
5025*ec779b8eSAndroid Build Coastguard Worker     }
5026*ec779b8eSAndroid Build Coastguard Worker     return false;
5027*ec779b8eSAndroid Build Coastguard Worker }
5028*ec779b8eSAndroid Build Coastguard Worker 
onNonOffloadableGlobalEffectEnable()5029*ec779b8eSAndroid Build Coastguard Worker void AudioFlinger::onNonOffloadableGlobalEffectEnable()
5030*ec779b8eSAndroid Build Coastguard Worker {
5031*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5032*ec779b8eSAndroid Build Coastguard Worker 
5033*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
5034*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
5035*ec779b8eSAndroid Build Coastguard Worker         if (t->type() == IAfThreadBase::OFFLOAD) {
5036*ec779b8eSAndroid Build Coastguard Worker             t->invalidateTracks(AUDIO_STREAM_MUSIC);
5037*ec779b8eSAndroid Build Coastguard Worker         }
5038*ec779b8eSAndroid Build Coastguard Worker     }
5039*ec779b8eSAndroid Build Coastguard Worker 
5040*ec779b8eSAndroid Build Coastguard Worker }
5041*ec779b8eSAndroid Build Coastguard Worker 
putOrphanEffectChain_l(const sp<IAfEffectChain> & chain)5042*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::putOrphanEffectChain_l(const sp<IAfEffectChain>& chain)
5043*ec779b8eSAndroid Build Coastguard Worker {
5044*ec779b8eSAndroid Build Coastguard Worker     // clear possible suspended state before parking the chain so that it starts in default state
5045*ec779b8eSAndroid Build Coastguard Worker     // when attached to a new record thread
5046*ec779b8eSAndroid Build Coastguard Worker     chain->setEffectSuspended_l(FX_IID_AEC, false);
5047*ec779b8eSAndroid Build Coastguard Worker     chain->setEffectSuspended_l(FX_IID_NS, false);
5048*ec779b8eSAndroid Build Coastguard Worker 
5049*ec779b8eSAndroid Build Coastguard Worker     audio_session_t session = chain->sessionId();
5050*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mOrphanEffectChains.indexOfKey(session);
5051*ec779b8eSAndroid Build Coastguard Worker     ALOGV("putOrphanEffectChain_l session %d index %zd", session, index);
5052*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
5053*ec779b8eSAndroid Build Coastguard Worker         ALOGW("putOrphanEffectChain_l chain for session %d already present", session);
5054*ec779b8eSAndroid Build Coastguard Worker         return ALREADY_EXISTS;
5055*ec779b8eSAndroid Build Coastguard Worker     }
5056*ec779b8eSAndroid Build Coastguard Worker     mOrphanEffectChains.add(session, chain);
5057*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
5058*ec779b8eSAndroid Build Coastguard Worker }
5059*ec779b8eSAndroid Build Coastguard Worker 
getOrphanEffectChain_l(audio_session_t session)5060*ec779b8eSAndroid Build Coastguard Worker sp<IAfEffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session_t session)
5061*ec779b8eSAndroid Build Coastguard Worker {
5062*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectChain> chain;
5063*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mOrphanEffectChains.indexOfKey(session);
5064*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getOrphanEffectChain_l session %d index %zd", session, index);
5065*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
5066*ec779b8eSAndroid Build Coastguard Worker         chain = mOrphanEffectChains.valueAt(index);
5067*ec779b8eSAndroid Build Coastguard Worker         mOrphanEffectChains.removeItemsAt(index);
5068*ec779b8eSAndroid Build Coastguard Worker     }
5069*ec779b8eSAndroid Build Coastguard Worker     return chain;
5070*ec779b8eSAndroid Build Coastguard Worker }
5071*ec779b8eSAndroid Build Coastguard Worker 
updateOrphanEffectChains(const sp<IAfEffectModule> & effect)5072*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
5073*ec779b8eSAndroid Build Coastguard Worker {
5074*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5075*ec779b8eSAndroid Build Coastguard Worker     return updateOrphanEffectChains_l(effect);
5076*ec779b8eSAndroid Build Coastguard Worker }
5077*ec779b8eSAndroid Build Coastguard Worker 
updateOrphanEffectChains_l(const sp<IAfEffectModule> & effect)5078*ec779b8eSAndroid Build Coastguard Worker bool AudioFlinger::updateOrphanEffectChains_l(const sp<IAfEffectModule>& effect)
5079*ec779b8eSAndroid Build Coastguard Worker {
5080*ec779b8eSAndroid Build Coastguard Worker     audio_session_t session = effect->sessionId();
5081*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mOrphanEffectChains.indexOfKey(session);
5082*ec779b8eSAndroid Build Coastguard Worker     ALOGV("updateOrphanEffectChains session %d index %zd", session, index);
5083*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
5084*ec779b8eSAndroid Build Coastguard Worker         sp<IAfEffectChain> chain = mOrphanEffectChains.valueAt(index);
5085*ec779b8eSAndroid Build Coastguard Worker         if (chain->removeEffect(effect, true) == 0) {
5086*ec779b8eSAndroid Build Coastguard Worker             ALOGV("updateOrphanEffectChains removing effect chain at index %zd", index);
5087*ec779b8eSAndroid Build Coastguard Worker             mOrphanEffectChains.removeItemsAt(index);
5088*ec779b8eSAndroid Build Coastguard Worker         }
5089*ec779b8eSAndroid Build Coastguard Worker         return true;
5090*ec779b8eSAndroid Build Coastguard Worker     }
5091*ec779b8eSAndroid Build Coastguard Worker     return false;
5092*ec779b8eSAndroid Build Coastguard Worker }
5093*ec779b8eSAndroid Build Coastguard Worker 
5094*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5095*ec779b8eSAndroid Build Coastguard Worker // from PatchPanel
5096*ec779b8eSAndroid Build Coastguard Worker 
5097*ec779b8eSAndroid Build Coastguard Worker /* List connected audio ports and their attributes */
listAudioPorts(unsigned int * num_ports,struct audio_port * ports) const5098*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::listAudioPorts(unsigned int* num_ports,
5099*ec779b8eSAndroid Build Coastguard Worker         struct audio_port* ports) const
5100*ec779b8eSAndroid Build Coastguard Worker {
5101*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5102*ec779b8eSAndroid Build Coastguard Worker     return mPatchPanel->listAudioPorts_l(num_ports, ports);
5103*ec779b8eSAndroid Build Coastguard Worker }
5104*ec779b8eSAndroid Build Coastguard Worker 
5105*ec779b8eSAndroid Build Coastguard Worker /* Get supported attributes for a given audio port */
getAudioPort(struct audio_port_v7 * port) const5106*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getAudioPort(struct audio_port_v7* port) const {
5107*ec779b8eSAndroid Build Coastguard Worker     const status_t status = AudioValidator::validateAudioPort(*port);
5108*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
5109*ec779b8eSAndroid Build Coastguard Worker         return status;
5110*ec779b8eSAndroid Build Coastguard Worker     }
5111*ec779b8eSAndroid Build Coastguard Worker 
5112*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5113*ec779b8eSAndroid Build Coastguard Worker     return mPatchPanel->getAudioPort_l(port);
5114*ec779b8eSAndroid Build Coastguard Worker }
5115*ec779b8eSAndroid Build Coastguard Worker 
5116*ec779b8eSAndroid Build Coastguard Worker /* Connect a patch between several source and sink ports */
createAudioPatch(const struct audio_patch * patch,audio_patch_handle_t * handle)5117*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::createAudioPatch(
5118*ec779b8eSAndroid Build Coastguard Worker         const struct audio_patch* patch, audio_patch_handle_t* handle)
5119*ec779b8eSAndroid Build Coastguard Worker {
5120*ec779b8eSAndroid Build Coastguard Worker     const status_t status = AudioValidator::validateAudioPatch(*patch);
5121*ec779b8eSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
5122*ec779b8eSAndroid Build Coastguard Worker         return status;
5123*ec779b8eSAndroid Build Coastguard Worker     }
5124*ec779b8eSAndroid Build Coastguard Worker 
5125*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5126*ec779b8eSAndroid Build Coastguard Worker     return mPatchPanel->createAudioPatch_l(patch, handle);
5127*ec779b8eSAndroid Build Coastguard Worker }
5128*ec779b8eSAndroid Build Coastguard Worker 
5129*ec779b8eSAndroid Build Coastguard Worker /* Disconnect a patch */
releaseAudioPatch(audio_patch_handle_t handle)5130*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
5131*ec779b8eSAndroid Build Coastguard Worker {
5132*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5133*ec779b8eSAndroid Build Coastguard Worker     return mPatchPanel->releaseAudioPatch_l(handle);
5134*ec779b8eSAndroid Build Coastguard Worker }
5135*ec779b8eSAndroid Build Coastguard Worker 
5136*ec779b8eSAndroid Build Coastguard Worker /* List connected audio ports and they attributes */
listAudioPatches(unsigned int * num_patches,struct audio_patch * patches) const5137*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::listAudioPatches(
5138*ec779b8eSAndroid Build Coastguard Worker         unsigned int* num_patches, struct audio_patch* patches) const
5139*ec779b8eSAndroid Build Coastguard Worker {
5140*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5141*ec779b8eSAndroid Build Coastguard Worker     return mPatchPanel->listAudioPatches_l(num_patches, patches);
5142*ec779b8eSAndroid Build Coastguard Worker }
5143*ec779b8eSAndroid Build Coastguard Worker 
5144*ec779b8eSAndroid Build Coastguard Worker /**
5145*ec779b8eSAndroid Build Coastguard Worker  * Get the attributes of the mix port when connecting to the given device port.
5146*ec779b8eSAndroid Build Coastguard Worker  */
getAudioMixPort(const struct audio_port_v7 * devicePort,struct audio_port_v7 * mixPort) const5147*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::getAudioMixPort(const struct audio_port_v7 *devicePort,
5148*ec779b8eSAndroid Build Coastguard Worker                                        struct audio_port_v7 *mixPort) const {
5149*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = AudioValidator::validateAudioPort(*devicePort); status != NO_ERROR) {
5150*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s, invalid device port, status=%d", __func__, status);
5151*ec779b8eSAndroid Build Coastguard Worker         return status;
5152*ec779b8eSAndroid Build Coastguard Worker     }
5153*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = AudioValidator::validateAudioPort(*mixPort); status != NO_ERROR) {
5154*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s, invalid mix port, status=%d", __func__, status);
5155*ec779b8eSAndroid Build Coastguard Worker         return status;
5156*ec779b8eSAndroid Build Coastguard Worker     }
5157*ec779b8eSAndroid Build Coastguard Worker 
5158*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5159*ec779b8eSAndroid Build Coastguard Worker     return mPatchPanel->getAudioMixPort_l(devicePort, mixPort);
5160*ec779b8eSAndroid Build Coastguard Worker }
5161*ec779b8eSAndroid Build Coastguard Worker 
setTracksInternalMute(const std::vector<media::TrackInternalMuteInfo> & tracksInternalMute)5162*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::setTracksInternalMute(
5163*ec779b8eSAndroid Build Coastguard Worker         const std::vector<media::TrackInternalMuteInfo>& tracksInternalMute) {
5164*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
5165*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s", __func__);
5166*ec779b8eSAndroid Build Coastguard Worker 
5167*ec779b8eSAndroid Build Coastguard Worker     std::map<audio_port_handle_t, bool> tracksInternalMuteMap;
5168*ec779b8eSAndroid Build Coastguard Worker     for (const auto& trackInternalMute : tracksInternalMute) {
5169*ec779b8eSAndroid Build Coastguard Worker         audio_port_handle_t portId = VALUE_OR_RETURN_STATUS(
5170*ec779b8eSAndroid Build Coastguard Worker                 aidl2legacy_int32_t_audio_port_handle_t(trackInternalMute.portId));
5171*ec779b8eSAndroid Build Coastguard Worker         tracksInternalMuteMap.emplace(portId, trackInternalMute.muted);
5172*ec779b8eSAndroid Build Coastguard Worker     }
5173*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mPlaybackThreads.size() && !tracksInternalMuteMap.empty(); i++) {
5174*ec779b8eSAndroid Build Coastguard Worker         mPlaybackThreads.valueAt(i)->setTracksInternalMute(&tracksInternalMuteMap);
5175*ec779b8eSAndroid Build Coastguard Worker     }
5176*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
5177*ec779b8eSAndroid Build Coastguard Worker }
5178*ec779b8eSAndroid Build Coastguard Worker 
resetReferencesForTest()5179*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::resetReferencesForTest() {
5180*ec779b8eSAndroid Build Coastguard Worker     mDeviceEffectManager.clear();
5181*ec779b8eSAndroid Build Coastguard Worker     mPatchPanel.clear();
5182*ec779b8eSAndroid Build Coastguard Worker     mMelReporter->resetReferencesForTest();
5183*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
5184*ec779b8eSAndroid Build Coastguard Worker }
5185*ec779b8eSAndroid Build Coastguard Worker 
5186*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5187*ec779b8eSAndroid Build Coastguard Worker 
onTransactWrapper(TransactionCode code,const Parcel & data,uint32_t flags,const std::function<status_t ()> & delegate)5188*ec779b8eSAndroid Build Coastguard Worker status_t AudioFlinger::onTransactWrapper(TransactionCode code,
5189*ec779b8eSAndroid Build Coastguard Worker                                          [[maybe_unused]] const Parcel& data,
5190*ec779b8eSAndroid Build Coastguard Worker                                          [[maybe_unused]] uint32_t flags,
5191*ec779b8eSAndroid Build Coastguard Worker                                          const std::function<status_t()>& delegate) {
5192*ec779b8eSAndroid Build Coastguard Worker     // make sure transactions reserved to AudioPolicyManager do not come from other processes
5193*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
5194*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_STREAM_VOLUME:
5195*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_STREAM_MUTE:
5196*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::OPEN_OUTPUT:
5197*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::OPEN_DUPLICATE_OUTPUT:
5198*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::CLOSE_OUTPUT:
5199*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SUSPEND_OUTPUT:
5200*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::RESTORE_OUTPUT:
5201*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::OPEN_INPUT:
5202*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::CLOSE_INPUT:
5203*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_VOICE_VOLUME:
5204*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::MOVE_EFFECTS:
5205*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_EFFECT_SUSPENDED:
5206*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::LOAD_HW_MODULE:
5207*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::GET_AUDIO_PORT:
5208*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::CREATE_AUDIO_PATCH:
5209*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::RELEASE_AUDIO_PATCH:
5210*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::LIST_AUDIO_PATCHES:
5211*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_AUDIO_PORT_CONFIG:
5212*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_RECORD_SILENCED:
5213*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::AUDIO_POLICY_READY:
5214*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_DEVICE_CONNECTED_STATE:
5215*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_REQUESTED_LATENCY_MODE:
5216*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::GET_SUPPORTED_LATENCY_MODES:
5217*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::INVALIDATE_TRACKS:
5218*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::GET_AUDIO_POLICY_CONFIG:
5219*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::GET_AUDIO_MIX_PORT:
5220*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_TRACKS_INTERNAL_MUTE:
5221*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::RESET_REFERENCES_FOR_TEST:
5222*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_PORTS_VOLUME:
5223*ec779b8eSAndroid Build Coastguard Worker             ALOGW("%s: transaction %d received from PID %d",
5224*ec779b8eSAndroid Build Coastguard Worker                   __func__, static_cast<int>(code), IPCThreadState::self()->getCallingPid());
5225*ec779b8eSAndroid Build Coastguard Worker             // return status only for non void methods
5226*ec779b8eSAndroid Build Coastguard Worker             switch (code) {
5227*ec779b8eSAndroid Build Coastguard Worker                 case TransactionCode::SET_RECORD_SILENCED:
5228*ec779b8eSAndroid Build Coastguard Worker                 case TransactionCode::SET_EFFECT_SUSPENDED:
5229*ec779b8eSAndroid Build Coastguard Worker                     break;
5230*ec779b8eSAndroid Build Coastguard Worker                 default:
5231*ec779b8eSAndroid Build Coastguard Worker                     return INVALID_OPERATION;
5232*ec779b8eSAndroid Build Coastguard Worker             }
5233*ec779b8eSAndroid Build Coastguard Worker             // Fail silently in these cases.
5234*ec779b8eSAndroid Build Coastguard Worker             return OK;
5235*ec779b8eSAndroid Build Coastguard Worker         default:
5236*ec779b8eSAndroid Build Coastguard Worker             break;
5237*ec779b8eSAndroid Build Coastguard Worker     }
5238*ec779b8eSAndroid Build Coastguard Worker 
5239*ec779b8eSAndroid Build Coastguard Worker     // make sure the following transactions come from system components
5240*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
5241*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MASTER_VOLUME:
5242*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MASTER_MUTE:
5243*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::MASTER_MUTE:
5244*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::GET_SOUND_DOSE_INTERFACE:
5245*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MODE:
5246*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MIC_MUTE:
5247*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_LOW_RAM_DEVICE:
5248*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SYSTEM_READY:
5249*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_AUDIO_HAL_PIDS:
5250*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_VIBRATOR_INFOS:
5251*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::UPDATE_SECONDARY_OUTPUTS:
5252*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_BLUETOOTH_VARIABLE_LATENCY_ENABLED:
5253*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::IS_BLUETOOTH_VARIABLE_LATENCY_ENABLED:
5254*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SUPPORTS_BLUETOOTH_VARIABLE_LATENCY: {
5255*ec779b8eSAndroid Build Coastguard Worker             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
5256*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
5257*ec779b8eSAndroid Build Coastguard Worker                       __func__, static_cast<int>(code),
5258*ec779b8eSAndroid Build Coastguard Worker                       IPCThreadState::self()->getCallingPid(),
5259*ec779b8eSAndroid Build Coastguard Worker                       IPCThreadState::self()->getCallingUid());
5260*ec779b8eSAndroid Build Coastguard Worker                 // return status only for non-void methods
5261*ec779b8eSAndroid Build Coastguard Worker                 switch (code) {
5262*ec779b8eSAndroid Build Coastguard Worker                     case TransactionCode::SYSTEM_READY:
5263*ec779b8eSAndroid Build Coastguard Worker                         break;
5264*ec779b8eSAndroid Build Coastguard Worker                     default:
5265*ec779b8eSAndroid Build Coastguard Worker                         return INVALID_OPERATION;
5266*ec779b8eSAndroid Build Coastguard Worker                 }
5267*ec779b8eSAndroid Build Coastguard Worker                 // Fail silently in these cases.
5268*ec779b8eSAndroid Build Coastguard Worker                 return OK;
5269*ec779b8eSAndroid Build Coastguard Worker             }
5270*ec779b8eSAndroid Build Coastguard Worker         } break;
5271*ec779b8eSAndroid Build Coastguard Worker         default:
5272*ec779b8eSAndroid Build Coastguard Worker             break;
5273*ec779b8eSAndroid Build Coastguard Worker     }
5274*ec779b8eSAndroid Build Coastguard Worker 
5275*ec779b8eSAndroid Build Coastguard Worker     // List of relevant events that trigger log merging.
5276*ec779b8eSAndroid Build Coastguard Worker     // Log merging should activate during audio activity of any kind. This are considered the
5277*ec779b8eSAndroid Build Coastguard Worker     // most relevant events.
5278*ec779b8eSAndroid Build Coastguard Worker     // TODO should select more wisely the items from the list
5279*ec779b8eSAndroid Build Coastguard Worker     switch (code) {
5280*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::CREATE_TRACK:
5281*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::CREATE_RECORD:
5282*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MASTER_VOLUME:
5283*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MASTER_MUTE:
5284*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_MIC_MUTE:
5285*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SET_PARAMETERS:
5286*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::CREATE_EFFECT:
5287*ec779b8eSAndroid Build Coastguard Worker         case TransactionCode::SYSTEM_READY: {
5288*ec779b8eSAndroid Build Coastguard Worker             requestLogMerge();
5289*ec779b8eSAndroid Build Coastguard Worker             break;
5290*ec779b8eSAndroid Build Coastguard Worker         }
5291*ec779b8eSAndroid Build Coastguard Worker         default:
5292*ec779b8eSAndroid Build Coastguard Worker             break;
5293*ec779b8eSAndroid Build Coastguard Worker     }
5294*ec779b8eSAndroid Build Coastguard Worker 
5295*ec779b8eSAndroid Build Coastguard Worker     const std::string methodName = getIAudioFlingerStatistics().getMethodForCode(code);
5296*ec779b8eSAndroid Build Coastguard Worker     mediautils::TimeCheck check(
5297*ec779b8eSAndroid Build Coastguard Worker             std::string("IAudioFlinger::").append(methodName),
5298*ec779b8eSAndroid Build Coastguard Worker             [code, methodName](bool timeout, float elapsedMs) { // don't move methodName.
5299*ec779b8eSAndroid Build Coastguard Worker         if (timeout) {
5300*ec779b8eSAndroid Build Coastguard Worker             mediametrics::LogItem(mMetricsId)
5301*ec779b8eSAndroid Build Coastguard Worker                 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_TIMEOUT)
5302*ec779b8eSAndroid Build Coastguard Worker                 .set(AMEDIAMETRICS_PROP_METHODCODE, int64_t(code))
5303*ec779b8eSAndroid Build Coastguard Worker                 .set(AMEDIAMETRICS_PROP_METHODNAME, methodName.c_str())
5304*ec779b8eSAndroid Build Coastguard Worker                 .record();
5305*ec779b8eSAndroid Build Coastguard Worker         } else {
5306*ec779b8eSAndroid Build Coastguard Worker             getIAudioFlingerStatistics().event(code, elapsedMs);
5307*ec779b8eSAndroid Build Coastguard Worker         }
5308*ec779b8eSAndroid Build Coastguard Worker     }, mediautils::TimeCheck::getDefaultTimeoutDuration(),
5309*ec779b8eSAndroid Build Coastguard Worker     mediautils::TimeCheck::getDefaultSecondChanceDuration(),
5310*ec779b8eSAndroid Build Coastguard Worker     !property_get_bool("audio.timecheck.disabled", false) /* crashOnTimeout */);
5311*ec779b8eSAndroid Build Coastguard Worker 
5312*ec779b8eSAndroid Build Coastguard Worker     return delegate();
5313*ec779b8eSAndroid Build Coastguard Worker }
5314*ec779b8eSAndroid Build Coastguard Worker 
5315*ec779b8eSAndroid Build Coastguard Worker } // namespace android
5316