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