blob: 9020342e77f277e74bb188a7ed9985ea3f798048 [file] [log] [blame]
Eric Laurent81784c32012-11-19 14:55:58 -08001/*
2**
3** Copyright 2012, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
Andy Hung71742ab2023-07-07 13:47:37 -070018#pragma once
Eric Laurent81784c32012-11-19 14:55:58 -080019
Andy Hung4d693a32023-07-19 12:47:35 -070020// ADD_BATTERY_DATA AUDIO_WATCHDOG FAST_THREAD_STATISTICS STATE_QUEUE_DUMP TEE_SINK
21#include "Configuration.h"
22#include "IAfThread.h"
23#include "IAfTrack.h"
24
25#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
26#include <android/os/IPowerManager.h>
27#include <afutils/AudioWatchdog.h>
28#include <afutils/NBAIO_Tee.h>
29#include <audio_utils/Balance.h>
30#include <audio_utils/SimpleLog.h>
31#include <datapath/ThreadMetrics.h>
32#include <fastpath/FastCapture.h>
33#include <fastpath/FastMixer.h>
34#include <mediautils/Synchronization.h>
35#include <mediautils/ThreadSnapshot.h>
36#include <timing/MonotonicFrameCounter.h>
37#include <utils/Log.h>
38
Andy Hung71742ab2023-07-07 13:47:37 -070039namespace android {
Andy Hung4989d312023-06-29 21:19:25 -070040
41class AsyncCallbackThread;
42
43class ThreadBase : public virtual IAfThreadBase, public Thread {
Eric Laurent81784c32012-11-19 14:55:58 -080044public:
Glenn Kasten97b7b752014-09-28 13:04:24 -070045 static const char *threadTypeToString(type_t type);
46
Andy Hung2cbc2722023-07-17 17:05:00 -070047 IAfThreadCallback* afThreadCallback() const final { return mAfThreadCallback.get(); }
Andy Hung44f27182023-07-06 20:56:16 -070048
Andy Hung2cbc2722023-07-17 17:05:00 -070049 ThreadBase(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
Andy Hungcf10d742020-04-28 15:38:24 -070050 type_t type, bool systemReady, bool isOut);
Andy Hung4989d312023-06-29 21:19:25 -070051 ~ThreadBase() override;
Eric Laurent81784c32012-11-19 14:55:58 -080052
Andy Hung4989d312023-06-29 21:19:25 -070053 status_t readyToRun() final;
Andy Hung94dfbb42023-09-06 19:41:47 -070054 void clearPowerManager() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -080055
56 // base for record and playback
57 enum {
58 CFG_EVENT_IO,
Eric Laurent10351942014-05-08 18:49:52 -070059 CFG_EVENT_PRIO,
60 CFG_EVENT_SET_PARAMETER,
Eric Laurent1c333e22014-05-20 10:48:17 -070061 CFG_EVENT_CREATE_AUDIO_PATCH,
62 CFG_EVENT_RELEASE_AUDIO_PATCH,
jiabinc52b1ff2019-10-31 17:20:42 -070063 CFG_EVENT_UPDATE_OUT_DEVICE,
Eric Laurentb3f315a2021-07-13 15:09:05 +020064 CFG_EVENT_RESIZE_BUFFER,
Eric Laurent6f9534f2022-05-03 18:15:04 +020065 CFG_EVENT_CHECK_OUTPUT_STAGE_EFFECTS,
66 CFG_EVENT_HAL_LATENCY_MODES_CHANGED,
Eric Laurent81784c32012-11-19 14:55:58 -080067 };
68
Eric Laurent10351942014-05-08 18:49:52 -070069 class ConfigEventData: public RefBase {
Eric Laurent81784c32012-11-19 14:55:58 -080070 public:
Eric Laurent81784c32012-11-19 14:55:58 -080071 virtual void dump(char *buffer, size_t size) = 0;
Eric Laurent10351942014-05-08 18:49:52 -070072 protected:
Andy Hung94dfbb42023-09-06 19:41:47 -070073 ConfigEventData() = default;
Eric Laurent81784c32012-11-19 14:55:58 -080074 };
75
Eric Laurent10351942014-05-08 18:49:52 -070076 // Config event sequence by client if status needed (e.g binder thread calling setParameters()):
77 // 1. create SetParameterConfigEvent. This sets mWaitStatus in config event
Andy Hung87e82412023-08-29 14:26:09 -070078 // 2. Lock mutex()
Eric Laurent10351942014-05-08 18:49:52 -070079 // 3. Call sendConfigEvent_l(): Append to mConfigEvents and mWaitWorkCV.signal
80 // 4. sendConfigEvent_l() reads status from event->mStatus;
81 // 5. sendConfigEvent_l() returns status
82 // 6. Unlock
83 //
84 // Parameter sequence by server: threadLoop calling processConfigEvents_l():
Andy Hung87e82412023-08-29 14:26:09 -070085 // 1. Lock mutex()
Eric Laurent10351942014-05-08 18:49:52 -070086 // 2. If there is an entry in mConfigEvents proceed ...
87 // 3. Read first entry in mConfigEvents
88 // 4. Remove first entry from mConfigEvents
89 // 5. Process
90 // 6. Set event->mStatus
Andy Hung87e82412023-08-29 14:26:09 -070091 // 7. event->mCondition.notify_one()
Eric Laurent10351942014-05-08 18:49:52 -070092 // 8. Unlock
Eric Laurent81784c32012-11-19 14:55:58 -080093
Eric Laurent10351942014-05-08 18:49:52 -070094 class ConfigEvent: public RefBase {
95 public:
Eric Laurentb3f315a2021-07-13 15:09:05 +020096 void dump(char *buffer, size_t size) {
97 snprintf(buffer, size, "Event type: %d\n", mType);
98 if (mData != nullptr) {
99 snprintf(buffer, size, "Data:\n");
100 mData->dump(buffer, size);
101 }
102 }
Eric Laurent10351942014-05-08 18:49:52 -0700103
Andy Hung94dfbb42023-09-06 19:41:47 -0700104 audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::ConfigEvent_Mutex) {
105 return mMutex;
106 }
Eric Laurent10351942014-05-08 18:49:52 -0700107 const int mType; // event type e.g. CFG_EVENT_IO
Andy Hung87e82412023-08-29 14:26:09 -0700108 mutable audio_utils::mutex mMutex; // mutex associated with mCondition
109 audio_utils::condition_variable mCondition; // condition for status return
Andy Hung94dfbb42023-09-06 19:41:47 -0700110
111 // NO_THREAD_SAFETY_ANALYSIS Can we add GUARDED_BY?
Eric Laurent10351942014-05-08 18:49:52 -0700112 status_t mStatus; // status communicated to sender
Andy Hung94dfbb42023-09-06 19:41:47 -0700113
114 bool mWaitStatus GUARDED_BY(mutex()); // true if sender is waiting for status
115 // true if must wait for system ready to enter event queue
116 bool mRequiresSystemReady GUARDED_BY(mutex());
117
118 // NO_THREAD_SAFETY_ANALYSIS Can we add GUARDED_BY?
119 sp<ConfigEventData> mData; // event specific parameter data
Eric Laurent10351942014-05-08 18:49:52 -0700120
121 protected:
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700122 explicit ConfigEvent(int type, bool requiresSystemReady = false) :
Eric Laurent72e3f392015-05-20 14:43:50 -0700123 mType(type), mStatus(NO_ERROR), mWaitStatus(false),
124 mRequiresSystemReady(requiresSystemReady), mData(NULL) {}
Eric Laurent10351942014-05-08 18:49:52 -0700125 };
126
127 class IoConfigEventData : public ConfigEventData {
128 public:
Mikhail Naganov88536df2021-07-26 17:30:29 -0700129 IoConfigEventData(audio_io_config_event_t event, pid_t pid,
Eric Laurent09f1ed22019-04-24 17:45:17 -0700130 audio_port_handle_t portId) :
131 mEvent(event), mPid(pid), mPortId(portId) {}
Eric Laurent81784c32012-11-19 14:55:58 -0800132
133 virtual void dump(char *buffer, size_t size) {
Eric Laurentb3f315a2021-07-13 15:09:05 +0200134 snprintf(buffer, size, "- IO event: event %d\n", mEvent);
Eric Laurent81784c32012-11-19 14:55:58 -0800135 }
136
Mikhail Naganov88536df2021-07-26 17:30:29 -0700137 const audio_io_config_event_t mEvent;
Eric Laurent7c1ec5f2015-07-09 14:52:47 -0700138 const pid_t mPid;
Eric Laurent09f1ed22019-04-24 17:45:17 -0700139 const audio_port_handle_t mPortId;
Eric Laurent81784c32012-11-19 14:55:58 -0800140 };
141
Eric Laurent10351942014-05-08 18:49:52 -0700142 class IoConfigEvent : public ConfigEvent {
Eric Laurent81784c32012-11-19 14:55:58 -0800143 public:
Mikhail Naganov88536df2021-07-26 17:30:29 -0700144 IoConfigEvent(audio_io_config_event_t event, pid_t pid, audio_port_handle_t portId) :
Eric Laurent10351942014-05-08 18:49:52 -0700145 ConfigEvent(CFG_EVENT_IO) {
Eric Laurent09f1ed22019-04-24 17:45:17 -0700146 mData = new IoConfigEventData(event, pid, portId);
Eric Laurent10351942014-05-08 18:49:52 -0700147 }
Eric Laurent10351942014-05-08 18:49:52 -0700148 };
Eric Laurent81784c32012-11-19 14:55:58 -0800149
Eric Laurent10351942014-05-08 18:49:52 -0700150 class PrioConfigEventData : public ConfigEventData {
151 public:
Mikhail Naganov83f04272017-02-07 10:45:09 -0800152 PrioConfigEventData(pid_t pid, pid_t tid, int32_t prio, bool forApp) :
153 mPid(pid), mTid(tid), mPrio(prio), mForApp(forApp) {}
Eric Laurent81784c32012-11-19 14:55:58 -0800154
155 virtual void dump(char *buffer, size_t size) {
Eric Laurentb3f315a2021-07-13 15:09:05 +0200156 snprintf(buffer, size, "- Prio event: pid %d, tid %d, prio %d, for app? %d\n",
Mikhail Naganov83f04272017-02-07 10:45:09 -0800157 mPid, mTid, mPrio, mForApp);
Eric Laurent81784c32012-11-19 14:55:58 -0800158 }
159
Eric Laurent81784c32012-11-19 14:55:58 -0800160 const pid_t mPid;
161 const pid_t mTid;
162 const int32_t mPrio;
Mikhail Naganov83f04272017-02-07 10:45:09 -0800163 const bool mForApp;
Eric Laurent81784c32012-11-19 14:55:58 -0800164 };
165
Eric Laurent10351942014-05-08 18:49:52 -0700166 class PrioConfigEvent : public ConfigEvent {
167 public:
Mikhail Naganov83f04272017-02-07 10:45:09 -0800168 PrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) :
Eric Laurent72e3f392015-05-20 14:43:50 -0700169 ConfigEvent(CFG_EVENT_PRIO, true) {
Mikhail Naganov83f04272017-02-07 10:45:09 -0800170 mData = new PrioConfigEventData(pid, tid, prio, forApp);
Eric Laurent10351942014-05-08 18:49:52 -0700171 }
Eric Laurent10351942014-05-08 18:49:52 -0700172 };
173
174 class SetParameterConfigEventData : public ConfigEventData {
175 public:
Andy Hung71ba4b32022-10-06 12:09:49 -0700176 explicit SetParameterConfigEventData(const String8& keyValuePairs) :
Eric Laurent10351942014-05-08 18:49:52 -0700177 mKeyValuePairs(keyValuePairs) {}
178
179 virtual void dump(char *buffer, size_t size) {
Tomasz Wasilczyk8f36f6e2023-08-15 20:59:35 +0000180 snprintf(buffer, size, "- KeyValue: %s\n", mKeyValuePairs.c_str());
Eric Laurent10351942014-05-08 18:49:52 -0700181 }
182
183 const String8 mKeyValuePairs;
184 };
185
186 class SetParameterConfigEvent : public ConfigEvent {
187 public:
Andy Hung71ba4b32022-10-06 12:09:49 -0700188 explicit SetParameterConfigEvent(const String8& keyValuePairs) :
Eric Laurent10351942014-05-08 18:49:52 -0700189 ConfigEvent(CFG_EVENT_SET_PARAMETER) {
190 mData = new SetParameterConfigEventData(keyValuePairs);
191 mWaitStatus = true;
192 }
Eric Laurent10351942014-05-08 18:49:52 -0700193 };
194
Eric Laurent1c333e22014-05-20 10:48:17 -0700195 class CreateAudioPatchConfigEventData : public ConfigEventData {
196 public:
197 CreateAudioPatchConfigEventData(const struct audio_patch patch,
198 audio_patch_handle_t handle) :
199 mPatch(patch), mHandle(handle) {}
200
201 virtual void dump(char *buffer, size_t size) {
Eric Laurentb3f315a2021-07-13 15:09:05 +0200202 snprintf(buffer, size, "- Patch handle: %u\n", mHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -0700203 }
204
205 const struct audio_patch mPatch;
Andy Hung94dfbb42023-09-06 19:41:47 -0700206 audio_patch_handle_t mHandle; // cannot be const
Eric Laurent1c333e22014-05-20 10:48:17 -0700207 };
208
209 class CreateAudioPatchConfigEvent : public ConfigEvent {
210 public:
211 CreateAudioPatchConfigEvent(const struct audio_patch patch,
212 audio_patch_handle_t handle) :
213 ConfigEvent(CFG_EVENT_CREATE_AUDIO_PATCH) {
214 mData = new CreateAudioPatchConfigEventData(patch, handle);
215 mWaitStatus = true;
216 }
Eric Laurent1c333e22014-05-20 10:48:17 -0700217 };
218
219 class ReleaseAudioPatchConfigEventData : public ConfigEventData {
220 public:
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700221 explicit ReleaseAudioPatchConfigEventData(const audio_patch_handle_t handle) :
Eric Laurent1c333e22014-05-20 10:48:17 -0700222 mHandle(handle) {}
223
224 virtual void dump(char *buffer, size_t size) {
Eric Laurentb3f315a2021-07-13 15:09:05 +0200225 snprintf(buffer, size, "- Patch handle: %u\n", mHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -0700226 }
227
Andy Hung94dfbb42023-09-06 19:41:47 -0700228 const audio_patch_handle_t mHandle;
Eric Laurent1c333e22014-05-20 10:48:17 -0700229 };
230
231 class ReleaseAudioPatchConfigEvent : public ConfigEvent {
232 public:
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700233 explicit ReleaseAudioPatchConfigEvent(const audio_patch_handle_t handle) :
Eric Laurent1c333e22014-05-20 10:48:17 -0700234 ConfigEvent(CFG_EVENT_RELEASE_AUDIO_PATCH) {
235 mData = new ReleaseAudioPatchConfigEventData(handle);
236 mWaitStatus = true;
237 }
Eric Laurent1c333e22014-05-20 10:48:17 -0700238 };
Eric Laurent81784c32012-11-19 14:55:58 -0800239
jiabinc52b1ff2019-10-31 17:20:42 -0700240 class UpdateOutDevicesConfigEventData : public ConfigEventData {
241 public:
242 explicit UpdateOutDevicesConfigEventData(const DeviceDescriptorBaseVector& outDevices) :
243 mOutDevices(outDevices) {}
244
245 virtual void dump(char *buffer, size_t size) {
Eric Laurentb3f315a2021-07-13 15:09:05 +0200246 snprintf(buffer, size, "- Devices: %s", android::toString(mOutDevices).c_str());
jiabinc52b1ff2019-10-31 17:20:42 -0700247 }
248
Andy Hung94dfbb42023-09-06 19:41:47 -0700249 const DeviceDescriptorBaseVector mOutDevices;
jiabinc52b1ff2019-10-31 17:20:42 -0700250 };
251
252 class UpdateOutDevicesConfigEvent : public ConfigEvent {
253 public:
254 explicit UpdateOutDevicesConfigEvent(const DeviceDescriptorBaseVector& outDevices) :
255 ConfigEvent(CFG_EVENT_UPDATE_OUT_DEVICE) {
256 mData = new UpdateOutDevicesConfigEventData(outDevices);
257 }
jiabinc52b1ff2019-10-31 17:20:42 -0700258 };
259
Eric Laurentec376dc2021-04-08 20:41:22 +0200260 class ResizeBufferConfigEventData : public ConfigEventData {
261 public:
262 explicit ResizeBufferConfigEventData(int32_t maxSharedAudioHistoryMs) :
263 mMaxSharedAudioHistoryMs(maxSharedAudioHistoryMs) {}
264
265 virtual void dump(char *buffer, size_t size) {
Eric Laurentb3f315a2021-07-13 15:09:05 +0200266 snprintf(buffer, size, "- mMaxSharedAudioHistoryMs: %d", mMaxSharedAudioHistoryMs);
Eric Laurentec376dc2021-04-08 20:41:22 +0200267 }
268
Andy Hung94dfbb42023-09-06 19:41:47 -0700269 const int32_t mMaxSharedAudioHistoryMs;
Eric Laurentec376dc2021-04-08 20:41:22 +0200270 };
271
272 class ResizeBufferConfigEvent : public ConfigEvent {
273 public:
274 explicit ResizeBufferConfigEvent(int32_t maxSharedAudioHistoryMs) :
275 ConfigEvent(CFG_EVENT_RESIZE_BUFFER) {
276 mData = new ResizeBufferConfigEventData(maxSharedAudioHistoryMs);
277 }
Eric Laurentec376dc2021-04-08 20:41:22 +0200278 };
279
Eric Laurentb3f315a2021-07-13 15:09:05 +0200280 class CheckOutputStageEffectsEvent : public ConfigEvent {
281 public:
282 CheckOutputStageEffectsEvent() :
283 ConfigEvent(CFG_EVENT_CHECK_OUTPUT_STAGE_EFFECTS) {
284 }
Eric Laurentb3f315a2021-07-13 15:09:05 +0200285 };
286
Eric Laurent6f9534f2022-05-03 18:15:04 +0200287 class HalLatencyModesChangedEvent : public ConfigEvent {
288 public:
289 HalLatencyModesChangedEvent() :
290 ConfigEvent(CFG_EVENT_HAL_LATENCY_MODES_CHANGED) {
291 }
Eric Laurent6f9534f2022-05-03 18:15:04 +0200292 };
293
Eric Laurentb3f315a2021-07-13 15:09:05 +0200294
Eric Laurent81784c32012-11-19 14:55:58 -0800295 class PMDeathRecipient : public IBinder::DeathRecipient {
296 public:
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -0700297 explicit PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {}
Eric Laurent81784c32012-11-19 14:55:58 -0800298
299 // IBinder::DeathRecipient
Andy Hung94dfbb42023-09-06 19:41:47 -0700300 void binderDied(const wp<IBinder>& who) final;
Eric Laurent81784c32012-11-19 14:55:58 -0800301
302 private:
Mikhail Naganovbf493082017-04-17 17:37:12 -0700303 DISALLOW_COPY_AND_ASSIGN(PMDeathRecipient);
Eric Laurent81784c32012-11-19 14:55:58 -0800304
Andy Hung94dfbb42023-09-06 19:41:47 -0700305 const wp<ThreadBase> mThread;
Eric Laurent81784c32012-11-19 14:55:58 -0800306 };
307
Andy Hung4989d312023-06-29 21:19:25 -0700308 type_t type() const final { return mType; }
309 bool isDuplicating() const final { return (mType == DUPLICATING); }
310 audio_io_handle_t id() const final { return mId;}
Eric Laurent81784c32012-11-19 14:55:58 -0800311
Andy Hung4989d312023-06-29 21:19:25 -0700312 uint32_t sampleRate() const final { return mSampleRate; }
313 audio_channel_mask_t channelMask() const final { return mChannelMask; }
314 audio_channel_mask_t mixerChannelMask() const override { return mChannelMask; }
315 audio_format_t format() const final { return mHALFormat; }
316 uint32_t channelCount() const final { return mChannelCount; }
317 audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
Andy Hung44f27182023-07-06 20:56:16 -0700318 uint32_t hapticChannelCount() const override { return 0; }
Andy Hung94dfbb42023-09-06 19:41:47 -0700319 uint32_t latency_l() const override { return 0; } // NO_THREAD_SAFETY_ANALYSIS
320 void setVolumeForOutput_l(float /* left */, float /* right */) const override
321 REQUIRES(mutex()) {}
Glenn Kasten4a8308b2016-04-18 14:10:01 -0700322
323 // Return's the HAL's frame count i.e. fast mixer buffer size.
Andy Hung4989d312023-06-29 21:19:25 -0700324 size_t frameCountHAL() const final { return mFrameCount; }
325 size_t frameSize() const final { return mFrameSize; }
Eric Laurent81784c32012-11-19 14:55:58 -0800326
327 // Should be "virtual status_t requestExitAndWait()" and override same
328 // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
Andy Hung94dfbb42023-09-06 19:41:47 -0700329 void exit() final EXCLUDES_ThreadBase_Mutex;
330 status_t setParameters(const String8& keyValuePairs) final EXCLUDES_ThreadBase_Mutex;
Andy Hung4989d312023-06-29 21:19:25 -0700331
Andy Hung87e82412023-08-29 14:26:09 -0700332 // sendConfigEvent_l() must be called with ThreadBase::mutex() held
Eric Laurent10351942014-05-08 18:49:52 -0700333 // Can temporarily release the lock if waiting for a reply from
334 // processConfigEvents_l().
Andy Hung94dfbb42023-09-06 19:41:47 -0700335 status_t sendConfigEvent_l(sp<ConfigEvent>& event) REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -0700336 void sendIoConfigEvent(audio_io_config_event_t event, pid_t pid = 0,
Andy Hung94dfbb42023-09-06 19:41:47 -0700337 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final EXCLUDES_ThreadBase_Mutex;
Andy Hung4989d312023-06-29 21:19:25 -0700338 void sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid = 0,
Andy Hung94dfbb42023-09-06 19:41:47 -0700339 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final REQUIRES(mutex());
340 void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) final
341 EXCLUDES_ThreadBase_Mutex;
342 void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp) final
343 REQUIRES(mutex());
344 status_t sendSetParameterConfigEvent_l(const String8& keyValuePair) final REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -0700345 status_t sendCreateAudioPatchConfigEvent(const struct audio_patch* patch,
Andy Hung94dfbb42023-09-06 19:41:47 -0700346 audio_patch_handle_t* handle) final EXCLUDES_ThreadBase_Mutex;
347 status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle) final
348 EXCLUDES_ThreadBase_Mutex;
Andy Hung4989d312023-06-29 21:19:25 -0700349 status_t sendUpdateOutDeviceConfigEvent(
Andy Hung94dfbb42023-09-06 19:41:47 -0700350 const DeviceDescriptorBaseVector& outDevices) final EXCLUDES_ThreadBase_Mutex;
351 void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs) final REQUIRES(mutex());
352 void sendCheckOutputStageEffectsEvent() final EXCLUDES_ThreadBase_Mutex;
353 void sendCheckOutputStageEffectsEvent_l() final REQUIRES(mutex());
354 void sendHalLatencyModesChangedEvent_l() final REQUIRES(mutex());
Eric Laurentb3f315a2021-07-13 15:09:05 +0200355
Andy Hung94dfbb42023-09-06 19:41:47 -0700356 void processConfigEvents_l() final REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -0700357 void setCheckOutputStageEffects() override {}
358 void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override;
359 void toAudioPortConfig(struct audio_port_config* config) override;
Andy Hung94dfbb42023-09-06 19:41:47 -0700360 void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override REQUIRES(mutex());
Eric Laurent1c333e22014-05-20 10:48:17 -0700361
Andy Hung4989d312023-06-29 21:19:25 -0700362 // see note at declaration of mStandby, mOutDevice and mInDevice
363 bool inStandby() const override { return mStandby; }
Andy Hung94dfbb42023-09-06 19:41:47 -0700364 const DeviceTypeSet outDeviceTypes_l() const final REQUIRES(mutex()) {
Andy Hung4989d312023-06-29 21:19:25 -0700365 return getAudioDeviceTypes(mOutDeviceTypeAddrs);
366 }
Andy Hung94dfbb42023-09-06 19:41:47 -0700367 audio_devices_t inDeviceType_l() const final REQUIRES(mutex()) {
368 return mInDeviceTypeAddr.mType;
369 }
370 DeviceTypeSet getDeviceTypes_l() const final REQUIRES(mutex()) {
371 return isOutput() ? outDeviceTypes_l() : DeviceTypeSet({inDeviceType_l()});
Andy Hung4989d312023-06-29 21:19:25 -0700372 }
Eric Laurent81784c32012-11-19 14:55:58 -0800373
Andy Hung4989d312023-06-29 21:19:25 -0700374 const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const final {
375 return mOutDeviceTypeAddrs;
376 }
377 const AudioDeviceTypeAddr& inDeviceTypeAddr() const final {
378 return mInDeviceTypeAddr;
379 }
Andy Hung293558a2017-03-21 12:19:20 -0700380
Andy Hung4989d312023-06-29 21:19:25 -0700381 bool isOutput() const final { return mIsOut; }
jiabin8f278ee2019-11-11 12:16:27 -0800382
Andy Hung4989d312023-06-29 21:19:25 -0700383 bool isOffloadOrMmap() const final {
384 switch (mType) {
385 case OFFLOAD:
386 case MMAP_PLAYBACK:
387 case MMAP_CAPTURE:
388 return true;
389 default:
390 return false;
391 }
392 }
Eric Laurent81784c32012-11-19 14:55:58 -0800393
Andy Hung4989d312023-06-29 21:19:25 -0700394 sp<IAfEffectHandle> createEffect_l(
Andy Hungd65869f2023-06-27 17:05:02 -0700395 const sp<Client>& client,
Ytai Ben-Tsvi9cd89812020-07-01 17:12:06 -0700396 const sp<media::IEffectClient>& effectClient,
Eric Laurent81784c32012-11-19 14:55:58 -0800397 int32_t priority,
Glenn Kastend848eb42016-03-08 13:42:11 -0800398 audio_session_t sessionId,
Eric Laurent81784c32012-11-19 14:55:58 -0800399 effect_descriptor_t *desc,
400 int *enabled,
Eric Laurent0d5a2ed2016-12-01 15:28:29 -0800401 status_t *status /*non-NULL*/,
Eric Laurent2fe0acd2020-03-13 14:30:46 -0700402 bool pinned,
Eric Laurentde8caf42021-08-11 17:19:25 +0200403 bool probe,
Andy Hungf79092d2023-08-31 16:13:39 -0700404 bool notifyFramesProcessed) final
405 REQUIRES(audio_utils::AudioFlinger_Mutex);
Eric Laurent81784c32012-11-19 14:55:58 -0800406
407 // return values for hasAudioSession (bit field)
408 enum effect_state {
409 EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
410 // effect
Eric Laurent4c415062016-06-17 16:14:16 -0700411 TRACK_SESSION = 0x2, // the audio session corresponds to at least one
Eric Laurent81784c32012-11-19 14:55:58 -0800412 // track
Eric Laurentb62d0362021-10-26 17:40:18 +0200413 FAST_SESSION = 0x4, // the audio session corresponds to at least one
Eric Laurent4c415062016-06-17 16:14:16 -0700414 // fast track
jiabinc658e452022-10-21 20:52:21 +0000415 SPATIALIZED_SESSION = 0x8, // the audio session corresponds to at least one
416 // spatialized track
417 BIT_PERFECT_SESSION = 0x10 // the audio session corresponds to at least one
418 // bit-perfect track
Eric Laurent81784c32012-11-19 14:55:58 -0800419 };
420
Andy Hung4989d312023-06-29 21:19:25 -0700421 // get effect chain corresponding to session Id.
422 sp<IAfEffectChain> getEffectChain(audio_session_t sessionId) const final;
423 // same as getEffectChain() but must be called with ThreadBase mutex locked
424 sp<IAfEffectChain> getEffectChain_l(audio_session_t sessionId) const final;
425 std::vector<int> getEffectIds_l(audio_session_t sessionId) const final;
426
Eric Laurent81784c32012-11-19 14:55:58 -0800427 // lock all effect chains Mutexes. Must be called before releasing the
428 // ThreadBase mutex before processing the mixer and effects. This guarantees the
429 // integrity of the chains during the process.
430 // Also sets the parameter 'effectChains' to current value of mEffectChains.
Andy Hung94dfbb42023-09-06 19:41:47 -0700431 void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains) final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -0800432 // unlock effect chains after process
Andy Hung4989d312023-06-29 21:19:25 -0700433 void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains) final;
Eric Laurentbfb1b832013-01-07 09:53:42 -0800434 // get a copy of mEffectChains vector
Andy Hung94dfbb42023-09-06 19:41:47 -0700435 Vector<sp<IAfEffectChain>> getEffectChains_l() const final REQUIRES(mutex()) {
436 return mEffectChains;
437 }
Eric Laurent81784c32012-11-19 14:55:58 -0800438 // set audio mode to all effect chains
Andy Hung4989d312023-06-29 21:19:25 -0700439 void setMode(audio_mode_t mode) final;
Eric Laurent81784c32012-11-19 14:55:58 -0800440 // get effect module with corresponding ID on specified audio session
Andy Hung4989d312023-06-29 21:19:25 -0700441 sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId) const final;
Andy Hung94dfbb42023-09-06 19:41:47 -0700442 sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const final
443 REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -0800444 // add and effect module. Also creates the effect chain is none exists for
Eric Laurent6c796322019-04-09 14:13:17 -0700445 // the effects audio session. Only called in a context of moving an effect
446 // from one thread to another
Andy Hungf79092d2023-08-31 16:13:39 -0700447 status_t addEffect_ll(const sp<IAfEffectModule>& effect) final
448 REQUIRES(audio_utils::AudioFlinger_Mutex, mutex());
Eric Laurent81784c32012-11-19 14:55:58 -0800449 // remove and effect module. Also removes the effect chain is this was the last
450 // effect
Andy Hung94dfbb42023-09-06 19:41:47 -0700451 void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) final
452 REQUIRES(mutex());
Eric Laurent0d5a2ed2016-12-01 15:28:29 -0800453 // disconnect an effect handle from module and destroy module if last handle
Andy Hung4989d312023-06-29 21:19:25 -0700454 void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast) final;
Eric Laurent81784c32012-11-19 14:55:58 -0800455 // detach all tracks connected to an auxiliary effect
Andy Hung94dfbb42023-09-06 19:41:47 -0700456 void detachAuxEffect_l(int /* effectId */) override REQUIRES(mutex()) {}
Andy Hung56126702023-07-14 11:00:08 -0700457 // TODO(b/291317898) - remove hasAudioSession_l below.
Andy Hung94dfbb42023-09-06 19:41:47 -0700458 uint32_t hasAudioSession_l(audio_session_t sessionId) const override REQUIRES(mutex()) = 0;
459 uint32_t hasAudioSession(audio_session_t sessionId) const final EXCLUDES_ThreadBase_Mutex {
460 std::lock_guard _l(mutex());
461 return hasAudioSession_l(sessionId);
462 }
Eric Laurent4c415062016-06-17 16:14:16 -0700463
Andy Hungc3d62f92019-03-14 13:38:51 -0700464 template <typename T>
465 uint32_t hasAudioSession_l(audio_session_t sessionId, const T& tracks) const {
466 uint32_t result = 0;
467 if (getEffectChain_l(sessionId) != 0) {
468 result = EFFECT_SESSION;
469 }
470 for (size_t i = 0; i < tracks.size(); ++i) {
Andy Hung3ff4b552023-06-26 19:20:57 -0700471 const sp<IAfTrackBase>& track = tracks[i];
Andy Hungc3d62f92019-03-14 13:38:51 -0700472 if (sessionId == track->sessionId()
473 && !track->isInvalid() // not yet removed from tracks.
474 && !track->isTerminated()) {
475 result |= TRACK_SESSION;
476 if (track->isFastTrack()) {
477 result |= FAST_SESSION; // caution, only represents first track.
478 }
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200479 if (track->isSpatialized()) {
Eric Laurentb62d0362021-10-26 17:40:18 +0200480 result |= SPATIALIZED_SESSION; // caution, only first track.
481 }
jiabinc658e452022-10-21 20:52:21 +0000482 if (track->isBitPerfect()) {
483 result |= BIT_PERFECT_SESSION;
484 }
Andy Hungc3d62f92019-03-14 13:38:51 -0700485 break;
486 }
487 }
488 return result;
489 }
490
Eric Laurent81784c32012-11-19 14:55:58 -0800491 // the value returned by default implementation is not important as the
492 // strategy is only meaningful for PlaybackThread which implements this method
Andy Hung4989d312023-06-29 21:19:25 -0700493 product_strategy_t getStrategyForSession_l(
Andy Hung94dfbb42023-09-06 19:41:47 -0700494 audio_session_t /* sessionId */) const override REQUIRES(mutex()){
495 return static_cast<product_strategy_t>(0);
496 }
Eric Laurent81784c32012-11-19 14:55:58 -0800497
Eric Laurent81784c32012-11-19 14:55:58 -0800498 // check if some effects must be suspended/restored when an effect is enabled
499 // or disabled
Andy Hung4989d312023-06-29 21:19:25 -0700500 void checkSuspendOnEffectEnabled(bool enabled,
Eric Laurent6b446ce2019-12-13 10:56:31 -0800501 audio_session_t sessionId,
Andy Hung4989d312023-06-29 21:19:25 -0700502 bool threadLocked) final;
Eric Laurent81784c32012-11-19 14:55:58 -0800503
Eric Laurent81784c32012-11-19 14:55:58 -0800504
Glenn Kastenb880f5e2014-05-07 08:43:45 -0700505 // Return a reference to a per-thread heap which can be used to allocate IMemory
506 // objects that will be read-only to client processes, read/write to mediaserver,
507 // and shared by all client processes of the thread.
508 // The heap is per-thread rather than common across all threads, because
509 // clients can't be trusted not to modify the offset of the IMemory they receive.
510 // If a thread does not have such a heap, this method returns 0.
Andy Hung4989d312023-06-29 21:19:25 -0700511 sp<MemoryDealer> readOnlyHeap() const override { return nullptr; }
Eric Laurent81784c32012-11-19 14:55:58 -0800512
Andy Hung4989d312023-06-29 21:19:25 -0700513 sp<IMemory> pipeMemory() const override { return nullptr; }
Glenn Kasten6181ffd2014-05-13 10:41:52 -0700514
Andy Hung94dfbb42023-09-06 19:41:47 -0700515 void systemReady() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent72e3f392015-05-20 14:43:50 -0700516
Andy Hung94dfbb42023-09-06 19:41:47 -0700517 void broadcast_l() final REQUIRES(mutex());
Eric Laurent4c415062016-06-17 16:14:16 -0700518
Andy Hung94dfbb42023-09-06 19:41:47 -0700519 bool isTimestampCorrectionEnabled_l() const override REQUIRES(mutex()) { return false; }
Eric Laurent6acd1d42017-01-04 14:23:29 -0800520
Andy Hung4989d312023-06-29 21:19:25 -0700521 bool isMsdDevice() const final { return mIsMsdDevice; }
Andy Hungc8fddf32018-08-08 18:32:37 -0700522
Andy Hung4989d312023-06-29 21:19:25 -0700523 void dump(int fd, const Vector<String16>& args) override;
Andy Hungdc099c22018-09-18 13:46:39 -0700524
Andy Hungd0979812019-02-21 15:51:44 -0800525 // deliver stats to mediametrics.
Andy Hung94dfbb42023-09-06 19:41:47 -0700526 void sendStatistics(bool force) final EXCLUDES_ThreadBase_Mutex;
Andy Hungd0979812019-02-21 15:51:44 -0800527
Andy Hungf79092d2023-08-31 16:13:39 -0700528 audio_utils::mutex& mutex() const final RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) {
Andy Hung87e82412023-08-29 14:26:09 -0700529 return mMutex;
Andy Hung4989d312023-06-29 21:19:25 -0700530 }
Andy Hung87e82412023-08-29 14:26:09 -0700531 mutable audio_utils::mutex mMutex;
Eric Laurent81784c32012-11-19 14:55:58 -0800532
Andy Hung94dfbb42023-09-06 19:41:47 -0700533 void onEffectEnable(const sp<IAfEffectModule>& effect) final EXCLUDES_ThreadBase_Mutex;
534 void onEffectDisable() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6b446ce2019-12-13 10:56:31 -0800535
Andy Hung87e82412023-08-29 14:26:09 -0700536 // invalidateTracksForAudioSession_l must be called with holding mutex().
Andy Hung94dfbb42023-09-06 19:41:47 -0700537 void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override
538 REQUIRES(mutex()) {}
jiabineb3bda02020-06-30 14:07:03 -0700539 // Invalidate all the tracks with the given audio session.
Andy Hung94dfbb42023-09-06 19:41:47 -0700540 void invalidateTracksForAudioSession(audio_session_t sessionId) const final
541 EXCLUDES_ThreadBase_Mutex {
Andy Hung87e82412023-08-29 14:26:09 -0700542 std::lock_guard _l(mutex());
jiabineb3bda02020-06-30 14:07:03 -0700543 invalidateTracksForAudioSession_l(sessionId);
544 }
545
546 template <typename T>
Andy Hung94dfbb42023-09-06 19:41:47 -0700547 void invalidateTracksForAudioSession_l(audio_session_t sessionId,
548 const T& tracks) const REQUIRES(mutex()) {
jiabineb3bda02020-06-30 14:07:03 -0700549 for (size_t i = 0; i < tracks.size(); ++i) {
Andy Hung3ff4b552023-06-26 19:20:57 -0700550 const sp<IAfTrackBase>& track = tracks[i];
jiabineb3bda02020-06-30 14:07:03 -0700551 if (sessionId == track->sessionId()) {
552 track->invalidate();
553 }
554 }
555 }
556
Andy Hungf79092d2023-08-31 16:13:39 -0700557 void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override
558 REQUIRES(audio_utils::AudioFlinger_Mutex);
559 void stopMelComputation_l() override
560 REQUIRES(audio_utils::AudioFlinger_Mutex);
Vlad Popa6fbbfbf2023-02-22 15:05:43 +0100561
Eric Laurent81784c32012-11-19 14:55:58 -0800562protected:
563
564 // entry describing an effect being suspended in mSuspendedSessions keyed vector
565 class SuspendedSessionDesc : public RefBase {
566 public:
567 SuspendedSessionDesc() : mRefCount(0) {}
568
569 int mRefCount; // number of active suspend requests
570 effect_uuid_t mType; // effect type UUID
571 };
572
Andy Hung94dfbb42023-09-06 19:41:47 -0700573 void acquireWakeLock() EXCLUDES_ThreadBase_Mutex;
574 virtual void acquireWakeLock_l() REQUIRES(mutex());
575 void releaseWakeLock() EXCLUDES_ThreadBase_Mutex;
576 void releaseWakeLock_l() REQUIRES(mutex());
577 void updateWakeLockUids_l(const SortedVector<uid_t> &uids) REQUIRES(mutex());
578 void getPowerManager_l() REQUIRES(mutex());
Eric Laurentd8365c52017-07-16 15:27:05 -0700579 // suspend or restore effects of the specified type (or all if type is NULL)
580 // on a given session. The number of suspend requests is counted and restore
581 // occurs when all suspend requests are cancelled.
Andy Hung94dfbb42023-09-06 19:41:47 -0700582 void setEffectSuspended_l(const effect_uuid_t *type,
Eric Laurent81784c32012-11-19 14:55:58 -0800583 bool suspend,
Andy Hung94dfbb42023-09-06 19:41:47 -0700584 audio_session_t sessionId) final REQUIRES(mutex());
Eric Laurentd8365c52017-07-16 15:27:05 -0700585 // updated mSuspendedSessions when an effect is suspended or restored
Andy Hung94dfbb42023-09-06 19:41:47 -0700586 void updateSuspendedSessions_l(const effect_uuid_t *type,
Eric Laurent81784c32012-11-19 14:55:58 -0800587 bool suspend,
Andy Hung94dfbb42023-09-06 19:41:47 -0700588 audio_session_t sessionId) REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -0800589 // check if some effects must be suspended when an effect chain is added
Andy Hung94dfbb42023-09-06 19:41:47 -0700590 void checkSuspendOnAddEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -0800591
Kevin Rocard069c2712018-03-29 19:09:14 -0700592 // sends the metadata of the active tracks to the HAL
Vlad Popa7e81cea2023-01-19 16:34:16 +0100593 struct MetadataUpdate {
594 std::vector<playback_track_metadata_v7_t> playbackMetadataUpdate;
595 std::vector<record_track_metadata_v7_t> recordMetadataUpdate;
596 };
Andy Hung94dfbb42023-09-06 19:41:47 -0700597 virtual MetadataUpdate updateMetadata_l() REQUIRES(mutex()) = 0;
Kevin Rocard069c2712018-03-29 19:09:14 -0700598
Narayan Kamath014e7fa2013-10-14 15:03:38 +0100599 String16 getWakeLockTag();
600
Andy Hung94dfbb42023-09-06 19:41:47 -0700601 virtual void preExit() EXCLUDES_ThreadBase_Mutex {}
602 virtual void setMasterMono_l(bool mono __unused) REQUIRES(mutex()) {}
Andy Hung2ddee192015-12-18 17:34:44 -0800603 virtual bool requireMonoBlend() { return false; }
Eric Laurent81784c32012-11-19 14:55:58 -0800604
Andy Hung1c86ebe2018-05-29 20:29:08 -0700605 // called within the threadLoop to obtain timestamp from the HAL.
Andy Hung94dfbb42023-09-06 19:41:47 -0700606 virtual status_t threadloop_getHalTimestamp_l(
607 ExtendedTimestamp *timestamp __unused) const REQUIRES(mutex()) {
Andy Hung1c86ebe2018-05-29 20:29:08 -0700608 return INVALID_OPERATION;
609 }
Andy Hungbd72c542023-06-20 18:56:17 -0700610public:
Andy Hung56126702023-07-14 11:00:08 -0700611// TODO(b/291317898) organize with publics
Eric Laurentd66d7a12021-07-13 13:35:32 +0200612 product_strategy_t getStrategyForStream(audio_stream_type_t stream) const;
Andy Hungbd72c542023-06-20 18:56:17 -0700613protected:
Eric Laurentd66d7a12021-07-13 13:35:32 +0200614
Andy Hung94dfbb42023-09-06 19:41:47 -0700615 virtual void onHalLatencyModesChanged_l() REQUIRES(mutex()) {}
Eric Laurentb0463942022-12-20 16:31:10 +0100616
Andy Hung94dfbb42023-09-06 19:41:47 -0700617 virtual void dumpInternals_l(int fd __unused, const Vector<String16>& args __unused)
618 REQUIRES(mutex()) {}
619 virtual void dumpTracks_l(int fd __unused, const Vector<String16>& args __unused)
620 REQUIRES(mutex()) {}
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -0700621
Eric Laurent81784c32012-11-19 14:55:58 -0800622 const type_t mType;
623
624 // Used by parameters, config events, addTrack_l, exit
Andy Hung87e82412023-08-29 14:26:09 -0700625 audio_utils::condition_variable mWaitWorkCV;
Eric Laurent81784c32012-11-19 14:55:58 -0800626
Andy Hung2cbc2722023-07-17 17:05:00 -0700627 const sp<IAfThreadCallback> mAfThreadCallback;
Andy Hungcf10d742020-04-28 15:38:24 -0700628 ThreadMetrics mThreadMetrics;
629 const bool mIsOut;
Glenn Kasten9b58f632013-07-16 11:37:48 -0700630
Glenn Kastendeca2ae2014-02-07 10:25:56 -0800631 // updated by PlaybackThread::readOutputParameters_l() or
632 // RecordThread::readInputParameters_l()
Eric Laurent81784c32012-11-19 14:55:58 -0800633 uint32_t mSampleRate;
634 size_t mFrameCount; // output HAL, direct output, record
Eric Laurent81784c32012-11-19 14:55:58 -0800635 audio_channel_mask_t mChannelMask;
Glenn Kastenf6ed4232013-07-16 11:16:27 -0700636 uint32_t mChannelCount;
Eric Laurent81784c32012-11-19 14:55:58 -0800637 size_t mFrameSize;
Glenn Kasten97b7b752014-09-28 13:04:24 -0700638 // not HAL frame size, this is for output sink (to pipe to fast mixer)
Andy Hung463be252014-07-10 16:56:07 -0700639 audio_format_t mFormat; // Source format for Recording and
640 // Sink format for Playback.
641 // Sink format may be different than
642 // HAL format if Fastmixer is used.
643 audio_format_t mHALFormat;
Glenn Kasten70949c42013-08-06 07:40:12 -0700644 size_t mBufferSize; // HAL buffer size for read() or write()
Andy Hung94dfbb42023-09-06 19:41:47 -0700645
646 // output device types and addresses
647 AudioDeviceTypeAddrVector mOutDeviceTypeAddrs GUARDED_BY(mutex());
648 AudioDeviceTypeAddr mInDeviceTypeAddr GUARDED_BY(mutex()); // input device type and address
Eric Laurent10351942014-05-08 18:49:52 -0700649 Vector< sp<ConfigEvent> > mConfigEvents;
Eric Laurent72e3f392015-05-20 14:43:50 -0700650 Vector< sp<ConfigEvent> > mPendingConfigEvents; // events awaiting system ready
Eric Laurent81784c32012-11-19 14:55:58 -0800651
652 // These fields are written and read by thread itself without lock or barrier,
jiabinc52b1ff2019-10-31 17:20:42 -0700653 // and read by other threads without lock or barrier via standby(), outDeviceTypes()
654 // and inDeviceType().
Eric Laurent81784c32012-11-19 14:55:58 -0800655 // Because of the absence of a lock or barrier, any other thread that reads
656 // these fields must use the information in isolation, or be prepared to deal
657 // with possibility that it might be inconsistent with other information.
Glenn Kasten4944acb2013-08-19 08:39:20 -0700658 bool mStandby; // Whether thread is currently in standby.
jiabinc52b1ff2019-10-31 17:20:42 -0700659
Eric Laurent296fb132015-05-01 11:38:42 -0700660 struct audio_patch mPatch;
jiabinc52b1ff2019-10-31 17:20:42 -0700661
Glenn Kastenf59497b2015-01-26 16:35:47 -0800662 audio_source_t mAudioSource;
Eric Laurent81784c32012-11-19 14:55:58 -0800663
664 const audio_io_handle_t mId;
Andy Hungbd72c542023-06-20 18:56:17 -0700665 Vector<sp<IAfEffectChain>> mEffectChains;
Eric Laurent81784c32012-11-19 14:55:58 -0800666
Glenn Kastend7dca052015-03-05 16:05:54 -0800667 static const int kThreadNameLength = 16; // prctl(PR_SET_NAME) limit
668 char mThreadName[kThreadNameLength]; // guaranteed NUL-terminated
Chris Ye6597d732020-02-28 22:38:25 -0800669 sp<os::IPowerManager> mPowerManager;
Eric Laurent81784c32012-11-19 14:55:58 -0800670 sp<IBinder> mWakeLockToken;
671 const sp<PMDeathRecipient> mDeathRecipient;
Glenn Kastend848eb42016-03-08 13:42:11 -0800672 // list of suspended effects per session and per type. The first (outer) vector is
673 // keyed by session ID, the second (inner) by type UUID timeLow field
Eric Laurentd8365c52017-07-16 15:27:05 -0700674 // Updated by updateSuspendedSessions_l() only.
Glenn Kastend848eb42016-03-08 13:42:11 -0800675 KeyedVector< audio_session_t, KeyedVector< int, sp<SuspendedSessionDesc> > >
Eric Laurent81784c32012-11-19 14:55:58 -0800676 mSuspendedSessions;
Sanna Catherine de Treville Wager2a6a9452017-07-28 11:02:01 -0700677 // TODO: add comment and adjust size as needed
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800678 static const size_t kLogSize = 4 * 1024;
Glenn Kasten9e58b552013-01-18 15:09:48 -0800679 sp<NBLog::Writer> mNBLogWriter;
Eric Laurent72e3f392015-05-20 14:43:50 -0700680 bool mSystemReady;
Andy Hung818e7a32016-02-16 18:08:07 -0800681 ExtendedTimestamp mTimestamp;
Andy Hung2e2c0bb2018-06-11 19:13:11 -0700682 TimestampVerifier< // For timestamp statistics.
683 int64_t /* frame count */, int64_t /* time ns */> mTimestampVerifier;
Dean Wheatley12473e92021-03-18 23:00:55 +1100684 // DIRECT and OFFLOAD threads should reset frame count to zero on stop/flush
685 // TODO: add confirmation checks:
686 // 1) DIRECT threads and linear PCM format really resets to 0?
687 // 2) Is frame count really valid if not linear pcm?
688 // 3) Are all 64 bits of position returned, not just lowest 32 bits?
jiabinc52b1ff2019-10-31 17:20:42 -0700689 // Timestamp corrected device should be a single device.
690 audio_devices_t mTimestampCorrectedDevice = AUDIO_DEVICE_NONE;
Andy Hung446f4df2019-02-21 12:26:41 -0800691
692 // ThreadLoop statistics per iteration.
693 int64_t mLastIoBeginNs = -1;
694 int64_t mLastIoEndNs = -1;
695
Andy Hung44d648b2022-04-08 17:33:40 -0700696 // ThreadSnapshot is thread-safe (internally locked)
697 mediautils::ThreadSnapshot mThreadSnapshot;
698
Andy Hung446f4df2019-02-21 12:26:41 -0800699 // This should be read under ThreadBase lock (if not on the threadLoop thread).
700 audio_utils::Statistics<double> mIoJitterMs{0.995 /* alpha */};
701 audio_utils::Statistics<double> mProcessTimeMs{0.995 /* alpha */};
Andy Hunge6c37112019-02-26 17:38:10 -0800702 audio_utils::Statistics<double> mLatencyMs{0.995 /* alpha */};
Robert Wu06db0a32021-08-10 19:05:34 +0000703 audio_utils::Statistics<double> mMonopipePipeDepthStats{0.999 /* alpha */};
Andy Hung446f4df2019-02-21 12:26:41 -0800704
Andy Hungd0979812019-02-21 15:51:44 -0800705 // Save the last count when we delivered statistics to mediametrics.
706 int64_t mLastRecordedTimestampVerifierN = 0;
707 int64_t mLastRecordedTimeNs = 0; // BOOTTIME to include suspend.
708
Andy Hungc8fddf32018-08-08 18:32:37 -0700709 bool mIsMsdDevice = false;
Eric Laurent6acd1d42017-01-04 14:23:29 -0800710 // A condition that must be evaluated by the thread loop has changed and
711 // we must not wait for async write callback in the thread loop before evaluating it
712 bool mSignalPending;
Andy Hungdae27702016-10-31 14:01:16 -0700713
Andy Hung8946a282018-04-19 20:04:56 -0700714#ifdef TEE_SINK
715 NBAIO_Tee mTee;
716#endif
Andy Hungdae27702016-10-31 14:01:16 -0700717 // ActiveTracks is a sorted vector of track type T representing the
718 // active tracks of threadLoop() to be considered by the locked prepare portion.
719 // ActiveTracks should be accessed with the ThreadBase lock held.
720 //
721 // During processing and I/O, the threadLoop does not hold the lock;
722 // hence it does not directly use ActiveTracks. Care should be taken
723 // to hold local strong references or defer removal of tracks
724 // if the threadLoop may still be accessing those tracks due to mix, etc.
725 //
726 // This class updates power information appropriately.
727 //
728
729 template <typename T>
730 class ActiveTracks {
731 public:
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700732 explicit ActiveTracks(SimpleLog *localLog = nullptr)
Andy Hungdae27702016-10-31 14:01:16 -0700733 : mActiveTracksGeneration(0)
734 , mLastActiveTracksGeneration(0)
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700735 , mLocalLog(localLog)
Andy Hungdae27702016-10-31 14:01:16 -0700736 { }
737
738 ~ActiveTracks() {
739 ALOGW_IF(!mActiveTracks.isEmpty(),
740 "ActiveTracks should be empty in destructor");
741 }
742 // returns the last track added (even though it may have been
743 // subsequently removed from ActiveTracks).
744 //
745 // Used for DirectOutputThread to ensure a flush is called when transitioning
746 // to a new track (even though it may be on the same session).
747 // Used for OffloadThread to ensure that volume and mixer state is
748 // taken from the latest track added.
749 //
750 // The latest track is saved with a weak pointer to prevent keeping an
751 // otherwise useless track alive. Thus the function will return nullptr
752 // if the latest track has subsequently been removed and destroyed.
753 sp<T> getLatest() {
754 return mLatestActiveTrack.promote();
755 }
756
757 // SortedVector methods
758 ssize_t add(const sp<T> &track);
759 ssize_t remove(const sp<T> &track);
760 size_t size() const {
761 return mActiveTracks.size();
762 }
Eric Tan39ec8d62018-07-24 09:49:29 -0700763 bool isEmpty() const {
764 return mActiveTracks.isEmpty();
765 }
Andy Hung44f27182023-07-06 20:56:16 -0700766 ssize_t indexOf(const sp<T>& item) const {
Andy Hungdae27702016-10-31 14:01:16 -0700767 return mActiveTracks.indexOf(item);
768 }
769 sp<T> operator[](size_t index) const {
770 return mActiveTracks[index];
771 }
772 typename SortedVector<sp<T>>::iterator begin() {
773 return mActiveTracks.begin();
774 }
775 typename SortedVector<sp<T>>::iterator end() {
776 return mActiveTracks.end();
777 }
778
779 // Due to Binder recursion optimization, clear() and updatePowerState()
780 // cannot be called from a Binder thread because they may call back into
781 // the original calling process (system server) for BatteryNotifier
782 // (which requires a Java environment that may not be present).
783 // Hence, call clear() and updatePowerState() only from the
784 // ThreadBase thread.
785 void clear();
786 // periodically called in the threadLoop() to update power state uids.
Andy Hung94dfbb42023-09-06 19:41:47 -0700787 void updatePowerState_l(const sp<ThreadBase>& thread, bool force = false)
788 REQUIRES(audio_utils::ThreadBase_Mutex);
Andy Hungdae27702016-10-31 14:01:16 -0700789
Kevin Rocardc86a7f72018-04-03 09:00:09 -0700790 /** @return true if one or move active tracks was added or removed since the
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800791 * last time this function was called or the vector was created.
792 * true if volume of one of active tracks was changed.
793 */
Kevin Rocard069c2712018-03-29 19:09:14 -0700794 bool readAndClearHasChanged();
795
Eric Laurentdda206a2022-07-08 17:28:35 +0200796 /** Force updating track metadata to audio HAL stream next time
797 * readAndClearHasChanged() is called.
798 */
799 void setHasChanged() { mHasChanged = true; }
800
Andy Hungdae27702016-10-31 14:01:16 -0700801 private:
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700802 void logTrack(const char *funcName, const sp<T> &track) const;
803
Andy Hungd01b0f12016-11-07 16:10:30 -0800804 SortedVector<uid_t> getWakeLockUids() {
805 SortedVector<uid_t> wakeLockUids;
Andy Hungdae27702016-10-31 14:01:16 -0700806 for (const sp<T> &track : mActiveTracks) {
807 wakeLockUids.add(track->uid());
808 }
809 return wakeLockUids; // moved by underlying SharedBuffer
810 }
811
812 std::map<uid_t, std::pair<ssize_t /* previous */, ssize_t /* current */>>
813 mBatteryCounter;
814 SortedVector<sp<T>> mActiveTracks;
815 int mActiveTracksGeneration;
816 int mLastActiveTracksGeneration;
817 wp<T> mLatestActiveTrack; // latest track added to ActiveTracks
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700818 SimpleLog * const mLocalLog;
Kevin Rocardc86a7f72018-04-03 09:00:09 -0700819 // If the vector has changed since last call to readAndClearHasChanged
Kevin Rocard069c2712018-03-29 19:09:14 -0700820 bool mHasChanged = false;
Andy Hungdae27702016-10-31 14:01:16 -0700821 };
Andy Hung293558a2017-03-21 12:19:20 -0700822
Andy Hung94dfbb42023-09-06 19:41:47 -0700823 SimpleLog mLocalLog; // locked internally
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -0700824
825private:
Andy Hung94dfbb42023-09-06 19:41:47 -0700826 void dumpBase_l(int fd, const Vector<String16>& args) REQUIRES(mutex());
827 void dumpEffectChains_l(int fd, const Vector<String16>& args) REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -0800828};
829
830// --- PlaybackThread ---
Andy Hung4989d312023-06-29 21:19:25 -0700831class PlaybackThread : public ThreadBase, public virtual IAfPlaybackThread,
832 public StreamOutHalInterfaceCallback,
Andy Hung44f27182023-07-06 20:56:16 -0700833 public virtual VolumeInterface, public StreamOutHalInterfaceEventCallback {
Eric Laurent81784c32012-11-19 14:55:58 -0800834public:
Andy Hung44f27182023-07-06 20:56:16 -0700835 sp<IAfPlaybackThread> asIAfPlaybackThread() final {
836 return sp<IAfPlaybackThread>::fromExisting(this);
837 }
Eric Laurent81784c32012-11-19 14:55:58 -0800838
Eric Laurente93cc032016-05-05 10:15:10 -0700839 // retry count before removing active track in case of underrun on offloaded thread:
840 // we need to make sure that AudioTrack client has enough time to send large buffers
841 //FIXME may be more appropriate if expressed in time units. Need to revise how underrun is
842 // handled for offloaded tracks
843 static const int8_t kMaxTrackRetriesOffload = 20;
844 static const int8_t kMaxTrackStartupRetriesOffload = 100;
Andy Hung8ed196a2018-01-05 13:21:11 -0800845 static constexpr uint32_t kMaxTracksPerUid = 40;
Andy Hung1bc088a2018-02-09 15:57:31 -0800846 static constexpr size_t kMaxTracks = 256;
Eric Laurente93cc032016-05-05 10:15:10 -0700847
rago1bb90822017-05-02 18:31:48 -0700848 // Maximum delay (in nanoseconds) for upcoming buffers in suspend mode, otherwise
849 // if delay is greater, the estimated time for timeLoopNextNs is reset.
850 // This allows for catch-up to be done for small delays, while resetting the estimate
851 // for initial conditions or large delays.
852 static const nsecs_t kMaxNextBufferDelayNs = 100000000;
853
Andy Hung2cbc2722023-07-17 17:05:00 -0700854 PlaybackThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
Eric Laurentf1f22e72021-07-13 14:04:14 +0200855 audio_io_handle_t id, type_t type, bool systemReady,
856 audio_config_base_t *mixerConfig = nullptr);
Andy Hung4989d312023-06-29 21:19:25 -0700857 ~PlaybackThread() override;
Eric Laurent81784c32012-11-19 14:55:58 -0800858
Eric Laurent81784c32012-11-19 14:55:58 -0800859 // Thread virtuals
Andy Hung94dfbb42023-09-06 19:41:47 -0700860 bool threadLoop() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -0800861
862 // RefBase
Andy Hung4989d312023-06-29 21:19:25 -0700863 void onFirstRef() override;
Eric Laurent81784c32012-11-19 14:55:58 -0800864
Andy Hung4989d312023-06-29 21:19:25 -0700865 status_t checkEffectCompatibility_l(
Andy Hung94dfbb42023-09-06 19:41:47 -0700866 const effect_descriptor_t* desc, audio_session_t sessionId) final REQUIRES(mutex());
Eric Laurent4c415062016-06-17 16:14:16 -0700867
Andy Hung94dfbb42023-09-06 19:41:47 -0700868 void addOutputTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex()) {
Andy Hung44f27182023-07-06 20:56:16 -0700869 mTracks.add(track);
870 }
871
Eric Laurent81784c32012-11-19 14:55:58 -0800872protected:
873 // Code snippets that were lifted up out of threadLoop()
874 virtual void threadLoop_mix() = 0;
875 virtual void threadLoop_sleepTime() = 0;
Eric Laurentbfb1b832013-01-07 09:53:42 -0800876 virtual ssize_t threadLoop_write();
877 virtual void threadLoop_drain();
Eric Laurent81784c32012-11-19 14:55:58 -0800878 virtual void threadLoop_standby();
Eric Laurentbfb1b832013-01-07 09:53:42 -0800879 virtual void threadLoop_exit();
Andy Hung3ff4b552023-06-26 19:20:57 -0700880 virtual void threadLoop_removeTracks(const Vector<sp<IAfTrack>>& tracksToRemove);
Eric Laurent81784c32012-11-19 14:55:58 -0800881
882 // prepareTracks_l reads and writes mActiveTracks, and returns
883 // the pending set of tracks to remove via Vector 'tracksToRemove'. The caller
884 // is responsible for clearing or destroying this Vector later on, when it
885 // is safe to do so. That will drop the final ref count and destroy the tracks.
Andy Hung3ff4b552023-06-26 19:20:57 -0700886 virtual mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) = 0;
887 void removeTracks_l(const Vector<sp<IAfTrack>>& tracksToRemove);
Eric Laurenteab90452019-06-24 15:17:46 -0700888 status_t handleVoipVolume_l(float *volume);
Eric Laurentbfb1b832013-01-07 09:53:42 -0800889
Mikhail Naganov1dc98672016-08-18 17:50:29 -0700890 // StreamOutHalInterfaceCallback implementation
891 virtual void onWriteReady();
892 virtual void onDrainReady();
893 virtual void onError();
Eric Laurentbfb1b832013-01-07 09:53:42 -0800894
Andy Hung71742ab2023-07-07 13:47:37 -0700895public: // AsyncCallbackThread
Mikhail Naganov1dc98672016-08-18 17:50:29 -0700896 void resetWriteBlocked(uint32_t sequence);
897 void resetDraining(uint32_t sequence);
Andy Hung71742ab2023-07-07 13:47:37 -0700898protected:
Eric Laurentbfb1b832013-01-07 09:53:42 -0800899
900 virtual bool waitingAsyncCallback();
Andy Hung94dfbb42023-09-06 19:41:47 -0700901 virtual bool waitingAsyncCallback_l() REQUIRES(mutex());
902 virtual bool shouldStandby_l() REQUIRES(mutex());
903 virtual void onAddNewTrack_l() REQUIRES(mutex());
Andy Hung71742ab2023-07-07 13:47:37 -0700904public: // AsyncCallbackThread
Haynes Mathew George4527b9e2016-07-07 19:54:17 -0700905 void onAsyncError(); // error reported by AsyncCallbackThread
Andy Hung71742ab2023-07-07 13:47:37 -0700906protected:
jiabinf6eb4c32020-02-25 14:06:25 -0800907 // StreamHalInterfaceCodecFormatCallback implementation
908 void onCodecFormatChanged(
Andy Hung4989d312023-06-29 21:19:25 -0700909 const std::basic_string<uint8_t>& metadataBs) final;
jiabinf6eb4c32020-02-25 14:06:25 -0800910
Eric Laurent81784c32012-11-19 14:55:58 -0800911 // ThreadBase virtuals
Andy Hung94dfbb42023-09-06 19:41:47 -0700912 void preExit() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -0800913
Eric Laurent64667972016-03-30 18:19:46 -0700914 virtual bool keepWakeLock() const { return true; }
Andy Hung94dfbb42023-09-06 19:41:47 -0700915 virtual void acquireWakeLock_l() REQUIRES(mutex()) {
Andy Hungdae27702016-10-31 14:01:16 -0700916 ThreadBase::acquireWakeLock_l();
Andy Hung94dfbb42023-09-06 19:41:47 -0700917 mActiveTracks.updatePowerState_l(this, true /* force */);
Andy Hungdae27702016-10-31 14:01:16 -0700918 }
Eric Laurent64667972016-03-30 18:19:46 -0700919
Eric Laurentb3f315a2021-07-13 15:09:05 +0200920 virtual void checkOutputStageEffects() {}
Eric Laurent6f9534f2022-05-03 18:15:04 +0200921 virtual void setHalLatencyMode_l() {}
922
Eric Laurentb3f315a2021-07-13 15:09:05 +0200923
Andy Hung94dfbb42023-09-06 19:41:47 -0700924 void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
925 void dumpTracks_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -0700926
Eric Laurent81784c32012-11-19 14:55:58 -0800927public:
928
Andy Hung4989d312023-06-29 21:19:25 -0700929 status_t initCheck() const final { return mOutput == nullptr ? NO_INIT : NO_ERROR; }
Eric Laurent81784c32012-11-19 14:55:58 -0800930
931 // return estimated latency in milliseconds, as reported by HAL
Andy Hung4989d312023-06-29 21:19:25 -0700932 uint32_t latency() const final;
Eric Laurent81784c32012-11-19 14:55:58 -0800933 // same, but lock must already be held
Andy Hung94dfbb42023-09-06 19:41:47 -0700934 uint32_t latency_l() const final /* REQUIRES(mutex()) */; // NO_THREAD_SAFETY_ANALYSIS
Eric Laurent81784c32012-11-19 14:55:58 -0800935
Eric Laurent6acd1d42017-01-04 14:23:29 -0800936 // VolumeInterface
Andy Hung4989d312023-06-29 21:19:25 -0700937 void setMasterVolume(float value) final;
Andy Hung94dfbb42023-09-06 19:41:47 -0700938 void setMasterBalance(float balance) override EXCLUDES_ThreadBase_Mutex;
Andy Hung4989d312023-06-29 21:19:25 -0700939 void setMasterMute(bool muted) final;
Andy Hung94dfbb42023-09-06 19:41:47 -0700940 void setStreamVolume(audio_stream_type_t stream, float value) final EXCLUDES_ThreadBase_Mutex;
941 void setStreamMute(audio_stream_type_t stream, bool muted) final EXCLUDES_ThreadBase_Mutex;
942 float streamVolume(audio_stream_type_t stream) const final EXCLUDES_ThreadBase_Mutex;
Andy Hung4989d312023-06-29 21:19:25 -0700943 void setVolumeForOutput_l(float left, float right) const final;
Eric Laurent81784c32012-11-19 14:55:58 -0800944
Andy Hung4989d312023-06-29 21:19:25 -0700945 sp<IAfTrack> createTrack_l(
Andy Hungd65869f2023-06-27 17:05:02 -0700946 const sp<Client>& client,
Eric Laurent81784c32012-11-19 14:55:58 -0800947 audio_stream_type_t streamType,
Kevin Rocard1f564ac2018-03-29 13:53:10 -0700948 const audio_attributes_t& attr,
Eric Laurent21da6472017-11-09 16:29:26 -0800949 uint32_t *sampleRate,
Eric Laurent81784c32012-11-19 14:55:58 -0800950 audio_format_t format,
951 audio_channel_mask_t channelMask,
Glenn Kasten74935e42013-12-19 08:56:45 -0800952 size_t *pFrameCount,
Eric Laurent21da6472017-11-09 16:29:26 -0800953 size_t *pNotificationFrameCount,
954 uint32_t notificationsPerBuffer,
955 float speed,
Eric Laurent81784c32012-11-19 14:55:58 -0800956 const sp<IMemory>& sharedBuffer,
Glenn Kastend848eb42016-03-08 13:42:11 -0800957 audio_session_t sessionId,
Eric Laurent05067782016-06-01 18:27:28 -0700958 audio_output_flags_t *flags,
Eric Laurent09f1ed22019-04-24 17:45:17 -0700959 pid_t creatorPid,
Svet Ganov33761132021-05-13 22:51:08 +0000960 const AttributionSourceState& attributionSource,
Eric Laurent81784c32012-11-19 14:55:58 -0800961 pid_t tid,
Eric Laurent20b9ef02016-12-05 11:03:16 -0800962 status_t *status /*non-NULL*/,
jiabinf6eb4c32020-02-25 14:06:25 -0800963 audio_port_handle_t portId,
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200964 const sp<media::IAudioTrackCallback>& callback,
jiabinc658e452022-10-21 20:52:21 +0000965 bool isSpatialized,
Andy Hungf79092d2023-08-31 16:13:39 -0700966 bool isBitPerfect) final
967 REQUIRES(audio_utils::AudioFlinger_Mutex);
Eric Laurent81784c32012-11-19 14:55:58 -0800968
Andy Hung44f27182023-07-06 20:56:16 -0700969 bool isTrackActive(const sp<IAfTrack>& track) const final {
970 return mActiveTracks.indexOf(track) >= 0;
971 }
972
Andy Hung94dfbb42023-09-06 19:41:47 -0700973 AudioStreamOut* getOutput_l() const final REQUIRES(mutex()) { return mOutput; }
Andy Hung4989d312023-06-29 21:19:25 -0700974 AudioStreamOut* getOutput() const final;
975 AudioStreamOut* clearOutput() final;
976 sp<StreamHalInterface> stream() const final;
Eric Laurent81784c32012-11-19 14:55:58 -0800977
978 // a very large number of suspend() will eventually wraparound, but unlikely
Andy Hung4989d312023-06-29 21:19:25 -0700979 void suspend() final { (void) android_atomic_inc(&mSuspended); }
980 void restore() final
Eric Laurent81784c32012-11-19 14:55:58 -0800981 {
982 // if restore() is done without suspend(), get back into
983 // range so that the next suspend() will operate correctly
984 if (android_atomic_dec(&mSuspended) <= 0) {
985 android_atomic_release_store(0, &mSuspended);
986 }
987 }
Andy Hung4989d312023-06-29 21:19:25 -0700988 bool isSuspended() const final
Eric Laurent81784c32012-11-19 14:55:58 -0800989 { return android_atomic_acquire_load(&mSuspended) > 0; }
990
Andy Hung94dfbb42023-09-06 19:41:47 -0700991 String8 getParameters(const String8& keys) EXCLUDES_ThreadBase_Mutex;
992
993 // Hold either the AudioFlinger::mutex or the ThreadBase::mutex
994 void ioConfigChanged_l(audio_io_config_event_t event, pid_t pid = 0,
Andy Hung4989d312023-06-29 21:19:25 -0700995 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
Andy Hung94dfbb42023-09-06 19:41:47 -0700996 status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const final
997 EXCLUDES_ThreadBase_Mutex;
Andy Hung010a1a12014-03-13 13:57:33 -0700998 // Consider also removing and passing an explicit mMainBuffer initialization
Andy Hung3ff4b552023-06-26 19:20:57 -0700999 // parameter to AF::IAfTrack::Track().
Andy Hung4989d312023-06-29 21:19:25 -07001000 float* sinkBuffer() const final {
Andy Hung319587b2023-05-23 14:01:03 -07001001 return reinterpret_cast<float *>(mSinkBuffer); };
Eric Laurent81784c32012-11-19 14:55:58 -08001002
Andy Hung94dfbb42023-09-06 19:41:47 -07001003 void detachAuxEffect_l(int effectId) final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001004
Andy Hung94dfbb42023-09-06 19:41:47 -07001005 status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId) final
1006 EXCLUDES_ThreadBase_Mutex;
1007 status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) final REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -07001008
Andy Hung94dfbb42023-09-06 19:41:47 -07001009 status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
1010 size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
1011 uint32_t hasAudioSession_l(audio_session_t sessionId) const final REQUIRES(mutex()) {
Andy Hungc3d62f92019-03-14 13:38:51 -07001012 return ThreadBase::hasAudioSession_l(sessionId, mTracks);
1013 }
Andy Hung94dfbb42023-09-06 19:41:47 -07001014 product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const final
1015 REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001016
1017
Andy Hung94dfbb42023-09-06 19:41:47 -07001018 status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final
1019 EXCLUDES_ThreadBase_Mutex;
1020 // could be static.
Andy Hung4989d312023-06-29 21:19:25 -07001021 bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;
Glenn Kastenfb1fdc92013-07-10 17:03:19 -07001022
Andy Hung94dfbb42023-09-06 19:41:47 -07001023 // Does this require the AudioFlinger mutex as well?
1024 bool invalidateTracks_l(audio_stream_type_t streamType) final
1025 REQUIRES(mutex());
1026 bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final
1027 REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -07001028 void invalidateTracks(audio_stream_type_t streamType) override;
jiabinc44b3462022-12-08 12:52:31 -08001029 // Invalidate tracks by a set of port ids. The port id will be removed from
1030 // the given set if the corresponding track is found and invalidated.
Andy Hung94dfbb42023-09-06 19:41:47 -07001031 void invalidateTracks(std::set<audio_port_handle_t>& portIds) override
1032 EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -08001033
Andy Hung44f27182023-07-06 20:56:16 -07001034 size_t frameCount() const final { return mNormalFrameCount; }
Glenn Kasten9b58f632013-07-16 11:37:48 -07001035
Andy Hung4989d312023-06-29 21:19:25 -07001036 audio_channel_mask_t mixerChannelMask() const final {
Eric Laurentf1f22e72021-07-13 14:04:14 +02001037 return mMixerChannelMask;
1038 }
1039
Andy Hung94dfbb42023-09-06 19:41:47 -07001040 status_t getTimestamp_l(AudioTimestamp& timestamp) final REQUIRES(mutex());
Eric Laurent83b88082014-06-20 18:31:16 -07001041
Andy Hung94dfbb42023-09-06 19:41:47 -07001042 void addPatchTrack(const sp<IAfPatchTrack>& track) final EXCLUDES_ThreadBase_Mutex;
1043 void deletePatchTrack(const sp<IAfPatchTrack>& track) final EXCLUDES_ThreadBase_Mutex;
Eric Laurent83b88082014-06-20 18:31:16 -07001044
Andy Hung94dfbb42023-09-06 19:41:47 -07001045 // NO_THREAD_SAFETY_ANALYSIS - fix this to use atomics.
Andy Hung4989d312023-06-29 21:19:25 -07001046 void toAudioPortConfig(struct audio_port_config* config) final;
Eric Laurentaccc1472013-09-20 09:36:34 -07001047
Andy Hung10cbff12017-02-21 17:30:14 -08001048 // Return the asynchronous signal wait time.
Andy Hung94dfbb42023-09-06 19:41:47 -07001049 int64_t computeWaitTimeNs_l() const override REQUIRES(mutex()) { return INT64_MAX; }
Andy Hung1bc088a2018-02-09 15:57:31 -08001050 // returns true if the track is allowed to be added to the thread.
Andy Hung4989d312023-06-29 21:19:25 -07001051 bool isTrackAllowed_l(
Andy Hung1bc088a2018-02-09 15:57:31 -08001052 audio_channel_mask_t channelMask __unused,
1053 audio_format_t format __unused,
1054 audio_session_t sessionId __unused,
Andy Hung94dfbb42023-09-06 19:41:47 -07001055 uid_t uid) const override REQUIRES(mutex()) {
Andy Hung1bc088a2018-02-09 15:57:31 -08001056 return trackCountForUid_l(uid) < PlaybackThread::kMaxTracksPerUid
1057 && mTracks.size() < PlaybackThread::kMaxTracks;
1058 }
1059
Andy Hung94dfbb42023-09-06 19:41:47 -07001060 bool isTimestampCorrectionEnabled_l() const final REQUIRES(mutex()) {
1061 return audio_is_output_devices(mTimestampCorrectedDevice)
1062 && outDeviceTypes_l().count(mTimestampCorrectedDevice) != 0;
Andy Hungc8fddf32018-08-08 18:32:37 -07001063 }
jiabinc52b1ff2019-10-31 17:20:42 -07001064
Andy Hung94dfbb42023-09-06 19:41:47 -07001065 // NO_THREAD_SAFETY_ANALYSIS - fix this to be atomic.
Andy Hung4989d312023-06-29 21:19:25 -07001066 bool isStreamInitialized() const final {
Jasmine Chaeaa10e42021-05-11 10:11:14 +08001067 return !(mOutput == nullptr || mOutput->stream == nullptr);
1068 }
1069
Andy Hung4989d312023-06-29 21:19:25 -07001070 audio_channel_mask_t hapticChannelMask() const final {
jiabineb3bda02020-06-30 14:07:03 -07001071 return mHapticChannelMask;
1072 }
Andy Hung44f27182023-07-06 20:56:16 -07001073
1074 uint32_t hapticChannelCount() const final {
1075 return mHapticChannelCount;
1076 }
1077
Andy Hung4989d312023-06-29 21:19:25 -07001078 bool supportsHapticPlayback() const final {
jiabineb3bda02020-06-30 14:07:03 -07001079 return (mHapticChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE;
1080 }
1081
Andy Hung94dfbb42023-09-06 19:41:47 -07001082 void setDownStreamPatch(const struct audio_patch* patch) final EXCLUDES_ThreadBase_Mutex {
Andy Hung87e82412023-08-29 14:26:09 -07001083 std::lock_guard _l(mutex());
Eric Laurent74c38dc2020-12-23 18:19:44 +01001084 mDownStreamPatch = *patch;
1085 }
1086
Andy Hung94dfbb42023-09-06 19:41:47 -07001087 IAfTrack* getTrackById_l(audio_port_handle_t trackId) final REQUIRES(mutex());
jiabinf042b9b2021-05-07 23:46:28 +00001088
Andy Hung4989d312023-06-29 21:19:25 -07001089 bool hasMixer() const final {
Eric Laurent1c5e2e32021-08-18 18:50:28 +02001090 return mType == MIXER || mType == DUPLICATING || mType == SPATIALIZER;
Eric Laurentb3f315a2021-07-13 15:09:05 +02001091 }
Eric Laurent6f9534f2022-05-03 18:15:04 +02001092
Andy Hung4989d312023-06-29 21:19:25 -07001093 status_t setRequestedLatencyMode(
1094 audio_latency_mode_t /* mode */) override { return INVALID_OPERATION; }
Eric Laurent6f9534f2022-05-03 18:15:04 +02001095
Andy Hung4989d312023-06-29 21:19:25 -07001096 status_t getSupportedLatencyModes(
1097 std::vector<audio_latency_mode_t>* /* modes */) override {
Eric Laurent6f9534f2022-05-03 18:15:04 +02001098 return INVALID_OPERATION;
1099 }
1100
Andy Hung4989d312023-06-29 21:19:25 -07001101 status_t setBluetoothVariableLatencyEnabled(bool /* enabled */) override{
Eric Laurentb0463942022-12-20 16:31:10 +01001102 return INVALID_OPERATION;
1103 }
Eric Laurent01eb1642022-12-16 11:45:07 +01001104
Andy Hungf79092d2023-08-31 16:13:39 -07001105 void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override
1106 REQUIRES(audio_utils::AudioFlinger_Mutex);
1107 void stopMelComputation_l() override
1108 REQUIRES(audio_utils::AudioFlinger_Mutex);
Vlad Popab042ee62022-10-20 18:05:00 +02001109
Andy Hung4989d312023-06-29 21:19:25 -07001110 void setStandby() final {
Andy Hung87e82412023-08-29 14:26:09 -07001111 std::lock_guard _l(mutex());
Eric Laurent19952e12023-04-20 10:08:29 +02001112 setStandby_l();
1113 }
1114
Andy Hung94dfbb42023-09-06 19:41:47 -07001115 void setStandby_l() final REQUIRES(mutex()) {
Eric Laurent19952e12023-04-20 10:08:29 +02001116 mStandby = true;
1117 mHalStarted = false;
1118 mKernelPositionOnStandby =
1119 mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
1120 }
1121
Andy Hung94dfbb42023-09-06 19:41:47 -07001122 bool waitForHalStart() final EXCLUDES_ThreadBase_Mutex {
Andy Hung87e82412023-08-29 14:26:09 -07001123 audio_utils::unique_lock _l(mutex());
Eric Laurent19952e12023-04-20 10:08:29 +02001124 static const nsecs_t kWaitHalTimeoutNs = seconds(2);
1125 nsecs_t endWaitTimetNs = systemTime() + kWaitHalTimeoutNs;
1126 while (!mHalStarted) {
1127 nsecs_t timeNs = systemTime();
1128 if (timeNs >= endWaitTimetNs) {
1129 break;
1130 }
1131 nsecs_t waitTimeLeftNs = endWaitTimetNs - timeNs;
Andy Hung87e82412023-08-29 14:26:09 -07001132 mWaitHalStartCV.wait_for(_l, std::chrono::nanoseconds(waitTimeLeftNs));
Eric Laurent19952e12023-04-20 10:08:29 +02001133 }
1134 return mHalStarted;
1135 }
Eric Laurent81784c32012-11-19 14:55:58 -08001136protected:
Glenn Kastendeca2ae2014-02-07 10:25:56 -08001137 // updated by readOutputParameters_l()
Glenn Kasten9b58f632013-07-16 11:37:48 -07001138 size_t mNormalFrameCount; // normal mixer and effects
1139
Andy Hung08fb1742015-05-31 23:22:10 -07001140 bool mThreadThrottle; // throttle the thread processing
Andy Hung40eb1a12015-06-18 13:42:02 -07001141 uint32_t mThreadThrottleTimeMs; // throttle time for MIXER threads
1142 uint32_t mThreadThrottleEndMs; // notify once per throttling
Andy Hung08fb1742015-05-31 23:22:10 -07001143 uint32_t mHalfBufferMs; // half the buffer size in milliseconds
1144
Andy Hung010a1a12014-03-13 13:57:33 -07001145 void* mSinkBuffer; // frame size aligned sink buffer
Eric Laurent81784c32012-11-19 14:55:58 -08001146
Andy Hung98ef9782014-03-04 14:46:50 -08001147 // TODO:
1148 // Rearrange the buffer info into a struct/class with
1149 // clear, copy, construction, destruction methods.
1150 //
1151 // mSinkBuffer also has associated with it:
1152 //
1153 // mSinkBufferSize: Sink Buffer Size
1154 // mFormat: Sink Buffer Format
1155
Andy Hung69aed5f2014-02-25 17:24:40 -08001156 // Mixer Buffer (mMixerBuffer*)
1157 //
1158 // In the case of floating point or multichannel data, which is not in the
1159 // sink format, it is required to accumulate in a higher precision or greater channel count
1160 // buffer before downmixing or data conversion to the sink buffer.
1161
1162 // Set to "true" to enable the Mixer Buffer otherwise mixer output goes to sink buffer.
1163 bool mMixerBufferEnabled;
1164
1165 // Storage, 32 byte aligned (may make this alignment a requirement later).
1166 // Due to constraints on mNormalFrameCount, the buffer size is a multiple of 16 frames.
1167 void* mMixerBuffer;
1168
1169 // Size of mMixerBuffer in bytes: mNormalFrameCount * #channels * sampsize.
1170 size_t mMixerBufferSize;
1171
1172 // The audio format of mMixerBuffer. Set to AUDIO_FORMAT_PCM_(FLOAT|16_BIT) only.
1173 audio_format_t mMixerBufferFormat;
1174
1175 // An internal flag set to true by MixerThread::prepareTracks_l()
1176 // when mMixerBuffer contains valid data after mixing.
1177 bool mMixerBufferValid;
1178
Andy Hung98ef9782014-03-04 14:46:50 -08001179 // Effects Buffer (mEffectsBuffer*)
1180 //
1181 // In the case of effects data, which is not in the sink format,
1182 // it is required to accumulate in a different buffer before data conversion
1183 // to the sink buffer.
1184
1185 // Set to "true" to enable the Effects Buffer otherwise effects output goes to sink buffer.
1186 bool mEffectBufferEnabled;
1187
1188 // Storage, 32 byte aligned (may make this alignment a requirement later).
1189 // Due to constraints on mNormalFrameCount, the buffer size is a multiple of 16 frames.
1190 void* mEffectBuffer;
1191
1192 // Size of mEffectsBuffer in bytes: mNormalFrameCount * #channels * sampsize.
1193 size_t mEffectBufferSize;
1194
1195 // The audio format of mEffectsBuffer. Set to AUDIO_FORMAT_PCM_16_BIT only.
1196 audio_format_t mEffectBufferFormat;
1197
1198 // An internal flag set to true by MixerThread::prepareTracks_l()
1199 // when mEffectsBuffer contains valid data after mixing.
1200 //
1201 // When this is set, all mixer data is routed into the effects buffer
1202 // for any processing (including output processing).
1203 bool mEffectBufferValid;
1204
jiabinc658e452022-10-21 20:52:21 +00001205 // Set to "true" to enable when data has already copied to sink
1206 bool mHasDataCopiedToSinkBuffer = false;
1207
Eric Laurentb62d0362021-10-26 17:40:18 +02001208 // Frame size aligned buffer used as input and output to all post processing effects
1209 // except the Spatializer in a SPATIALIZER thread. Non spatialized tracks are mixed into
1210 // this buffer so that post processing effects can be applied.
1211 void* mPostSpatializerBuffer = nullptr;
1212
1213 // Size of mPostSpatializerBuffer in bytes
1214 size_t mPostSpatializerBufferSize;
Eric Laurent39095982021-08-24 18:29:27 +02001215
1216
Eric Laurent81784c32012-11-19 14:55:58 -08001217 // suspend count, > 0 means suspended. While suspended, the thread continues to pull from
1218 // tracks and mix, but doesn't write to HAL. A2DP and SCO HAL implementations can't handle
1219 // concurrent use of both of them, so Audio Policy Service suspends one of the threads to
1220 // workaround that restriction.
1221 // 'volatile' means accessed via atomic operations and no lock.
1222 volatile int32_t mSuspended;
1223
Andy Hung818e7a32016-02-16 18:08:07 -08001224 int64_t mBytesWritten;
yucliu91503922022-07-20 17:40:39 -07001225 std::atomic<int64_t> mFramesWritten; // not reset on standby
Dean Wheatley12473e92021-03-18 23:00:55 +11001226 int64_t mLastFramesWritten = -1; // track changes in timestamp
1227 // server frames written.
Andy Hung238fa3d2016-07-28 10:53:22 -07001228 int64_t mSuspendedFrames; // not reset on standby
jiabin245cdd92018-12-07 17:55:15 -08001229
1230 // mHapticChannelMask and mHapticChannelCount will only be valid when the thread support
1231 // haptic playback.
1232 audio_channel_mask_t mHapticChannelMask = AUDIO_CHANNEL_NONE;
1233 uint32_t mHapticChannelCount = 0;
Eric Laurentf1f22e72021-07-13 14:04:14 +02001234
1235 audio_channel_mask_t mMixerChannelMask = AUDIO_CHANNEL_NONE;
1236
Eric Laurent81784c32012-11-19 14:55:58 -08001237 // mMasterMute is in both PlaybackThread and in AudioFlinger. When a
1238 // PlaybackThread needs to find out if master-muted, it checks it's local
1239 // copy rather than the one in AudioFlinger. This optimization saves a lock.
1240 bool mMasterMute;
1241 void setMasterMute_l(bool muted) { mMasterMute = muted; }
Dean Wheatley12473e92021-03-18 23:00:55 +11001242
1243 auto discontinuityForStandbyOrFlush() const { // call on threadLoop or with lock.
1244 return ((mType == DIRECT && !audio_is_linear_pcm(mFormat))
1245 || mType == OFFLOAD)
1246 ? mTimestampVerifier.DISCONTINUITY_MODE_ZERO
1247 : mTimestampVerifier.DISCONTINUITY_MODE_CONTINUOUS;
1248 }
1249
Andy Hung3ff4b552023-06-26 19:20:57 -07001250 ActiveTracks<IAfTrack> mActiveTracks;
Eric Laurent81784c32012-11-19 14:55:58 -08001251
Eric Laurent81784c32012-11-19 14:55:58 -08001252 // Time to sleep between cycles when:
1253 virtual uint32_t activeSleepTimeUs() const; // mixer state MIXER_TRACKS_ENABLED
1254 virtual uint32_t idleSleepTimeUs() const = 0; // mixer state MIXER_IDLE
1255 virtual uint32_t suspendSleepTimeUs() const = 0; // audio policy manager suspended us
1256 // No sleep when mixer state == MIXER_TRACKS_READY; relies on audio HAL stream->write()
1257 // No sleep in standby mode; waits on a condition
1258
1259 // Code snippets that are temporarily lifted up out of threadLoop() until the merge
Andy Hung94dfbb42023-09-06 19:41:47 -07001260
1261 // consider unification with MMapThread
1262 virtual void checkSilentMode_l() final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001263
1264 // Non-trivial for DUPLICATING only
1265 virtual void saveOutputTracks() { }
1266 virtual void clearOutputTracks() { }
1267
1268 // Cache various calculated values, at threadLoop() entry and after a parameter change
Andy Hung94dfbb42023-09-06 19:41:47 -07001269 virtual void cacheParameters_l() REQUIRES(mutex());
Eric Laurentb3f315a2021-07-13 15:09:05 +02001270 void setCheckOutputStageEffects() override {
1271 mCheckOutputStageEffects.store(true);
1272 }
Eric Laurent81784c32012-11-19 14:55:58 -08001273
Andy Hung94dfbb42023-09-06 19:41:47 -07001274 virtual uint32_t correctLatency_l(uint32_t latency) const REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001275
Eric Laurent1c333e22014-05-20 10:48:17 -07001276 virtual status_t createAudioPatch_l(const struct audio_patch *patch,
Andy Hung94dfbb42023-09-06 19:41:47 -07001277 audio_patch_handle_t *handle) REQUIRES(mutex());
1278 virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle)
1279 REQUIRES(mutex());
Eric Laurent1c333e22014-05-20 10:48:17 -07001280
Andy Hung94dfbb42023-09-06 19:41:47 -07001281 // NO_THREAD_SAFETY_ANALYSIS - fix this to use atomics
Andy Hung44f27182023-07-06 20:56:16 -07001282 bool usesHwAvSync() const final { return mType == DIRECT && mOutput != nullptr
Phil Burk6fc2a7c2015-04-30 16:08:10 -07001283 && mHwSupportsPause
1284 && (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
Eric Laurent0f7b5f22014-12-19 10:43:21 -08001285
Andy Hung1bc088a2018-02-09 15:57:31 -08001286 uint32_t trackCountForUid_l(uid_t uid) const;
Eric Laurentad7dd962016-09-22 12:38:37 -07001287
jiabineb3bda02020-06-30 14:07:03 -07001288 void invalidateTracksForAudioSession_l(
Andy Hung94dfbb42023-09-06 19:41:47 -07001289 audio_session_t sessionId) const override REQUIRES(mutex()) {
jiabineb3bda02020-06-30 14:07:03 -07001290 ThreadBase::invalidateTracksForAudioSession_l(sessionId, mTracks);
1291 }
1292
Mikhail Naganovbf493082017-04-17 17:37:12 -07001293 DISALLOW_COPY_AND_ASSIGN(PlaybackThread);
Eric Laurent81784c32012-11-19 14:55:58 -08001294
Andy Hung94dfbb42023-09-06 19:41:47 -07001295 status_t addTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex());
1296 bool destroyTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex());
Andy Hung44f27182023-07-06 20:56:16 -07001297
Andy Hung94dfbb42023-09-06 19:41:47 -07001298 void removeTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001299
Andy Hung94dfbb42023-09-06 19:41:47 -07001300 void readOutputParameters_l() REQUIRES(mutex());
1301 MetadataUpdate updateMetadata_l() final REQUIRES(mutex());
1302 virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata)
1303 REQUIRES(mutex()) ;
Eric Laurent81784c32012-11-19 14:55:58 -08001304
Andy Hung94dfbb42023-09-06 19:41:47 -07001305 void collectTimestamps_l() REQUIRES(mutex());
Dean Wheatley12473e92021-03-18 23:00:55 +11001306
Andy Hungc0691382018-09-12 18:01:57 -07001307 // The Tracks class manages tracks added and removed from the Thread.
Andy Hung1bc088a2018-02-09 15:57:31 -08001308 template <typename T>
1309 class Tracks {
1310 public:
Andy Hung71ba4b32022-10-06 12:09:49 -07001311 explicit Tracks(bool saveDeletedTrackIds) :
Andy Hungc0691382018-09-12 18:01:57 -07001312 mSaveDeletedTrackIds(saveDeletedTrackIds) { }
Andy Hung1bc088a2018-02-09 15:57:31 -08001313
1314 // SortedVector methods
Andy Hungc0691382018-09-12 18:01:57 -07001315 ssize_t add(const sp<T> &track) {
1316 const ssize_t index = mTracks.add(track);
1317 LOG_ALWAYS_FATAL_IF(index < 0, "cannot add track");
1318 return index;
1319 }
Andy Hung1bc088a2018-02-09 15:57:31 -08001320 ssize_t remove(const sp<T> &track);
1321 size_t size() const {
1322 return mTracks.size();
1323 }
1324 bool isEmpty() const {
1325 return mTracks.isEmpty();
1326 }
1327 ssize_t indexOf(const sp<T> &item) {
1328 return mTracks.indexOf(item);
1329 }
1330 sp<T> operator[](size_t index) const {
1331 return mTracks[index];
1332 }
1333 typename SortedVector<sp<T>>::iterator begin() {
1334 return mTracks.begin();
1335 }
1336 typename SortedVector<sp<T>>::iterator end() {
1337 return mTracks.end();
1338 }
1339
Andy Hung71ba4b32022-10-06 12:09:49 -07001340 size_t processDeletedTrackIds(const std::function<void(int)>& f) {
Andy Hungc0691382018-09-12 18:01:57 -07001341 for (const int trackId : mDeletedTrackIds) {
1342 f(trackId);
Andy Hung1bc088a2018-02-09 15:57:31 -08001343 }
Andy Hungc0691382018-09-12 18:01:57 -07001344 return mDeletedTrackIds.size();
Andy Hung1bc088a2018-02-09 15:57:31 -08001345 }
1346
Andy Hungc0691382018-09-12 18:01:57 -07001347 void clearDeletedTrackIds() { mDeletedTrackIds.clear(); }
Andy Hung1bc088a2018-02-09 15:57:31 -08001348
1349 private:
Andy Hungc0691382018-09-12 18:01:57 -07001350 // Tracks pending deletion for MIXER type threads
1351 const bool mSaveDeletedTrackIds; // true to enable tracking
1352 std::set<int> mDeletedTrackIds;
Andy Hung1bc088a2018-02-09 15:57:31 -08001353
1354 SortedVector<sp<T>> mTracks; // wrapped SortedVector.
1355 };
1356
Andy Hung3ff4b552023-06-26 19:20:57 -07001357 Tracks<IAfTrack> mTracks;
Andy Hung1bc088a2018-02-09 15:57:31 -08001358
Eric Laurent223fd5c2014-11-11 13:43:36 -08001359 stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
Andy Hung71742ab2023-07-07 13:47:37 -07001360
Eric Laurent81784c32012-11-19 14:55:58 -08001361 AudioStreamOut *mOutput;
1362
1363 float mMasterVolume;
Richard Folke Tullberg3fae0372017-01-13 09:04:25 +01001364 std::atomic<float> mMasterBalance{};
1365 audio_utils::Balance mBalance;
Eric Laurent81784c32012-11-19 14:55:58 -08001366 int mNumWrites;
1367 int mNumDelayedWrites;
1368 bool mInWrite;
1369
1370 // FIXME rename these former local variables of threadLoop to standard "m" names
Eric Laurentad9cb8b2015-05-26 16:38:19 -07001371 nsecs_t mStandbyTimeNs;
Andy Hung25c2dac2014-02-27 14:56:00 -08001372 size_t mSinkBufferSize;
Eric Laurent81784c32012-11-19 14:55:58 -08001373
1374 // cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l()
Eric Laurentad9cb8b2015-05-26 16:38:19 -07001375 uint32_t mActiveSleepTimeUs;
1376 uint32_t mIdleSleepTimeUs;
Eric Laurent81784c32012-11-19 14:55:58 -08001377
Eric Laurentad9cb8b2015-05-26 16:38:19 -07001378 uint32_t mSleepTimeUs;
Eric Laurent81784c32012-11-19 14:55:58 -08001379
1380 // mixer status returned by prepareTracks_l()
1381 mixer_state mMixerStatus; // current cycle
1382 // previous cycle when in prepareTracks_l()
1383 mixer_state mMixerStatusIgnoringFastTracks;
1384 // FIXME or a separate ready state per track
1385
1386 // FIXME move these declarations into the specific sub-class that needs them
1387 // MIXER only
1388 uint32_t sleepTimeShift;
1389
1390 // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
Eric Laurentad9cb8b2015-05-26 16:38:19 -07001391 nsecs_t mStandbyDelayNs;
Eric Laurent81784c32012-11-19 14:55:58 -08001392
1393 // MIXER only
1394 nsecs_t maxPeriod;
1395
1396 // DUPLICATING only
1397 uint32_t writeFrames;
1398
Eric Laurentbfb1b832013-01-07 09:53:42 -08001399 size_t mBytesRemaining;
1400 size_t mCurrentWriteLength;
1401 bool mUseAsyncWrite;
Eric Laurent3b4529e2013-09-05 18:09:19 -07001402 // mWriteAckSequence contains current write sequence on bits 31-1. The write sequence is
1403 // incremented each time a write(), a flush() or a standby() occurs.
1404 // Bit 0 is set when a write blocks and indicates a callback is expected.
1405 // Bit 0 is reset by the async callback thread calling resetWriteBlocked(). Out of sequence
1406 // callbacks are ignored.
1407 uint32_t mWriteAckSequence;
1408 // mDrainSequence contains current drain sequence on bits 31-1. The drain sequence is
1409 // incremented each time a drain is requested or a flush() or standby() occurs.
1410 // Bit 0 is set when the drain() command is called at the HAL and indicates a callback is
1411 // expected.
1412 // Bit 0 is reset by the async callback thread calling resetDraining(). Out of sequence
1413 // callbacks are ignored.
1414 uint32_t mDrainSequence;
Andy Hung71742ab2023-07-07 13:47:37 -07001415
Eric Laurentbfb1b832013-01-07 09:53:42 -08001416 sp<AsyncCallbackThread> mCallbackThread;
1417
Andy Hung87e82412023-08-29 14:26:09 -07001418 audio_utils::mutex& audioTrackCbMutex() const { return mAudioTrackCbMutex; }
1419 mutable audio_utils::mutex mAudioTrackCbMutex;
jiabinf6eb4c32020-02-25 14:06:25 -08001420 // Record of IAudioTrackCallback
Andy Hung3ff4b552023-06-26 19:20:57 -07001421 std::map<sp<IAfTrack>, sp<media::IAudioTrackCallback>> mAudioTrackCallbacks;
jiabinf6eb4c32020-02-25 14:06:25 -08001422
Eric Laurent81784c32012-11-19 14:55:58 -08001423 // The HAL output sink is treated as non-blocking, but current implementation is blocking
1424 sp<NBAIO_Sink> mOutputSink;
1425 // If a fast mixer is present, the blocking pipe sink, otherwise clear
1426 sp<NBAIO_Sink> mPipeSink;
1427 // The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink
1428 sp<NBAIO_Sink> mNormalSink;
Andy Hung71742ab2023-07-07 13:47:37 -07001429
Eric Laurent81784c32012-11-19 14:55:58 -08001430 uint32_t mScreenState; // cached copy of gScreenState
Sanna Catherine de Treville Wager2a6a9452017-07-28 11:02:01 -07001431 // TODO: add comment and adjust size as needed
Glenn Kasteneef598c2017-04-03 14:41:13 -07001432 static const size_t kFastMixerLogSize = 8 * 1024;
Glenn Kasten9e58b552013-01-18 15:09:48 -08001433 sp<NBLog::Writer> mFastMixerNBLogWriter;
Andy Hung2148bf02016-11-28 19:01:02 -08001434
Dean Wheatley30d28422018-11-06 10:27:40 +11001435 // Downstream patch latency, available if mDownstreamLatencyStatMs.getN() > 0.
1436 audio_utils::Statistics<double> mDownstreamLatencyStatMs{0.999};
Andy Hung2148bf02016-11-28 19:01:02 -08001437
Eric Laurent19952e12023-04-20 10:08:29 +02001438 // output stream start detection based on render position returned by the kernel
1439 // condition signalled when the output stream has started
Andy Hung87e82412023-08-29 14:26:09 -07001440 audio_utils::condition_variable mWaitHalStartCV;
Eric Laurent19952e12023-04-20 10:08:29 +02001441 // true when the output stream render position has moved, reset to false in standby
1442 bool mHalStarted = false;
1443 // last kernel render position saved when entering standby
1444 int64_t mKernelPositionOnStandby = 0;
1445
Eric Laurent81784c32012-11-19 14:55:58 -08001446public:
Andy Hung4989d312023-06-29 21:19:25 -07001447 FastTrackUnderruns getFastTrackUnderruns(size_t /* fastIndex */) const override
1448 { return {}; }
1449 const std::atomic<int64_t>& framesWritten() const final { return mFramesWritten; }
Eric Laurent81784c32012-11-19 14:55:58 -08001450
1451protected:
1452 // accessed by both binder threads and within threadLoop(), lock on mutex needed
Andy Hung94dfbb42023-09-06 19:41:47 -07001453 uint32_t& fastTrackAvailMask_l() final REQUIRES(mutex()) { return mFastTrackAvailMask; }
Andy Hung44f27182023-07-06 20:56:16 -07001454 uint32_t mFastTrackAvailMask; // bit i set if fast track [i] is available
Eric Laurentd1f69b02014-12-15 14:33:13 -08001455 bool mHwSupportsPause;
1456 bool mHwPaused;
1457 bool mFlushPending;
Eric Laurent7c29ec92017-09-20 17:54:22 -07001458 // volumes last sent to audio HAL with stream->setVolume()
1459 float mLeftVolFloat;
1460 float mRightVolFloat;
Eric Laurent74c38dc2020-12-23 18:19:44 +01001461
1462 // audio patch used by the downstream software patch.
1463 // Only used if ThreadBase::mIsMsdDevice is true.
1464 struct audio_patch mDownStreamPatch;
Eric Laurentb3f315a2021-07-13 15:09:05 +02001465
1466 std::atomic_bool mCheckOutputStageEffects{};
ziyangch8f194f12021-12-01 13:48:04 -08001467
ziyangch8f194f12021-12-01 13:48:04 -08001468
Brian Lindahl9e661ad2022-07-27 18:01:07 +02001469 // Provides periodic checking for timestamp advancement for underrun detection.
1470 class IsTimestampAdvancing {
1471 public:
1472 // The timestamp will not be checked any faster than the specified time.
Andy Hung71ba4b32022-10-06 12:09:49 -07001473 explicit IsTimestampAdvancing(nsecs_t minimumTimeBetweenChecksNs)
Brian Lindahl9e661ad2022-07-27 18:01:07 +02001474 : mMinimumTimeBetweenChecksNs(minimumTimeBetweenChecksNs)
1475 {
1476 clear();
1477 }
1478 // Check if the presentation position has advanced in the last periodic time.
1479 bool check(AudioStreamOut * output);
1480 // Clear the internal state when the playback state changes for the output
1481 // stream.
1482 void clear();
1483 private:
1484 // The minimum time between timestamp checks.
1485 const nsecs_t mMinimumTimeBetweenChecksNs;
1486 // Add differential check on the timestamps to see if there is a change in the
1487 // timestamp frame position between the last call to check.
1488 uint64_t mPreviousPosition;
1489 // The time at which the last check occurred, to ensure we don't check too
1490 // frequently, giving the Audio HAL enough time to update its timestamps.
1491 nsecs_t mPreviousNs;
1492 // The valued is latched so we don't check timestamps too frequently.
1493 bool mLatchedValue;
1494 };
1495 IsTimestampAdvancing mIsTimestampAdvancing;
ziyangch8f194f12021-12-01 13:48:04 -08001496
Brian Lindahl9e661ad2022-07-27 18:01:07 +02001497 virtual void flushHw_l() {
1498 mIsTimestampAdvancing.clear();
1499 }
Eric Laurent81784c32012-11-19 14:55:58 -08001500};
1501
Eric Laurentb0463942022-12-20 16:31:10 +01001502class MixerThread : public PlaybackThread,
1503 public StreamOutHalInterfaceLatencyModeCallback {
Eric Laurent81784c32012-11-19 14:55:58 -08001504public:
Andy Hung2cbc2722023-07-17 17:05:00 -07001505 MixerThread(const sp<IAfThreadCallback>& afThreadCallback,
Eric Laurent81784c32012-11-19 14:55:58 -08001506 AudioStreamOut* output,
1507 audio_io_handle_t id,
Eric Laurent72e3f392015-05-20 14:43:50 -07001508 bool systemReady,
Eric Laurentf1f22e72021-07-13 14:04:14 +02001509 type_t type = MIXER,
1510 audio_config_base_t *mixerConfig = nullptr);
Andy Hung4989d312023-06-29 21:19:25 -07001511 ~MixerThread() override;
Eric Laurent81784c32012-11-19 14:55:58 -08001512
Eric Laurentb0463942022-12-20 16:31:10 +01001513 // RefBase
Andy Hung4989d312023-06-29 21:19:25 -07001514 void onFirstRef() override;
Eric Laurentb0463942022-12-20 16:31:10 +01001515
1516 // StreamOutHalInterfaceLatencyModeCallback
1517 void onRecommendedLatencyModeChanged(
Andy Hung4989d312023-06-29 21:19:25 -07001518 std::vector<audio_latency_mode_t> modes) final;
Eric Laurentb0463942022-12-20 16:31:10 +01001519
Eric Laurent81784c32012-11-19 14:55:58 -08001520 // Thread virtuals
1521
Andy Hung94dfbb42023-09-06 19:41:47 -07001522 bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) final
1523 REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001524
Andy Hung4989d312023-06-29 21:19:25 -07001525 bool isTrackAllowed_l(
Andy Hung1bc088a2018-02-09 15:57:31 -08001526 audio_channel_mask_t channelMask, audio_format_t format,
Andy Hung94dfbb42023-09-06 19:41:47 -07001527 audio_session_t sessionId, uid_t uid) const final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001528protected:
Andy Hung4989d312023-06-29 21:19:25 -07001529 mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) override;
1530 uint32_t idleSleepTimeUs() const final;
1531 uint32_t suspendSleepTimeUs() const final;
Andy Hung94dfbb42023-09-06 19:41:47 -07001532 void cacheParameters_l() override REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001533
Andy Hung94dfbb42023-09-06 19:41:47 -07001534 void acquireWakeLock_l() final REQUIRES(mutex()) {
Andy Hungdae27702016-10-31 14:01:16 -07001535 PlaybackThread::acquireWakeLock_l();
Andy Hung818e7a32016-02-16 18:08:07 -08001536 if (hasFastMixer()) {
1537 mFastMixer->setBoottimeOffset(
1538 mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME]);
1539 }
1540 }
1541
Andy Hung94dfbb42023-09-06 19:41:47 -07001542 void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -07001543
Eric Laurent81784c32012-11-19 14:55:58 -08001544 // threadLoop snippets
Andy Hung4989d312023-06-29 21:19:25 -07001545 ssize_t threadLoop_write() override;
1546 void threadLoop_standby() override;
1547 void threadLoop_mix() override;
1548 void threadLoop_sleepTime() override;
Andy Hung94dfbb42023-09-06 19:41:47 -07001549 uint32_t correctLatency_l(uint32_t latency) const final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001550
Andy Hung4989d312023-06-29 21:19:25 -07001551 status_t createAudioPatch_l(
Andy Hung94dfbb42023-09-06 19:41:47 -07001552 const struct audio_patch* patch, audio_patch_handle_t* handle)
1553 final REQUIRES(mutex());
1554 status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final REQUIRES(mutex());
Eric Laurent054d9d32015-04-24 08:48:48 -07001555
Eric Laurent81784c32012-11-19 14:55:58 -08001556 AudioMixer* mAudioMixer; // normal mixer
Eric Laurentb0463942022-12-20 16:31:10 +01001557
1558 // Support low latency mode by default as unless explicitly indicated by the audio HAL
1559 // we assume the audio path is compatible with the head tracking latency requirements
1560 std::vector<audio_latency_mode_t> mSupportedLatencyModes = {AUDIO_LATENCY_MODE_LOW};
1561 // default to invalid value to force first update to the audio HAL
1562 audio_latency_mode_t mSetLatencyMode =
1563 (audio_latency_mode_t)AUDIO_LATENCY_MODE_INVALID;
1564
1565 // Bluetooth Variable latency control logic is enabled or disabled for this thread
1566 std::atomic_bool mBluetoothLatencyModesEnabled;
1567
Eric Laurent81784c32012-11-19 14:55:58 -08001568private:
1569 // one-time initialization, no locks required
Glenn Kasten4d23ca32014-05-13 10:39:51 -07001570 sp<FastMixer> mFastMixer; // non-0 if there is also a fast mixer
Eric Laurent81784c32012-11-19 14:55:58 -08001571 sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread
1572
1573 // contents are not guaranteed to be consistent, no locks required
1574 FastMixerDumpState mFastMixerDumpState;
1575#ifdef STATE_QUEUE_DUMP
1576 StateQueueObserverDump mStateQueueObserverDump;
1577 StateQueueMutatorDump mStateQueueMutatorDump;
1578#endif
1579 AudioWatchdogDump mAudioWatchdogDump;
1580
1581 // accessible only within the threadLoop(), no locks required
1582 // mFastMixer->sq() // for mutating and pushing state
1583 int32_t mFastMixerFutex; // for cold idle
1584
Andy Hung2ddee192015-12-18 17:34:44 -08001585 std::atomic_bool mMasterMono;
Eric Laurent81784c32012-11-19 14:55:58 -08001586public:
Glenn Kasten4d23ca32014-05-13 10:39:51 -07001587 virtual bool hasFastMixer() const { return mFastMixer != 0; }
Eric Laurent81784c32012-11-19 14:55:58 -08001588 virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const {
Glenn Kastendc2c50b2016-04-21 08:13:14 -07001589 ALOG_ASSERT(fastIndex < FastMixerState::sMaxFastTracks);
Eric Laurent81784c32012-11-19 14:55:58 -08001590 return mFastMixerDumpState.mTracks[fastIndex].mUnderruns;
1591 }
Eric Laurent83b88082014-06-20 18:31:16 -07001592
Andy Hung94dfbb42023-09-06 19:41:47 -07001593 status_t threadloop_getHalTimestamp_l(
1594 ExtendedTimestamp *timestamp) const override REQUIRES(mutex()) {
Andy Hung1c86ebe2018-05-29 20:29:08 -07001595 if (mNormalSink.get() != nullptr) {
1596 return mNormalSink->getTimestamp(*timestamp);
1597 }
1598 return INVALID_OPERATION;
1599 }
1600
Eric Laurentb0463942022-12-20 16:31:10 +01001601 status_t getSupportedLatencyModes(
1602 std::vector<audio_latency_mode_t>* modes) override;
1603
1604 status_t setBluetoothVariableLatencyEnabled(bool enabled) override;
1605
Andy Hung2ddee192015-12-18 17:34:44 -08001606protected:
1607 virtual void setMasterMono_l(bool mono) {
1608 mMasterMono.store(mono);
1609 if (mFastMixer != nullptr) { /* hasFastMixer() */
1610 mFastMixer->setMasterMono(mMasterMono);
1611 }
1612 }
1613 // the FastMixer performs mono blend if it exists.
Glenn Kasten03c48d52016-01-27 17:25:17 -08001614 // Blending with limiter is not idempotent,
1615 // and blending without limiter is idempotent but inefficient to do twice.
Andy Hung2ddee192015-12-18 17:34:44 -08001616 virtual bool requireMonoBlend() { return mMasterMono.load() && !hasFastMixer(); }
Richard Folke Tullberg3fae0372017-01-13 09:04:25 +01001617
Andy Hung94dfbb42023-09-06 19:41:47 -07001618 void setMasterBalance(float balance) override EXCLUDES_ThreadBase_Mutex {
Richard Folke Tullberg3fae0372017-01-13 09:04:25 +01001619 mMasterBalance.store(balance);
1620 if (hasFastMixer()) {
1621 mFastMixer->setMasterBalance(balance);
1622 }
1623 }
Eric Laurentb0463942022-12-20 16:31:10 +01001624
Andy Hung94dfbb42023-09-06 19:41:47 -07001625 void updateHalSupportedLatencyModes_l() REQUIRES(mutex());
1626 void onHalLatencyModesChanged_l() override REQUIRES(mutex());
1627 void setHalLatencyMode_l() override REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001628};
1629
Andy Hung44f27182023-07-06 20:56:16 -07001630class DirectOutputThread : public PlaybackThread, public virtual IAfDirectOutputThread {
Eric Laurent81784c32012-11-19 14:55:58 -08001631public:
1632
Andy Hung44f27182023-07-06 20:56:16 -07001633 sp<IAfDirectOutputThread> asIAfDirectOutputThread() final {
1634 return sp<IAfDirectOutputThread>::fromExisting(this);
1635 }
1636
Andy Hung2cbc2722023-07-17 17:05:00 -07001637 DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
Gareth Fenn56576722022-10-05 13:42:36 -07001638 audio_io_handle_t id, bool systemReady,
1639 const audio_offload_info_t& offloadInfo)
Andy Hung2cbc2722023-07-17 17:05:00 -07001640 : DirectOutputThread(afThreadCallback, output, id, DIRECT, systemReady, offloadInfo) { }
Andy Hung48f59ed2019-01-28 15:06:59 -08001641
Andy Hung94dfbb42023-09-06 19:41:47 -07001642 ~DirectOutputThread() override;
Eric Laurent81784c32012-11-19 14:55:58 -08001643
Andy Hung44f27182023-07-06 20:56:16 -07001644 status_t selectPresentation(int presentationId, int programId) final;
Mikhail Naganovac917ac2018-11-28 14:03:52 -08001645
Eric Laurent81784c32012-11-19 14:55:58 -08001646 // Thread virtuals
1647
Eric Laurent10351942014-05-08 18:49:52 -07001648 virtual bool checkForNewParameter_l(const String8& keyValuePair,
Andy Hung94dfbb42023-09-06 19:41:47 -07001649 status_t& status) REQUIRES(mutex());
Richard Folke Tullberg3fae0372017-01-13 09:04:25 +01001650
Andy Hung94dfbb42023-09-06 19:41:47 -07001651 void flushHw_l() override REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001652
Andy Hung94dfbb42023-09-06 19:41:47 -07001653 void setMasterBalance(float balance) override EXCLUDES_ThreadBase_Mutex;
Richard Folke Tullberg3fae0372017-01-13 09:04:25 +01001654
Eric Laurent81784c32012-11-19 14:55:58 -08001655protected:
Eric Laurent81784c32012-11-19 14:55:58 -08001656 virtual uint32_t activeSleepTimeUs() const;
1657 virtual uint32_t idleSleepTimeUs() const;
1658 virtual uint32_t suspendSleepTimeUs() const;
Andy Hung94dfbb42023-09-06 19:41:47 -07001659 virtual void cacheParameters_l() REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001660
Andy Hung94dfbb42023-09-06 19:41:47 -07001661 void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -07001662
Eric Laurent81784c32012-11-19 14:55:58 -08001663 // threadLoop snippets
Andy Hung94dfbb42023-09-06 19:41:47 -07001664 virtual mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001665 virtual void threadLoop_mix();
1666 virtual void threadLoop_sleepTime();
Eric Laurentd1f69b02014-12-15 14:33:13 -08001667 virtual void threadLoop_exit();
Andy Hung94dfbb42023-09-06 19:41:47 -07001668 virtual bool shouldStandby_l() REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001669
Andy Hung94dfbb42023-09-06 19:41:47 -07001670 virtual void onAddNewTrack_l() REQUIRES(mutex());
Phil Burk43b4dcc2015-06-09 16:53:44 -07001671
Gareth Fenn56576722022-10-05 13:42:36 -07001672 const audio_offload_info_t mOffloadInfo;
Andy Hungee86cee2022-12-13 19:19:53 -08001673
1674 audioflinger::MonotonicFrameCounter mMonotonicFrameCounter; // for VolumeShaper
Andy Hung48f59ed2019-01-28 15:06:59 -08001675 bool mVolumeShaperActive = false;
Eric Laurent81784c32012-11-19 14:55:58 -08001676
Andy Hung2cbc2722023-07-17 17:05:00 -07001677 DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
Gareth Fenn56576722022-10-05 13:42:36 -07001678 audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
1679 const audio_offload_info_t& offloadInfo);
Andy Hung94dfbb42023-09-06 19:41:47 -07001680 void processVolume_l(IAfTrack *track, bool lastTrack) REQUIRES(mutex());
Gareth Fenn56576722022-10-05 13:42:36 -07001681 bool isTunerStream() const { return (mOffloadInfo.content_id > 0); }
Eric Laurentbfb1b832013-01-07 09:53:42 -08001682
Eric Laurent81784c32012-11-19 14:55:58 -08001683 // prepareTracks_l() tells threadLoop_mix() the name of the single active track
Andy Hung3ff4b552023-06-26 19:20:57 -07001684 sp<IAfTrack> mActiveTrack;
Phil Burk43b4dcc2015-06-09 16:53:44 -07001685
Andy Hung3ff4b552023-06-26 19:20:57 -07001686 wp<IAfTrack> mPreviousTrack; // used to detect track switch
Phil Burk43b4dcc2015-06-09 16:53:44 -07001687
Richard Folke Tullberg3fae0372017-01-13 09:04:25 +01001688 // This must be initialized for initial condition of mMasterBalance = 0 (disabled).
1689 float mMasterBalanceLeft = 1.f;
1690 float mMasterBalanceRight = 1.f;
1691
Eric Laurent81784c32012-11-19 14:55:58 -08001692public:
1693 virtual bool hasFastMixer() const { return false; }
Andy Hung10cbff12017-02-21 17:30:14 -08001694
Andy Hung94dfbb42023-09-06 19:41:47 -07001695 virtual int64_t computeWaitTimeNs_l() const override REQUIRES(mutex());
Andy Hungf3234512018-07-03 14:51:47 -07001696
1697 status_t threadloop_getHalTimestamp_l(ExtendedTimestamp *timestamp) const override {
1698 // For DIRECT and OFFLOAD threads, query the output sink directly.
1699 if (mOutput != nullptr) {
1700 uint64_t uposition64;
1701 struct timespec time;
1702 if (mOutput->getPresentationPosition(
1703 &uposition64, &time) == OK) {
1704 timestamp->mPosition[ExtendedTimestamp::LOCATION_KERNEL]
1705 = (int64_t)uposition64;
1706 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]
1707 = audio_utils_ns_from_timespec(&time);
1708 return NO_ERROR;
1709 }
1710 }
1711 return INVALID_OPERATION;
1712 }
Eric Laurent81784c32012-11-19 14:55:58 -08001713};
1714
Eric Laurentbfb1b832013-01-07 09:53:42 -08001715class OffloadThread : public DirectOutputThread {
1716public:
1717
Andy Hung2cbc2722023-07-17 17:05:00 -07001718 OffloadThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
Gareth Fenn56576722022-10-05 13:42:36 -07001719 audio_io_handle_t id, bool systemReady,
1720 const audio_offload_info_t& offloadInfo);
Eric Laurent6a51d7e2013-10-17 18:59:26 -07001721 virtual ~OffloadThread() {};
Andy Hung94dfbb42023-09-06 19:41:47 -07001722 void flushHw_l() final REQUIRES(mutex());
Eric Laurentbfb1b832013-01-07 09:53:42 -08001723
1724protected:
1725 // threadLoop snippets
Andy Hung94dfbb42023-09-06 19:41:47 -07001726 mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) final
1727 REQUIRES(mutex());
1728 void threadLoop_exit() final;
Eric Laurentbfb1b832013-01-07 09:53:42 -08001729
Andy Hung94dfbb42023-09-06 19:41:47 -07001730 bool waitingAsyncCallback() final;
1731 bool waitingAsyncCallback_l() final REQUIRES(mutex());
1732 void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
1733 void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;
Eric Laurentbfb1b832013-01-07 09:53:42 -08001734
Andy Hung94dfbb42023-09-06 19:41:47 -07001735 bool keepWakeLock() const final { return (mKeepWakeLock || (mDrainSequence & 1)); }
Eric Laurent64667972016-03-30 18:19:46 -07001736
Eric Laurentbfb1b832013-01-07 09:53:42 -08001737private:
Eric Laurentbfb1b832013-01-07 09:53:42 -08001738 size_t mPausedWriteLength; // length in bytes of write interrupted by pause
1739 size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume
Eric Laurent64667972016-03-30 18:19:46 -07001740 bool mKeepWakeLock; // keep wake lock while waiting for write callback
Eric Laurentbfb1b832013-01-07 09:53:42 -08001741};
1742
1743class AsyncCallbackThread : public Thread {
1744public:
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07001745 explicit AsyncCallbackThread(const wp<PlaybackThread>& playbackThread);
Eric Laurentbfb1b832013-01-07 09:53:42 -08001746
Eric Laurentbfb1b832013-01-07 09:53:42 -08001747 // Thread virtuals
1748 virtual bool threadLoop();
1749
1750 // RefBase
1751 virtual void onFirstRef();
1752
1753 void exit();
Eric Laurent3b4529e2013-09-05 18:09:19 -07001754 void setWriteBlocked(uint32_t sequence);
1755 void resetWriteBlocked();
1756 void setDraining(uint32_t sequence);
1757 void resetDraining();
Haynes Mathew George4527b9e2016-07-07 19:54:17 -07001758 void setAsyncError();
Eric Laurentbfb1b832013-01-07 09:53:42 -08001759
1760private:
Eric Laurent4de95592013-09-26 15:28:21 -07001761 const wp<PlaybackThread> mPlaybackThread;
Eric Laurent3b4529e2013-09-05 18:09:19 -07001762 // mWriteAckSequence corresponds to the last write sequence passed by the offload thread via
1763 // setWriteBlocked(). The sequence is shifted one bit to the left and the lsb is used
1764 // to indicate that the callback has been received via resetWriteBlocked()
Eric Laurent4de95592013-09-26 15:28:21 -07001765 uint32_t mWriteAckSequence;
Eric Laurent3b4529e2013-09-05 18:09:19 -07001766 // mDrainSequence corresponds to the last drain sequence passed by the offload thread via
1767 // setDraining(). The sequence is shifted one bit to the left and the lsb is used
1768 // to indicate that the callback has been received via resetDraining()
Eric Laurent4de95592013-09-26 15:28:21 -07001769 uint32_t mDrainSequence;
Andy Hung87e82412023-08-29 14:26:09 -07001770 audio_utils::condition_variable mWaitWorkCV;
1771 mutable audio_utils::mutex mMutex;
Haynes Mathew George4527b9e2016-07-07 19:54:17 -07001772 bool mAsyncError;
Andy Hung87e82412023-08-29 14:26:09 -07001773
Andy Hung94dfbb42023-09-06 19:41:47 -07001774 audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::AsyncCallbackThread_Mutex) {
1775 return mMutex;
1776 }
Eric Laurentbfb1b832013-01-07 09:53:42 -08001777};
1778
Andy Hung44f27182023-07-06 20:56:16 -07001779class DuplicatingThread : public MixerThread, public IAfDuplicatingThread {
Eric Laurent81784c32012-11-19 14:55:58 -08001780public:
Andy Hung2cbc2722023-07-17 17:05:00 -07001781 DuplicatingThread(const sp<IAfThreadCallback>& afThreadCallback,
1782 IAfPlaybackThread* mainThread,
Eric Laurent72e3f392015-05-20 14:43:50 -07001783 audio_io_handle_t id, bool systemReady);
Andy Hung44f27182023-07-06 20:56:16 -07001784 ~DuplicatingThread() override;
1785
1786 sp<IAfDuplicatingThread> asIAfDuplicatingThread() final {
1787 return sp<IAfDuplicatingThread>::fromExisting(this);
1788 }
Eric Laurent81784c32012-11-19 14:55:58 -08001789
1790 // Thread virtuals
Andy Hung94dfbb42023-09-06 19:41:47 -07001791 void addOutputTrack(IAfPlaybackThread* thread) final EXCLUDES_ThreadBase_Mutex;
1792 void removeOutputTrack(IAfPlaybackThread* thread) final EXCLUDES_ThreadBase_Mutex;
Andy Hung44f27182023-07-06 20:56:16 -07001793 uint32_t waitTimeMs() const final { return mWaitTimeMs; }
Kevin Rocard069c2712018-03-29 19:09:14 -07001794
Kevin Rocardc86a7f72018-04-03 09:00:09 -07001795 void sendMetadataToBackend_l(
Andy Hung94dfbb42023-09-06 19:41:47 -07001796 const StreamOutHalInterface::SourceMetadata& metadata) final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001797protected:
1798 virtual uint32_t activeSleepTimeUs() const;
Andy Hung94dfbb42023-09-06 19:41:47 -07001799 void dumpInternals_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001800
1801private:
Andy Hung71ba4b32022-10-06 12:09:49 -07001802 bool outputsReady();
Eric Laurent81784c32012-11-19 14:55:58 -08001803protected:
1804 // threadLoop snippets
Andy Hung94dfbb42023-09-06 19:41:47 -07001805 void threadLoop_mix() final;
1806 void threadLoop_sleepTime() final;
1807 ssize_t threadLoop_write() final;
1808 void threadLoop_standby() final;
1809 void cacheParameters_l() final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001810
1811private:
1812 // called from threadLoop, addOutputTrack, removeOutputTrack
Andy Hung94dfbb42023-09-06 19:41:47 -07001813 void updateWaitTime_l() REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001814protected:
Andy Hung94dfbb42023-09-06 19:41:47 -07001815 void saveOutputTracks() final;
1816 void clearOutputTracks() final;
Eric Laurent81784c32012-11-19 14:55:58 -08001817private:
1818
1819 uint32_t mWaitTimeMs;
Andy Hung3ff4b552023-06-26 19:20:57 -07001820 SortedVector <sp<IAfOutputTrack>> outputTracks;
1821 SortedVector <sp<IAfOutputTrack>> mOutputTracks;
Eric Laurent81784c32012-11-19 14:55:58 -08001822public:
1823 virtual bool hasFastMixer() const { return false; }
Andy Hung1c86ebe2018-05-29 20:29:08 -07001824 status_t threadloop_getHalTimestamp_l(
Andy Hung94dfbb42023-09-06 19:41:47 -07001825 ExtendedTimestamp *timestamp) const override REQUIRES(mutex()) {
Andy Hung1c86ebe2018-05-29 20:29:08 -07001826 if (mOutputTracks.size() > 0) {
1827 // forward the first OutputTrack's kernel information for timestamp.
1828 const ExtendedTimestamp trackTimestamp =
1829 mOutputTracks[0]->getClientProxyTimestamp();
1830 if (trackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] > 0) {
1831 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
1832 trackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
1833 timestamp->mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
1834 trackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
1835 return OK; // discard server timestamp - that's ignored.
1836 }
1837 }
1838 return INVALID_OPERATION;
1839 }
Eric Laurent81784c32012-11-19 14:55:58 -08001840};
1841
Eric Laurentb0463942022-12-20 16:31:10 +01001842class SpatializerThread : public MixerThread {
Eric Laurentb3f315a2021-07-13 15:09:05 +02001843public:
Andy Hung2cbc2722023-07-17 17:05:00 -07001844 SpatializerThread(const sp<IAfThreadCallback>& afThreadCallback,
Eric Laurentb3f315a2021-07-13 15:09:05 +02001845 AudioStreamOut* output,
1846 audio_io_handle_t id,
1847 bool systemReady,
1848 audio_config_base_t *mixerConfig);
Eric Laurentb3f315a2021-07-13 15:09:05 +02001849
Andy Hung4989d312023-06-29 21:19:25 -07001850 bool hasFastMixer() const final { return false; }
Eric Laurentb3f315a2021-07-13 15:09:05 +02001851
Andy Hung94dfbb42023-09-06 19:41:47 -07001852 status_t setRequestedLatencyMode(audio_latency_mode_t mode) final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6f9534f2022-05-03 18:15:04 +02001853
Eric Laurentb3f315a2021-07-13 15:09:05 +02001854protected:
Andy Hung94dfbb42023-09-06 19:41:47 -07001855 void checkOutputStageEffects() final EXCLUDES_ThreadBase_Mutex;
1856 void setHalLatencyMode_l() final REQUIRES(mutex());
Eric Laurentb3f315a2021-07-13 15:09:05 +02001857
1858private:
Eric Laurent6f9534f2022-05-03 18:15:04 +02001859 // Do not request a specific mode by default
1860 audio_latency_mode_t mRequestedLatencyMode = AUDIO_LATENCY_MODE_FREE;
1861
Andy Hungbd72c542023-06-20 18:56:17 -07001862 sp<IAfEffectHandle> mFinalDownMixer;
Eric Laurentb3f315a2021-07-13 15:09:05 +02001863};
1864
Eric Laurent81784c32012-11-19 14:55:58 -08001865// record thread
Andy Hung44f27182023-07-06 20:56:16 -07001866class RecordThread : public IAfRecordThread, public ThreadBase
Eric Laurent81784c32012-11-19 14:55:58 -08001867{
Andy Hung3ff4b552023-06-26 19:20:57 -07001868 friend class ResamplerBufferProvider;
Eric Laurent81784c32012-11-19 14:55:58 -08001869public:
Andy Hung44f27182023-07-06 20:56:16 -07001870 sp<IAfRecordThread> asIAfRecordThread() final {
1871 return sp<IAfRecordThread>::fromExisting(this);
1872 }
Eric Laurent81784c32012-11-19 14:55:58 -08001873
Andy Hung2cbc2722023-07-17 17:05:00 -07001874 RecordThread(const sp<IAfThreadCallback>& afThreadCallback,
Eric Laurent81784c32012-11-19 14:55:58 -08001875 AudioStreamIn *input,
Eric Laurent81784c32012-11-19 14:55:58 -08001876 audio_io_handle_t id,
Eric Laurent72e3f392015-05-20 14:43:50 -07001877 bool systemReady
Glenn Kasten46909e72013-02-26 09:20:22 -08001878 );
Andy Hung4989d312023-06-29 21:19:25 -07001879 ~RecordThread() override;
Eric Laurent81784c32012-11-19 14:55:58 -08001880
1881 // no addTrack_l ?
Andy Hung94dfbb42023-09-06 19:41:47 -07001882 void destroyTrack_l(const sp<IAfRecordTrack>& track) final REQUIRES(mutex());
1883 void removeTrack_l(const sp<IAfRecordTrack>& track) final REQUIRES(mutex());
Eric Laurent81784c32012-11-19 14:55:58 -08001884
Eric Laurent81784c32012-11-19 14:55:58 -08001885 // Thread virtuals
Andy Hung94dfbb42023-09-06 19:41:47 -07001886 bool threadLoop() final EXCLUDES_ThreadBase_Mutex;
1887 void preExit() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -08001888
1889 // RefBase
Andy Hung94dfbb42023-09-06 19:41:47 -07001890 void onFirstRef() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -08001891
Andy Hung4989d312023-06-29 21:19:25 -07001892 status_t initCheck() const final { return mInput == nullptr ? NO_INIT : NO_ERROR; }
Glenn Kastene198c362013-08-13 09:13:36 -07001893
Andy Hung4989d312023-06-29 21:19:25 -07001894 sp<MemoryDealer> readOnlyHeap() const final { return mReadOnlyHeap; }
Glenn Kastenb880f5e2014-05-07 08:43:45 -07001895
Andy Hung4989d312023-06-29 21:19:25 -07001896 sp<IMemory> pipeMemory() const final { return mPipeMemory; }
Glenn Kasten6dbb5e32014-05-13 10:38:42 -07001897
Andy Hung44f27182023-07-06 20:56:16 -07001898 sp<IAfRecordTrack> createRecordTrack_l(
Andy Hungd65869f2023-06-27 17:05:02 -07001899 const sp<Client>& client,
Kevin Rocard1f564ac2018-03-29 13:53:10 -07001900 const audio_attributes_t& attr,
Eric Laurentf14db3c2017-12-08 14:20:36 -08001901 uint32_t *pSampleRate,
Eric Laurent81784c32012-11-19 14:55:58 -08001902 audio_format_t format,
1903 audio_channel_mask_t channelMask,
Glenn Kasten74935e42013-12-19 08:56:45 -08001904 size_t *pFrameCount,
Glenn Kastend848eb42016-03-08 13:42:11 -08001905 audio_session_t sessionId,
Eric Laurentf14db3c2017-12-08 14:20:36 -08001906 size_t *pNotificationFrameCount,
Eric Laurent09f1ed22019-04-24 17:45:17 -07001907 pid_t creatorPid,
Svet Ganov33761132021-05-13 22:51:08 +00001908 const AttributionSourceState& attributionSource,
Eric Laurent05067782016-06-01 18:27:28 -07001909 audio_input_flags_t *flags,
Eric Laurent81784c32012-11-19 14:55:58 -08001910 pid_t tid,
Eric Laurent20b9ef02016-12-05 11:03:16 -08001911 status_t *status /*non-NULL*/,
Eric Laurentec376dc2021-04-08 20:41:22 +02001912 audio_port_handle_t portId,
Andy Hungf79092d2023-08-31 16:13:39 -07001913 int32_t maxSharedAudioHistoryMs) final
Andy Hung94dfbb42023-09-06 19:41:47 -07001914 REQUIRES(audio_utils::AudioFlinger_Mutex) EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -08001915
Andy Hung3ff4b552023-06-26 19:20:57 -07001916 status_t start(IAfRecordTrack* recordTrack,
Eric Laurent81784c32012-11-19 14:55:58 -08001917 AudioSystem::sync_event_t event,
Andy Hung94dfbb42023-09-06 19:41:47 -07001918 audio_session_t triggerSession) final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -08001919
1920 // ask the thread to stop the specified track, and
1921 // return true if the caller should then do it's part of the stopping process
Andy Hung94dfbb42023-09-06 19:41:47 -07001922 bool stop(IAfRecordTrack* recordTrack) final EXCLUDES_ThreadBase_Mutex;
Andy Hung44f27182023-07-06 20:56:16 -07001923 AudioStreamIn* getInput() const final { return mInput; }
1924 AudioStreamIn* clearInput() final;
Eric Laurent81784c32012-11-19 14:55:58 -08001925
Andy Hung56126702023-07-14 11:00:08 -07001926 // TODO(b/291317898) Unify with IAfThreadBase
Mikhail Naganov1dc98672016-08-18 17:50:29 -07001927 virtual sp<StreamHalInterface> stream() const;
Eric Laurent81784c32012-11-19 14:55:58 -08001928
Eric Laurent81784c32012-11-19 14:55:58 -08001929
Andy Hung94dfbb42023-09-06 19:41:47 -07001930 virtual bool checkForNewParameter_l(const String8& keyValuePair,
1931 status_t& status) REQUIRES(mutex());
1932 virtual void cacheParameters_l() REQUIRES(mutex()) {}
1933 virtual String8 getParameters(const String8& keys) EXCLUDES_ThreadBase_Mutex;
1934
1935 // Hold either the AudioFlinger::mutex or the ThreadBase::mutex
1936 void ioConfigChanged_l(audio_io_config_event_t event, pid_t pid = 0,
Andy Hung44f27182023-07-06 20:56:16 -07001937 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
Eric Laurent1c333e22014-05-20 10:48:17 -07001938 virtual status_t createAudioPatch_l(const struct audio_patch *patch,
Andy Hung94dfbb42023-09-06 19:41:47 -07001939 audio_patch_handle_t *handle) REQUIRES(mutex());
1940 virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) REQUIRES(mutex());
1941 void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override
1942 EXCLUDES_ThreadBase_Mutex;
1943 void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override REQUIRES(mutex());
Eric Laurent83b88082014-06-20 18:31:16 -07001944
Andy Hung94dfbb42023-09-06 19:41:47 -07001945 void addPatchTrack(const sp<IAfPatchRecord>& record) final EXCLUDES_ThreadBase_Mutex;
1946 void deletePatchTrack(const sp<IAfPatchRecord>& record) final EXCLUDES_ThreadBase_Mutex;
Eric Laurent83b88082014-06-20 18:31:16 -07001947
Andy Hung94dfbb42023-09-06 19:41:47 -07001948 void readInputParameters_l() REQUIRES(mutex());
1949 uint32_t getInputFramesLost() const final EXCLUDES_ThreadBase_Mutex;
Eric Laurent81784c32012-11-19 14:55:58 -08001950
Andy Hung94dfbb42023-09-06 19:41:47 -07001951 virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
1952 virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
1953 uint32_t hasAudioSession_l(audio_session_t sessionId) const override REQUIRES(mutex()) {
Andy Hungc3d62f92019-03-14 13:38:51 -07001954 return ThreadBase::hasAudioSession_l(sessionId, mTracks);
1955 }
Eric Laurent81784c32012-11-19 14:55:58 -08001956
1957 // Return the set of unique session IDs across all tracks.
1958 // The keys are the session IDs, and the associated values are meaningless.
1959 // FIXME replace by Set [and implement Bag/Multiset for other uses].
Glenn Kastend848eb42016-03-08 13:42:11 -08001960 KeyedVector<audio_session_t, bool> sessionIds() const;
Eric Laurent81784c32012-11-19 14:55:58 -08001961
Andy Hung94dfbb42023-09-06 19:41:47 -07001962 status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override
1963 EXCLUDES_ThreadBase_Mutex;
Andy Hung068e08e2023-05-15 19:02:55 -07001964 bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const override;
Eric Laurent81784c32012-11-19 14:55:58 -08001965
Andy Hung068e08e2023-05-15 19:02:55 -07001966 static void syncStartEventCallback(const wp<audioflinger::SyncEvent>& event);
Eric Laurent81784c32012-11-19 14:55:58 -08001967
Glenn Kasten9b58f632013-07-16 11:37:48 -07001968 virtual size_t frameCount() const { return mFrameCount; }
Andy Hung44f27182023-07-06 20:56:16 -07001969 bool hasFastCapture() const final { return mFastCapture != 0; }
Mikhail Naganovdc769682018-05-04 15:34:08 -07001970 virtual void toAudioPortConfig(struct audio_port_config *config);
Glenn Kasten9b58f632013-07-16 11:37:48 -07001971
Andy Hung94dfbb42023-09-06 19:41:47 -07001972 virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
1973 audio_session_t sessionId) REQUIRES(mutex());
Eric Laurent4c415062016-06-17 16:14:16 -07001974
Andy Hung94dfbb42023-09-06 19:41:47 -07001975 virtual void acquireWakeLock_l() REQUIRES(mutex()) {
Andy Hungdae27702016-10-31 14:01:16 -07001976 ThreadBase::acquireWakeLock_l();
Andy Hung94dfbb42023-09-06 19:41:47 -07001977 mActiveTracks.updatePowerState_l(this, true /* force */);
Andy Hungdae27702016-10-31 14:01:16 -07001978 }
1979
Andy Hung94dfbb42023-09-06 19:41:47 -07001980 void checkBtNrec() final EXCLUDES_ThreadBase_Mutex;
Eric Laurentd8365c52017-07-16 15:27:05 -07001981
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001982 // Sets the UID records silence
Andy Hung94dfbb42023-09-06 19:41:47 -07001983 void setRecordSilenced(audio_port_handle_t portId, bool silenced) final
1984 EXCLUDES_ThreadBase_Mutex;
Svet Ganovf4ddfef2018-01-16 07:37:58 -08001985
Andy Hung44f27182023-07-06 20:56:16 -07001986 status_t getActiveMicrophones(
Andy Hung94dfbb42023-09-06 19:41:47 -07001987 std::vector<media::MicrophoneInfoFw>* activeMicrophones) const final
1988 EXCLUDES_ThreadBase_Mutex;
1989 status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) final
1990 EXCLUDES_ThreadBase_Mutex;
1991 status_t setPreferredMicrophoneFieldDimension(float zoom) final EXCLUDES_ThreadBase_Mutex;
Paul McLean03a6e6a2018-12-04 10:54:13 -07001992
Andy Hung94dfbb42023-09-06 19:41:47 -07001993 MetadataUpdate updateMetadata_l() override REQUIRES(mutex());
Kevin Rocard069c2712018-03-29 19:09:14 -07001994
Andy Hung44f27182023-07-06 20:56:16 -07001995 bool fastTrackAvailable() const final { return mFastTrackAvail; }
1996 void setFastTrackAvailable(bool available) final { mFastTrackAvail = available; }
jiabin01c8f562018-07-19 17:47:28 -07001997
Andy Hung94dfbb42023-09-06 19:41:47 -07001998 bool isTimestampCorrectionEnabled_l() const override REQUIRES(mutex()) {
Andy Hungc8fddf32018-08-08 18:32:37 -07001999 // checks popcount for exactly one device.
Atneya Nair497fff12022-01-18 16:23:04 -05002000 // Is currently disabled. Before enabling,
2001 // verify compressed record timestamps.
jiabinc52b1ff2019-10-31 17:20:42 -07002002 return audio_is_input_device(mTimestampCorrectedDevice)
Andy Hung94dfbb42023-09-06 19:41:47 -07002003 && inDeviceType_l() == mTimestampCorrectedDevice;
Andy Hungc8fddf32018-08-08 18:32:37 -07002004 }
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -07002005
Andy Hung44f27182023-07-06 20:56:16 -07002006 status_t shareAudioHistory(const std::string& sharedAudioPackageName,
Eric Laurentec376dc2021-04-08 20:41:22 +02002007 audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
Andy Hung94dfbb42023-09-06 19:41:47 -07002008 int64_t sharedAudioStartMs = -1) final EXCLUDES_ThreadBase_Mutex;
Eric Laurentec376dc2021-04-08 20:41:22 +02002009 status_t shareAudioHistory_l(const std::string& sharedAudioPackageName,
2010 audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
Andy Hung94dfbb42023-09-06 19:41:47 -07002011 int64_t sharedAudioStartMs = -1) REQUIRES(mutex());
2012 void resetAudioHistory_l() final REQUIRES(mutex());
Eric Laurentec376dc2021-04-08 20:41:22 +02002013
Andy Hung4989d312023-06-29 21:19:25 -07002014 bool isStreamInitialized() const final {
Jasmine Chaeaa10e42021-05-11 10:11:14 +08002015 return !(mInput == nullptr || mInput->stream == nullptr);
2016 }
2017
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -07002018protected:
Andy Hung94dfbb42023-09-06 19:41:47 -07002019 void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
2020 void dumpTracks_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
Mikhail Naganov01dc5ca2019-03-29 10:12:12 -07002021
Eric Laurent81784c32012-11-19 14:55:58 -08002022private:
Eric Laurent81784c32012-11-19 14:55:58 -08002023 // Enter standby if not already in standby, and set mStandby flag
Glenn Kasten93e471f2013-08-19 08:40:07 -07002024 void standbyIfNotAlreadyInStandby();
Eric Laurent81784c32012-11-19 14:55:58 -08002025
2026 // Call the HAL standby method unconditionally, and don't change mStandby flag
Glenn Kastene198c362013-08-13 09:13:36 -07002027 void inputStandBy();
Eric Laurent81784c32012-11-19 14:55:58 -08002028
Andy Hung94dfbb42023-09-06 19:41:47 -07002029 void checkBtNrec_l() REQUIRES(mutex());
Eric Laurentd8365c52017-07-16 15:27:05 -07002030
Andy Hung94dfbb42023-09-06 19:41:47 -07002031 int32_t getOldestFront_l() REQUIRES(mutex());
2032 void updateFronts_l(int32_t offset) REQUIRES(mutex());
Eric Laurentec376dc2021-04-08 20:41:22 +02002033
Eric Laurent81784c32012-11-19 14:55:58 -08002034 AudioStreamIn *mInput;
Mikhail Naganov2534b382019-09-25 13:05:02 -07002035 Source *mSource;
Andy Hung3ff4b552023-06-26 19:20:57 -07002036 SortedVector <sp<IAfRecordTrack>> mTracks;
Glenn Kasten2b806402013-11-20 16:37:38 -08002037 // mActiveTracks has dual roles: it indicates the current active track(s), and
Andy Hung87e82412023-08-29 14:26:09 -07002038 // is used together with mStartStopCV to indicate start()/stop() progress
Andy Hung3ff4b552023-06-26 19:20:57 -07002039 ActiveTracks<IAfRecordTrack> mActiveTracks;
Andy Hungdae27702016-10-31 14:01:16 -07002040
Andy Hung87e82412023-08-29 14:26:09 -07002041 audio_utils::condition_variable mStartStopCV;
Glenn Kasten9b58f632013-07-16 11:37:48 -07002042
Glenn Kasten85948432013-08-19 12:09:05 -07002043 // resampler converts input at HAL Hz to output at AudioRecord client Hz
Glenn Kasten1b291842016-07-18 14:55:21 -07002044 void *mRsmpInBuffer; // size = mRsmpInFramesOA
Glenn Kasten85948432013-08-19 12:09:05 -07002045 size_t mRsmpInFrames; // size of resampler input in frames
2046 size_t mRsmpInFramesP2;// size rounded up to a power-of-2
Glenn Kasten1b291842016-07-18 14:55:21 -07002047 size_t mRsmpInFramesOA;// mRsmpInFramesP2 + over-allocation
Glenn Kasten6dd62fb2013-12-05 16:35:58 -08002048
2049 // rolling index that is never cleared
Glenn Kasten85948432013-08-19 12:09:05 -07002050 int32_t mRsmpInRear; // last filled frame + 1
Glenn Kasten85948432013-08-19 12:09:05 -07002051
Eric Laurent81784c32012-11-19 14:55:58 -08002052 // For dumpsys
Glenn Kastenb880f5e2014-05-07 08:43:45 -07002053 const sp<MemoryDealer> mReadOnlyHeap;
Glenn Kasten6dbb5e32014-05-13 10:38:42 -07002054
2055 // one-time initialization, no locks required
Glenn Kastenb187de12014-12-30 08:18:15 -08002056 sp<FastCapture> mFastCapture; // non-0 if there is also
2057 // a fast capture
Eric Laurent72e3f392015-05-20 14:43:50 -07002058
Glenn Kasten6dbb5e32014-05-13 10:38:42 -07002059 // FIXME audio watchdog thread
2060
2061 // contents are not guaranteed to be consistent, no locks required
2062 FastCaptureDumpState mFastCaptureDumpState;
2063#ifdef STATE_QUEUE_DUMP
2064 // FIXME StateQueue observer and mutator dump fields
2065#endif
2066 // FIXME audio watchdog dump
2067
2068 // accessible only within the threadLoop(), no locks required
2069 // mFastCapture->sq() // for mutating and pushing state
2070 int32_t mFastCaptureFutex; // for cold idle
2071
2072 // The HAL input source is treated as non-blocking,
2073 // but current implementation is blocking
2074 sp<NBAIO_Source> mInputSource;
2075 // The source for the normal capture thread to read from: mInputSource or mPipeSource
2076 sp<NBAIO_Source> mNormalSource;
2077 // If a fast capture is present, the non-blocking pipe sink written to by fast capture,
2078 // otherwise clear
2079 sp<NBAIO_Sink> mPipeSink;
2080 // If a fast capture is present, the non-blocking pipe source read by normal thread,
2081 // otherwise clear
2082 sp<NBAIO_Source> mPipeSource;
2083 // Depth of pipe from fast capture to normal thread and fast clients, always power of 2
2084 size_t mPipeFramesP2;
2085 // If a fast capture is present, the Pipe as IMemory, otherwise clear
2086 sp<IMemory> mPipeMemory;
2087
Sanna Catherine de Treville Wager2a6a9452017-07-28 11:02:01 -07002088 // TODO: add comment and adjust size as needed
Glenn Kasten6dbb5e32014-05-13 10:38:42 -07002089 static const size_t kFastCaptureLogSize = 4 * 1024;
2090 sp<NBLog::Writer> mFastCaptureNBLogWriter;
2091
2092 bool mFastTrackAvail; // true if fast track available
Eric Laurentd8365c52017-07-16 15:27:05 -07002093 // common state to all record threads
2094 std::atomic_bool mBtNrecSuspended;
Andy Hung6427e442018-08-09 12:51:02 -07002095
2096 int64_t mFramesRead = 0; // continuous running counter.
jiabinc52b1ff2019-10-31 17:20:42 -07002097
2098 DeviceDescriptorBaseVector mOutDevices;
Eric Laurentec376dc2021-04-08 20:41:22 +02002099
Eric Laurent5f0fd7b2021-05-07 16:33:26 +02002100 int32_t mMaxSharedAudioHistoryMs = 0;
Eric Laurentec376dc2021-04-08 20:41:22 +02002101 std::string mSharedAudioPackageName = {};
Eric Laurent2407ce32021-04-26 14:56:03 +02002102 int32_t mSharedAudioStartFrames = -1;
Eric Laurentec376dc2021-04-08 20:41:22 +02002103 audio_session_t mSharedAudioSessionId = AUDIO_SESSION_NONE;
Eric Laurent81784c32012-11-19 14:55:58 -08002104};
Eric Laurent6acd1d42017-01-04 14:23:29 -08002105
Andy Hung667dec42023-07-07 15:58:48 -07002106class MmapThread : public ThreadBase, public virtual IAfMmapThread
Eric Laurent6acd1d42017-01-04 14:23:29 -08002107{
2108 public:
Andy Hung2cbc2722023-07-17 17:05:00 -07002109 MmapThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
Andy Hung71ba4b32022-10-06 12:09:49 -07002110 AudioHwDevice *hwDev, const sp<StreamHalInterface>& stream, bool systemReady,
Andy Hungcf10d742020-04-28 15:38:24 -07002111 bool isOut);
Eric Laurent6acd1d42017-01-04 14:23:29 -08002112
Andy Hung667dec42023-07-07 15:58:48 -07002113 void configure(const audio_attributes_t* attr,
Eric Laurent6acd1d42017-01-04 14:23:29 -08002114 audio_stream_type_t streamType,
2115 audio_session_t sessionId,
2116 const sp<MmapStreamCallback>& callback,
Eric Laurent7aa0ccb2017-08-28 11:12:52 -07002117 audio_port_handle_t deviceId,
Andy Hung667dec42023-07-07 15:58:48 -07002118 audio_port_handle_t portId) override;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002119
Andy Hung94dfbb42023-09-06 19:41:47 -07002120 void disconnect() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002121
Andy Hung4989d312023-06-29 21:19:25 -07002122 // MmapStreamInterface for adapter.
Andy Hung667dec42023-07-07 15:58:48 -07002123 status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info* info) final;
2124 status_t getMmapPosition(struct audio_mmap_position* position) const override;
2125 status_t start(const AudioClient& client,
jiabind1f1cb62020-03-24 11:57:57 -07002126 const audio_attributes_t *attr,
Andy Hung94dfbb42023-09-06 19:41:47 -07002127 audio_port_handle_t* handle) final EXCLUDES_ThreadBase_Mutex;
2128 status_t stop(audio_port_handle_t handle) final EXCLUDES_ThreadBase_Mutex;
2129 status_t standby() final EXCLUDES_ThreadBase_Mutex;
Andy Hung667dec42023-07-07 15:58:48 -07002130 status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
2131 status_t reportData(const void* buffer, size_t frameCount) override;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002132
2133 // RefBase
Andy Hung4989d312023-06-29 21:19:25 -07002134 void onFirstRef() final;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002135
2136 // Thread virtuals
Andy Hung94dfbb42023-09-06 19:41:47 -07002137 bool threadLoop() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002138
Andy Hung4989d312023-06-29 21:19:25 -07002139 // Not in ThreadBase
2140 virtual void threadLoop_exit() final;
2141 virtual void threadLoop_standby() final;
Andy Hung94dfbb42023-09-06 19:41:47 -07002142 virtual bool shouldStandby_l() final REQUIRES(mutex()){ return false; }
Andy Hung87e82412023-08-29 14:26:09 -07002143 virtual status_t exitStandby_l() REQUIRES(mutex());
Eric Laurent6acd1d42017-01-04 14:23:29 -08002144
Andy Hung4989d312023-06-29 21:19:25 -07002145 status_t initCheck() const final { return mHalStream == nullptr ? NO_INIT : NO_ERROR; }
2146 size_t frameCount() const final { return mFrameCount; }
Andy Hung94dfbb42023-09-06 19:41:47 -07002147 bool checkForNewParameter_l(const String8& keyValuePair, status_t& status)
2148 final REQUIRES(mutex());
2149 String8 getParameters(const String8& keys) final EXCLUDES_ThreadBase_Mutex;
2150 void ioConfigChanged_l(audio_io_config_event_t event, pid_t pid = 0,
2151 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final
2152 /* holds either AF::mutex or TB::mutex */;
2153 void readHalParameters_l() REQUIRES(mutex());
2154 void cacheParameters_l() final REQUIRES(mutex()) {}
Andy Hung4989d312023-06-29 21:19:25 -07002155 status_t createAudioPatch_l(
Andy Hung94dfbb42023-09-06 19:41:47 -07002156 const struct audio_patch* patch, audio_patch_handle_t* handle) final
2157 REQUIRES(mutex());
2158 status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final
2159 REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -07002160 void toAudioPortConfig(struct audio_port_config* config) override;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002161
Andy Hung4989d312023-06-29 21:19:25 -07002162 sp<StreamHalInterface> stream() const final { return mHalStream; }
Andy Hung94dfbb42023-09-06 19:41:47 -07002163 status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
2164 size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -07002165 status_t checkEffectCompatibility_l(
Andy Hung94dfbb42023-09-06 19:41:47 -07002166 const effect_descriptor_t *desc, audio_session_t sessionId) final REQUIRES(mutex());
Eric Laurent6acd1d42017-01-04 14:23:29 -08002167
Andy Hung94dfbb42023-09-06 19:41:47 -07002168 uint32_t hasAudioSession_l(audio_session_t sessionId) const override REQUIRES(mutex()) {
Andy Hungc3d62f92019-03-14 13:38:51 -07002169 // Note: using mActiveTracks as no mTracks here.
2170 return ThreadBase::hasAudioSession_l(sessionId, mActiveTracks);
2171 }
Andy Hung4989d312023-06-29 21:19:25 -07002172 status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
2173 bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002174
Andy Hung94dfbb42023-09-06 19:41:47 -07002175 virtual void checkSilentMode_l() REQUIRES(mutex()) {} // cannot be const (RecordThread)
2176 virtual void processVolume_l() REQUIRES(mutex()) {}
Eric Laurent6acd1d42017-01-04 14:23:29 -08002177 void checkInvalidTracks_l();
2178
Andy Hung4989d312023-06-29 21:19:25 -07002179 // Not in ThreadBase
2180 virtual audio_stream_type_t streamType() const { return AUDIO_STREAM_DEFAULT; }
Andy Hung94dfbb42023-09-06 19:41:47 -07002181 virtual void invalidateTracks(audio_stream_type_t /* streamType */)
2182 EXCLUDES_ThreadBase_Mutex {}
2183 void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override
2184 EXCLUDES_ThreadBase_Mutex {}
Eric Laurent6acd1d42017-01-04 14:23:29 -08002185
Eric Laurent331679c2018-04-16 17:03:16 -07002186 // Sets the UID records silence
Andy Hung667dec42023-07-07 15:58:48 -07002187 void setRecordSilenced(
Andy Hung94dfbb42023-09-06 19:41:47 -07002188 audio_port_handle_t /* portId */, bool /* silenced */) override
2189 EXCLUDES_ThreadBase_Mutex {}
Eric Laurent331679c2018-04-16 17:03:16 -07002190
Andy Hung4989d312023-06-29 21:19:25 -07002191 bool isStreamInitialized() const override { return false; }
Jasmine Chaeaa10e42021-05-11 10:11:14 +08002192
Andy Hung94dfbb42023-09-06 19:41:47 -07002193 void setClientSilencedState_l(audio_port_handle_t portId, bool silenced) REQUIRES(mutex()) {
jiabincfc10a42022-06-15 19:26:01 +00002194 mClientSilencedStates[portId] = silenced;
2195 }
2196
Andy Hung94dfbb42023-09-06 19:41:47 -07002197 size_t eraseClientSilencedState_l(audio_port_handle_t portId) REQUIRES(mutex()) {
jiabincfc10a42022-06-15 19:26:01 +00002198 return mClientSilencedStates.erase(portId);
2199 }
2200
Andy Hung94dfbb42023-09-06 19:41:47 -07002201 bool isClientSilenced_l(audio_port_handle_t portId) const REQUIRES(mutex()) {
jiabincfc10a42022-06-15 19:26:01 +00002202 const auto it = mClientSilencedStates.find(portId);
2203 return it != mClientSilencedStates.end() ? it->second : false;
2204 }
2205
Andy Hung94dfbb42023-09-06 19:41:47 -07002206 void setClientSilencedIfExists_l(audio_port_handle_t portId, bool silenced)
2207 REQUIRES(mutex()) {
jiabincfc10a42022-06-15 19:26:01 +00002208 const auto it = mClientSilencedStates.find(portId);
2209 if (it != mClientSilencedStates.end()) {
2210 it->second = silenced;
2211 }
2212 }
2213
Eric Laurent6acd1d42017-01-04 14:23:29 -08002214 protected:
Andy Hung94dfbb42023-09-06 19:41:47 -07002215 void dumpInternals_l(int fd, const Vector<String16>& args) override REQUIRES(mutex());
2216 void dumpTracks_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
Eric Laurent6acd1d42017-01-04 14:23:29 -08002217
jiabinc52b1ff2019-10-31 17:20:42 -07002218 /**
2219 * @brief mDeviceId current device port unique identifier
2220 */
2221 audio_port_handle_t mDeviceId = AUDIO_PORT_HANDLE_NONE;
2222
Eric Laurent6acd1d42017-01-04 14:23:29 -08002223 audio_attributes_t mAttr;
2224 audio_session_t mSessionId;
2225 audio_port_handle_t mPortId;
2226
Phil Burk7f6b40d2017-02-09 13:18:38 -08002227 wp<MmapStreamCallback> mCallback;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002228 sp<StreamHalInterface> mHalStream;
2229 sp<DeviceHalInterface> mHalDevice;
2230 AudioHwDevice* const mAudioHwDev;
Andy Hung3ff4b552023-06-26 19:20:57 -07002231 ActiveTracks<IAfMmapTrack> mActiveTracks;
Eric Laurent67f97292018-04-20 18:05:41 -07002232 float mHalVolFloat;
jiabincfc10a42022-06-15 19:26:01 +00002233 std::map<audio_port_handle_t, bool> mClientSilencedStates;
Eric Laurent331679c2018-04-16 17:03:16 -07002234
2235 int32_t mNoCallbackWarningCount;
2236 static constexpr int32_t kMaxNoCallbackWarnings = 5;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002237};
2238
Andy Hung667dec42023-07-07 15:58:48 -07002239class MmapPlaybackThread : public MmapThread, public IAfMmapPlaybackThread,
2240 public virtual VolumeInterface {
Eric Laurent6acd1d42017-01-04 14:23:29 -08002241public:
Andy Hung2cbc2722023-07-17 17:05:00 -07002242 MmapPlaybackThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
jiabinc52b1ff2019-10-31 17:20:42 -07002243 AudioHwDevice *hwDev, AudioStreamOut *output, bool systemReady);
Eric Laurent6acd1d42017-01-04 14:23:29 -08002244
Andy Hung667dec42023-07-07 15:58:48 -07002245 sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() final {
2246 return sp<IAfMmapPlaybackThread>::fromExisting(this);
2247 }
2248
Andy Hung4989d312023-06-29 21:19:25 -07002249 void configure(const audio_attributes_t* attr,
Eric Laurent6acd1d42017-01-04 14:23:29 -08002250 audio_stream_type_t streamType,
2251 audio_session_t sessionId,
2252 const sp<MmapStreamCallback>& callback,
Eric Laurent7aa0ccb2017-08-28 11:12:52 -07002253 audio_port_handle_t deviceId,
Andy Hung4989d312023-06-29 21:19:25 -07002254 audio_port_handle_t portId) final;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002255
Andy Hung94dfbb42023-09-06 19:41:47 -07002256 AudioStreamOut* clearOutput() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002257
2258 // VolumeInterface
Andy Hung4989d312023-06-29 21:19:25 -07002259 void setMasterVolume(float value) final;
Andy Hung94dfbb42023-09-06 19:41:47 -07002260 // Needs implementation?
2261 void setMasterBalance(float /* value */) final EXCLUDES_ThreadBase_Mutex {}
Andy Hung4989d312023-06-29 21:19:25 -07002262 void setMasterMute(bool muted) final;
Andy Hung94dfbb42023-09-06 19:41:47 -07002263 void setStreamVolume(audio_stream_type_t stream, float value) final EXCLUDES_ThreadBase_Mutex;
2264 void setStreamMute(audio_stream_type_t stream, bool muted) final EXCLUDES_ThreadBase_Mutex;
2265 float streamVolume(audio_stream_type_t stream) const final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002266
2267 void setMasterMute_l(bool muted) { mMasterMute = muted; }
2268
Andy Hung94dfbb42023-09-06 19:41:47 -07002269 void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
2270 void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002271
Andy Hung4989d312023-06-29 21:19:25 -07002272 audio_stream_type_t streamType() const final { return mStreamType; }
Andy Hung94dfbb42023-09-06 19:41:47 -07002273 void checkSilentMode_l() final REQUIRES(mutex());
2274 void processVolume_l() final REQUIRES(mutex());
Eric Laurent6acd1d42017-01-04 14:23:29 -08002275
Andy Hung94dfbb42023-09-06 19:41:47 -07002276 MetadataUpdate updateMetadata_l() final REQUIRES(mutex());
Kevin Rocard069c2712018-03-29 19:09:14 -07002277
Andy Hung4989d312023-06-29 21:19:25 -07002278 void toAudioPortConfig(struct audio_port_config* config) final;
Mikhail Naganov32abc2b2018-05-24 12:57:11 -07002279
Andy Hung4989d312023-06-29 21:19:25 -07002280 status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const final;
jiabinb7d8c5a2020-08-26 17:24:52 -07002281
Andy Hung4989d312023-06-29 21:19:25 -07002282 bool isStreamInitialized() const final {
Jasmine Chaeaa10e42021-05-11 10:11:14 +08002283 return !(mOutput == nullptr || mOutput->stream == nullptr);
2284 }
2285
Andy Hung4989d312023-06-29 21:19:25 -07002286 status_t reportData(const void* buffer, size_t frameCount) final;
jiabinfc791ee2023-02-15 19:43:40 +00002287
Andy Hungf79092d2023-08-31 16:13:39 -07002288 void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) final
2289 REQUIRES(audio_utils::AudioFlinger_Mutex);
2290 void stopMelComputation_l() final
2291 REQUIRES(audio_utils::AudioFlinger_Mutex);
Vlad Popa6fbbfbf2023-02-22 15:05:43 +01002292
Eric Laurent6acd1d42017-01-04 14:23:29 -08002293protected:
Andy Hung94dfbb42023-09-06 19:41:47 -07002294 void dumpInternals_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
Eric Laurent19611512023-07-03 18:14:07 +02002295 float streamVolume_l() const {
2296 return mStreamTypes[mStreamType].volume;
2297 }
2298 bool streamMuted_l() const {
2299 return mStreamTypes[mStreamType].mute;
2300 }
Eric Laurent6acd1d42017-01-04 14:23:29 -08002301
Eric Laurent19611512023-07-03 18:14:07 +02002302 stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
Eric Laurent6acd1d42017-01-04 14:23:29 -08002303 audio_stream_type_t mStreamType;
2304 float mMasterVolume;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002305 bool mMasterMute;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002306 AudioStreamOut* mOutput;
Vlad Popa6fbbfbf2023-02-22 15:05:43 +01002307
2308 mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002309};
2310
Andy Hung667dec42023-07-07 15:58:48 -07002311class MmapCaptureThread : public MmapThread, public IAfMmapCaptureThread
Eric Laurent6acd1d42017-01-04 14:23:29 -08002312{
Eric Laurent6acd1d42017-01-04 14:23:29 -08002313public:
Andy Hung2cbc2722023-07-17 17:05:00 -07002314 MmapCaptureThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
jiabinc52b1ff2019-10-31 17:20:42 -07002315 AudioHwDevice *hwDev, AudioStreamIn *input, bool systemReady);
Eric Laurent6acd1d42017-01-04 14:23:29 -08002316
Andy Hung667dec42023-07-07 15:58:48 -07002317 sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() final {
2318 return sp<IAfMmapCaptureThread>::fromExisting(this);
2319 }
2320
Andy Hung94dfbb42023-09-06 19:41:47 -07002321 AudioStreamIn* clearInput() final EXCLUDES_ThreadBase_Mutex;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002322
Andy Hung87e82412023-08-29 14:26:09 -07002323 status_t exitStandby_l() REQUIRES(mutex()) final;
Eric Laurent6acd1d42017-01-04 14:23:29 -08002324
Andy Hung94dfbb42023-09-06 19:41:47 -07002325 MetadataUpdate updateMetadata_l() final REQUIRES(mutex());
2326 void processVolume_l() final REQUIRES(mutex());
2327 void setRecordSilenced(audio_port_handle_t portId, bool silenced) final
2328 EXCLUDES_ThreadBase_Mutex;
Kevin Rocard069c2712018-03-29 19:09:14 -07002329
Andy Hung4989d312023-06-29 21:19:25 -07002330 void toAudioPortConfig(struct audio_port_config* config) final;
Mikhail Naganov32abc2b2018-05-24 12:57:11 -07002331
Andy Hung4989d312023-06-29 21:19:25 -07002332 status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const final;
jiabinb7d8c5a2020-08-26 17:24:52 -07002333
Andy Hung4989d312023-06-29 21:19:25 -07002334 bool isStreamInitialized() const final {
Jasmine Chaeaa10e42021-05-11 10:11:14 +08002335 return !(mInput == nullptr || mInput->stream == nullptr);
2336 }
2337
Eric Laurent6acd1d42017-01-04 14:23:29 -08002338protected:
2339
2340 AudioStreamIn* mInput;
2341};
jiabinc658e452022-10-21 20:52:21 +00002342
2343class BitPerfectThread : public MixerThread {
2344public:
Andy Hung2cbc2722023-07-17 17:05:00 -07002345 BitPerfectThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut *output,
jiabinc658e452022-10-21 20:52:21 +00002346 audio_io_handle_t id, bool systemReady);
2347
2348protected:
Andy Hung94dfbb42023-09-06 19:41:47 -07002349 mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) final REQUIRES(mutex());
Andy Hung4989d312023-06-29 21:19:25 -07002350 void threadLoop_mix() final;
jiabinc658e452022-10-21 20:52:21 +00002351
2352private:
2353 bool mIsBitPerfect;
jiabin76d94692022-12-15 21:51:21 +00002354 float mVolumeLeft = 0.f;
2355 float mVolumeRight = 0.f;
jiabinc658e452022-10-21 20:52:21 +00002356};
Andy Hungaaa18282023-06-23 19:27:19 -07002357
Andy Hung71742ab2023-07-07 13:47:37 -07002358} // namespace android