blob: 5708c61aaf1202aaca0efda01f7ac01142bebdaa [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 Hung8d31fd22023-06-26 19:20:57 -070018#pragma once
19
Andy Hung0f725b42023-07-19 11:40:07 -070020#include "Configuration.h" // TEE_SINK
21#include "IAfTrack.h"
22
23#include <afutils/NBAIO_Tee.h>
24#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
25#include <datapath/TrackMetrics.h>
26#include <mediautils/BatteryNotifier.h>
27
28#include <atomic> // avoid transitive dependency
29#include <list> // avoid transitive dependency
30#include <optional> // avoid transitive dependency
31
Andy Hung8d31fd22023-06-26 19:20:57 -070032namespace android {
Eric Laurent81784c32012-11-19 14:55:58 -080033
34// base for record and playback
Andy Hungd29af632023-06-23 19:27:19 -070035class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase {
Eric Laurent81784c32012-11-19 14:55:58 -080036public:
Andy Hung87c693c2023-07-06 20:56:16 -070037 TrackBase(IAfThreadBase* thread,
Eric Laurent81784c32012-11-19 14:55:58 -080038 const sp<Client>& client,
Kevin Rocard1f564ac2018-03-29 13:53:10 -070039 const audio_attributes_t& mAttr,
Eric Laurent81784c32012-11-19 14:55:58 -080040 uint32_t sampleRate,
41 audio_format_t format,
42 audio_channel_mask_t channelMask,
43 size_t frameCount,
Eric Laurent83b88082014-06-20 18:31:16 -070044 void *buffer,
Andy Hung8fe68032017-06-05 16:17:51 -070045 size_t bufferSize,
Glenn Kastend848eb42016-03-08 13:42:11 -080046 audio_session_t sessionId,
Eric Laurent09f1ed22019-04-24 17:45:17 -070047 pid_t creatorPid,
Andy Hung1f12a8a2016-11-07 16:10:30 -080048 uid_t uid,
Glenn Kastend776ac62014-05-07 09:16:09 -070049 bool isOut,
Dmitry Sidorenkova41c2732023-05-15 13:47:07 -070050 const alloc_type alloc = ALLOC_CBLK,
Eric Laurent20b9ef02016-12-05 11:03:16 -080051 track_type type = TYPE_DEFAULT,
Andy Hungb68f5eb2019-12-03 16:49:17 -080052 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
53 std::string metricsId = {});
Andy Hungd29af632023-06-23 19:27:19 -070054 ~TrackBase() override;
55 status_t initCheck() const override;
56 sp<IMemory> getCblk() const final { return mCblkMemory; }
57 audio_track_cblk_t* cblk() const final { return mCblk; }
58 audio_session_t sessionId() const final { return mSessionId; }
59 uid_t uid() const final { return mUid; }
60 pid_t creatorPid() const final { return mCreatorPid; }
61 audio_port_handle_t portId() const final { return mPortId; }
62 status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
63 track_state state() const final { return mState; }
64 void setState(track_state state) final { mState = state; }
65 sp<IMemory> getBuffers() const final { return mBufferMemory; }
66 void* buffer() const final { return mBuffer; }
67 size_t bufferSize() const final { return mBufferSize; }
Eric Laurent81784c32012-11-19 14:55:58 -080068
Andy Hungd29af632023-06-23 19:27:19 -070069 bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); }
70 bool isPatchTrack() const final { return (mType == TYPE_PATCH); }
71 bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); }
72 void invalidate() override {
Andy Hungb68f5eb2019-12-03 16:49:17 -080073 if (mIsInvalid) return;
Andy Hungc2b11cb2020-04-22 09:04:01 -070074 mTrackMetrics.logInvalidate();
Andy Hungb68f5eb2019-12-03 16:49:17 -080075 mIsInvalid = true;
76 }
Andy Hungd29af632023-06-23 19:27:19 -070077 bool isInvalid() const final { return mIsInvalid; }
78 void terminate() final { mTerminated = true; }
79 bool isTerminated() const final { return mTerminated; }
80 audio_attributes_t attributes() const final { return mAttr; }
81 bool isSpatialized() const override { return false; }
82 bool isBitPerfect() const override { return false; }
Eric Laurent6acd1d42017-01-04 14:23:29 -080083
Andy Hung87c693c2023-07-06 20:56:16 -070084 wp<IAfThreadBase> thread() const final { return mThread; }
Andy Hungc3d62f92019-03-14 13:38:51 -070085
Andy Hungd29af632023-06-23 19:27:19 -070086 const sp<ServerProxy>& serverProxy() const final { return mServerProxy; }
jiabinc658e452022-10-21 20:52:21 +000087
Andy Hung8946a282018-04-19 20:04:56 -070088#ifdef TEE_SINK
Andy Hungd29af632023-06-23 19:27:19 -070089 void dumpTee(int fd, const std::string &reason) const final {
90 mTee.dump(fd, reason);
91 }
Andy Hung8946a282018-04-19 20:04:56 -070092#endif
Andy Hungd29af632023-06-23 19:27:19 -070093 /** returns the buffer contents size converted to time in milliseconds
94 * for PCM Playback or Record streaming tracks. The return value is zero for
95 * PCM static tracks and not defined for non-PCM tracks.
96 *
97 * This may be called without the thread lock.
98 */
99 double bufferLatencyMs() const override {
Andy Hung920f6572022-10-06 12:09:49 -0700100 return mServerProxy->framesReadySafe() * 1000. / sampleRate();
Andy Hungcef2daa2018-06-01 15:31:49 -0700101 }
102
Andy Hungd29af632023-06-23 19:27:19 -0700103 /** returns whether the track supports server latency computation.
104 * This is set in the constructor and constant throughout the track lifetime.
105 */
106 bool isServerLatencySupported() const final { return mServerLatencySupported; }
Andy Hungcef2daa2018-06-01 15:31:49 -0700107
Andy Hungd29af632023-06-23 19:27:19 -0700108 /** computes the server latency for PCM Playback or Record track
109 * to the device sink/source. This is the time for the next frame in the track buffer
110 * written or read from the server thread to the device source or sink.
111 *
112 * This may be called without the thread lock, but latencyMs and fromTrack
113 * may be not be synchronized. For example PatchPanel may not obtain the
114 * thread lock before calling.
115 *
116 * \param latencyMs on success is set to the latency in milliseconds of the
117 * next frame written/read by the server thread to/from the track buffer
118 * from the device source/sink.
119 * \param fromTrack on success is set to true if latency was computed directly
120 * from the track timestamp; otherwise set to false if latency was
121 * estimated from the server timestamp.
122 * fromTrack may be nullptr or omitted if not required.
123 *
124 * \returns OK or INVALID_OPERATION on failure.
125 */
126 status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final {
Andy Hungcef2daa2018-06-01 15:31:49 -0700127 if (!isServerLatencySupported()) {
128 return INVALID_OPERATION;
129 }
130
131 // if no thread lock is acquired, these atomics are not
132 // synchronized with each other, considered a benign race.
133
134 const double serverLatencyMs = mServerLatencyMs.load();
135 if (serverLatencyMs == 0.) {
136 return INVALID_OPERATION;
137 }
138 if (fromTrack != nullptr) {
139 *fromTrack = mServerLatencyFromTrack.load();
140 }
141 *latencyMs = serverLatencyMs;
142 return OK;
143 }
144
Andy Hungd29af632023-06-23 19:27:19 -0700145 /** computes the total client latency for PCM Playback or Record tracks
146 * for the next client app access to the device sink/source; i.e. the
147 * server latency plus the buffer latency.
148 *
149 * This may be called without the thread lock, but latencyMs and fromTrack
150 * may be not be synchronized. For example PatchPanel may not obtain the
151 * thread lock before calling.
152 *
153 * \param latencyMs on success is set to the latency in milliseconds of the
154 * next frame written/read by the client app to/from the track buffer
155 * from the device sink/source.
156 * \param fromTrack on success is set to true if latency was computed directly
157 * from the track timestamp; otherwise set to false if latency was
158 * estimated from the server timestamp.
159 * fromTrack may be nullptr or omitted if not required.
160 *
161 * \returns OK or INVALID_OPERATION on failure.
162 */
163 status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const {
Andy Hungcef2daa2018-06-01 15:31:49 -0700164 double serverLatencyMs;
165 status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
166 if (status == OK) {
167 *latencyMs = serverLatencyMs + bufferLatencyMs();
168 }
169 return status;
170 }
171
Andy Hungd29af632023-06-23 19:27:19 -0700172 // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
173 void getKernelFrameTime(FrameTime* ft) const final {
Andy Hung30282562018-08-08 18:27:03 -0700174 *ft = mKernelFrameTime.load();
175 }
176
Andy Hungd29af632023-06-23 19:27:19 -0700177 audio_format_t format() const final { return mFormat; }
178 int id() const final { return mId; }
Andy Hung30282562018-08-08 18:27:03 -0700179
Andy Hungd29af632023-06-23 19:27:19 -0700180 const char* getTrackStateAsString() const final {
Andy Hunge2e830f2019-12-03 12:54:46 -0800181 if (isTerminated()) {
182 return "TERMINATED";
183 }
184 switch (mState) {
185 case IDLE:
186 return "IDLE";
187 case STOPPING_1: // for Fast and Offload
188 return "STOPPING_1";
189 case STOPPING_2: // for Fast and Offload
190 return "STOPPING_2";
191 case STOPPED:
192 return "STOPPED";
193 case RESUMING:
194 return "RESUMING";
195 case ACTIVE:
196 return "ACTIVE";
197 case PAUSING:
198 return "PAUSING";
199 case PAUSED:
200 return "PAUSED";
201 case FLUSHED:
202 return "FLUSHED";
203 case STARTING_1: // for RecordTrack
204 return "STARTING_1";
205 case STARTING_2: // for RecordTrack
206 return "STARTING_2";
207 default:
208 return "UNKNOWN";
209 }
210 }
211
Andy Hungc2b11cb2020-04-22 09:04:01 -0700212 // Called by the PlaybackThread to indicate that the track is becoming active
213 // and a new interval should start with a given device list.
Andy Hungd29af632023-06-23 19:27:19 -0700214 void logBeginInterval(const std::string& devices) final {
Andy Hungc2b11cb2020-04-22 09:04:01 -0700215 mTrackMetrics.logBeginInterval(devices);
216 }
217
218 // Called by the PlaybackThread to indicate the track is no longer active.
Andy Hungd29af632023-06-23 19:27:19 -0700219 void logEndInterval() final {
Andy Hungc2b11cb2020-04-22 09:04:01 -0700220 mTrackMetrics.logEndInterval();
221 }
222
223 // Called to tally underrun frames in playback.
Andy Hungd29af632023-06-23 19:27:19 -0700224 void tallyUnderrunFrames(size_t /* frames */) override {}
Andy Hungc2b11cb2020-04-22 09:04:01 -0700225
Andy Hungd29af632023-06-23 19:27:19 -0700226 audio_channel_mask_t channelMask() const final { return mChannelMask; }
Eric Laurent94579172020-11-20 18:41:04 +0100227
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800228 /** @return true if the track has changed (metadata or volume) since
229 * the last time this function was called,
230 * true if this function was never called since the track creation,
231 * false otherwise.
232 * Thread safe.
233 */
Andy Hungd29af632023-06-23 19:27:19 -0700234 bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); }
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800235
236 /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
Andy Hungd29af632023-06-23 19:27:19 -0700237 void setMetadataHasChanged() final { mChangeNotified.clear(); }
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800238
Atneya Nair166663a2023-06-27 19:16:24 -0700239 /**
240 * Called when a track moves to active state to record its contribution to battery usage.
241 * Track state transitions should eventually be handled within the track class.
242 */
Andy Hungd29af632023-06-23 19:27:19 -0700243 void beginBatteryAttribution() final {
Atneya Nair166663a2023-06-27 19:16:24 -0700244 mBatteryStatsHolder.emplace(uid());
245 }
246
247 /**
248 * Called when a track moves out of the active state to record its contribution
249 * to battery usage.
250 */
Andy Hungd29af632023-06-23 19:27:19 -0700251 void endBatteryAttribution() final {
Atneya Nair166663a2023-06-27 19:16:24 -0700252 mBatteryStatsHolder.reset();
253 }
254
Eric Laurent81784c32012-11-19 14:55:58 -0800255protected:
Mikhail Naganovbf493082017-04-17 17:37:12 -0700256 DISALLOW_COPY_AND_ASSIGN(TrackBase);
Eric Laurent81784c32012-11-19 14:55:58 -0800257
Andy Hung689e82c2019-08-21 17:53:17 -0700258 void releaseCblk() {
259 if (mCblk != nullptr) {
Andy Hung959b5b82021-09-24 10:46:20 -0700260 mState.clear();
Andy Hung689e82c2019-08-21 17:53:17 -0700261 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
262 if (mClient == 0) {
263 free(mCblk);
264 }
265 mCblk = nullptr;
266 }
267 }
268
Eric Laurent81784c32012-11-19 14:55:58 -0800269 // AudioBufferProvider interface
Andy Hungd29af632023-06-23 19:27:19 -0700270 // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
271 void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
Eric Laurent81784c32012-11-19 14:55:58 -0800272
273 // ExtendedAudioBufferProvider interface is only needed for Track,
274 // but putting it in TrackBase avoids the complexity of virtual inheritance
Andy Hungd29af632023-06-23 19:27:19 -0700275 size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement.
Eric Laurent81784c32012-11-19 14:55:58 -0800276
Eric Laurent81784c32012-11-19 14:55:58 -0800277 uint32_t channelCount() const { return mChannelCount; }
278
Andy Hungd29af632023-06-23 19:27:19 -0700279 size_t frameSize() const final { return mFrameSize; }
Jean-Michel Trividdf87ef2019-08-20 15:42:04 -0700280
Andy Hungd29af632023-06-23 19:27:19 -0700281 uint32_t sampleRate() const override { return mSampleRate; }
Eric Laurent81784c32012-11-19 14:55:58 -0800282
Andy Hungd29af632023-06-23 19:27:19 -0700283 bool isStopped() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800284 return (mState == STOPPED || mState == FLUSHED);
285 }
286
Eric Laurentbfb1b832013-01-07 09:53:42 -0800287 // for fast tracks and offloaded tracks only
Andy Hungd29af632023-06-23 19:27:19 -0700288 bool isStopping() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800289 return mState == STOPPING_1 || mState == STOPPING_2;
290 }
Andy Hungd29af632023-06-23 19:27:19 -0700291 bool isStopping_1() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800292 return mState == STOPPING_1;
293 }
Andy Hungd29af632023-06-23 19:27:19 -0700294 bool isStopping_2() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800295 return mState == STOPPING_2;
296 }
297
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700298 // Upper case characters are final states.
299 // Lower case characters are transitory.
Andy Hunge2e830f2019-12-03 12:54:46 -0800300 const char *getTrackStateAsCodedString() const {
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700301 if (isTerminated()) {
302 return "T ";
303 }
304 switch (mState) {
305 case IDLE:
306 return "I ";
307 case STOPPING_1: // for Fast and Offload
308 return "s1";
309 case STOPPING_2: // for Fast and Offload
310 return "s2";
311 case STOPPED:
312 return "S ";
313 case RESUMING:
314 return "r ";
315 case ACTIVE:
316 return "A ";
317 case PAUSING:
318 return "p ";
319 case PAUSED:
320 return "P ";
321 case FLUSHED:
322 return "F ";
323 case STARTING_1: // for RecordTrack
324 return "r1";
325 case STARTING_2: // for RecordTrack
326 return "r2";
327 default:
328 return "? ";
329 }
330 }
331
Glenn Kastene3aa6592012-12-04 12:22:46 -0800332 bool isOut() const { return mIsOut; }
Glenn Kastend79072e2016-01-06 08:41:20 -0800333 // true for Track, false for RecordTrack,
Eric Laurent81784c32012-11-19 14:55:58 -0800334 // this could be a track type if needed later
335
Andy Hung87c693c2023-07-06 20:56:16 -0700336 const wp<IAfThreadBase> mThread;
Dmitry Sidorenkova41c2732023-05-15 13:47:07 -0700337 const alloc_type mAllocType;
Eric Laurent81784c32012-11-19 14:55:58 -0800338 /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const
339 sp<IMemory> mCblkMemory;
340 audio_track_cblk_t* mCblk;
Glenn Kastend776ac62014-05-07 09:16:09 -0700341 sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only
Eric Laurent81784c32012-11-19 14:55:58 -0800342 void* mBuffer; // start of track buffer, typically in shared memory
Glenn Kastene3aa6592012-12-04 12:22:46 -0800343 // except for OutputTrack when it is in local memory
Andy Hung8fe68032017-06-05 16:17:51 -0700344 size_t mBufferSize; // size of mBuffer in bytes
Eric Laurent81784c32012-11-19 14:55:58 -0800345 // we don't really need a lock for these
Andy Hung959b5b82021-09-24 10:46:20 -0700346 MirroredVariable<track_state> mState;
Kevin Rocard1f564ac2018-03-29 13:53:10 -0700347 const audio_attributes_t mAttr;
Eric Laurent81784c32012-11-19 14:55:58 -0800348 const uint32_t mSampleRate; // initial sample rate only; for tracks which
349 // support dynamic rates, the current value is in control block
350 const audio_format_t mFormat;
351 const audio_channel_mask_t mChannelMask;
Glenn Kastenf6ed4232013-07-16 11:16:27 -0700352 const uint32_t mChannelCount;
Eric Laurent81784c32012-11-19 14:55:58 -0800353 const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory,
354 // where for AudioTrack (but not AudioRecord),
355 // 8-bit PCM samples are stored as 16-bit
356 const size_t mFrameCount;// size of track buffer given at createTrack() or
Eric Laurentf14db3c2017-12-08 14:20:36 -0800357 // createRecord(), and then adjusted as needed
Eric Laurent81784c32012-11-19 14:55:58 -0800358
Glenn Kastend848eb42016-03-08 13:42:11 -0800359 const audio_session_t mSessionId;
Andy Hung1f12a8a2016-11-07 16:10:30 -0800360 uid_t mUid;
Andy Hung068e08e2023-05-15 19:02:55 -0700361 std::list<sp<audioflinger::SyncEvent>> mSyncEvents;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800362 const bool mIsOut;
Eric Laurent5bba2f62016-03-18 11:14:14 -0700363 sp<ServerProxy> mServerProxy;
Glenn Kastenda6ef132013-01-10 12:31:01 -0800364 const int mId;
Andy Hung8946a282018-04-19 20:04:56 -0700365#ifdef TEE_SINK
366 NBAIO_Tee mTee;
367#endif
Eric Laurentbfb1b832013-01-07 09:53:42 -0800368 bool mTerminated;
Eric Laurent83b88082014-06-20 18:31:16 -0700369 track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
Eric Laurentaaa44472014-09-12 17:41:50 -0700370 audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to
Eric Laurent20b9ef02016-12-05 11:03:16 -0800371 audio_port_handle_t mPortId; // unique ID for this track used by audio policy
Eric Laurent6acd1d42017-01-04 14:23:29 -0800372 bool mIsInvalid; // non-resettable latch, set by invalidate()
Andy Hungcef2daa2018-06-01 15:31:49 -0700373
Andy Hungb68f5eb2019-12-03 16:49:17 -0800374 // It typically takes 5 threadloop mix iterations for latency to stabilize.
Andy Hung62921122020-05-18 10:47:31 -0700375 // However, this can be 12+ iterations for BT.
376 // To be sure, we wait for latency to dip (it usually increases at the start)
377 // to assess stability and then log to MediaMetrics.
378 // Rapid start / pause calls may cause inaccurate numbers.
379 static inline constexpr int32_t LOG_START_COUNTDOWN = 12;
380 int32_t mLogStartCountdown = 0; // Mixer period countdown
381 int64_t mLogStartTimeNs = 0; // Monotonic time at start()
382 int64_t mLogStartFrames = 0; // Timestamp frames at start()
383 double mLogLatencyMs = 0.; // Track the last log latency
Andy Hungb68f5eb2019-12-03 16:49:17 -0800384
Andy Hunga81a4b42022-05-19 19:24:51 -0700385 bool mLogForceVolumeUpdate = true; // force volume update to TrackMetrics.
386
Andy Hungc2b11cb2020-04-22 09:04:01 -0700387 TrackMetrics mTrackMetrics;
Andy Hungb68f5eb2019-12-03 16:49:17 -0800388
Andy Hungcef2daa2018-06-01 15:31:49 -0700389 bool mServerLatencySupported = false;
390 std::atomic<bool> mServerLatencyFromTrack{}; // latency from track or server timestamp.
391 std::atomic<double> mServerLatencyMs{}; // last latency pushed from server thread.
Andy Hung30282562018-08-08 18:27:03 -0700392 std::atomic<FrameTime> mKernelFrameTime{}; // last frame time on kernel side.
Eric Laurent09f1ed22019-04-24 17:45:17 -0700393 const pid_t mCreatorPid; // can be different from mclient->pid() for instance
394 // when created by NuPlayer on behalf of a client
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800395
396 // If the last track change was notified to the client with readAndClearHasChanged
397 std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT;
Atneya Nair166663a2023-06-27 19:16:24 -0700398 // RAII object for battery stats book-keeping
399 std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder;
Eric Laurent83b88082014-06-20 18:31:16 -0700400};
401
Andy Hungca9be052023-06-26 19:20:57 -0700402class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase
Kevin Rocard45986c72018-12-18 18:22:59 -0800403{
404public:
Andy Hung8d31fd22023-06-26 19:20:57 -0700405 PatchTrackBase(const sp<ClientProxy>& proxy,
Andy Hung4fd69012023-07-14 16:57:01 -0700406 IAfThreadBase* thread,
Kevin Rocard45986c72018-12-18 18:22:59 -0800407 const Timeout& timeout);
Andy Hungca9be052023-06-26 19:20:57 -0700408 void setPeerTimeout(std::chrono::nanoseconds timeout) final;
409 void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final {
410 if (proxy) {
411 mPeerReferenceHold = holdReference ? proxy : nullptr;
412 mPeerProxy = proxy->asPatchProxyBufferProvider();
413 } else {
414 clearPeerProxy();
415 }
416 }
417 void clearPeerProxy() final {
Andy Hungabfab202019-03-07 19:45:54 -0800418 mPeerReferenceHold.clear();
419 mPeerProxy = nullptr;
420 }
Kevin Rocard45986c72018-12-18 18:22:59 -0800421
Andy Hungca9be052023-06-26 19:20:57 -0700422 PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; }
423
Mikhail Naganovcaf59942019-09-25 14:05:29 -0700424 bool producesBufferOnDemand() const override { return false; }
425
Kevin Rocard45986c72018-12-18 18:22:59 -0800426protected:
427 const sp<ClientProxy> mProxy;
Andy Hungabfab202019-03-07 19:45:54 -0800428 sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access.
Kevin Rocard45986c72018-12-18 18:22:59 -0800429 PatchProxyBufferProvider* mPeerProxy = nullptr;
430 struct timespec mPeerTimeout{};
Kevin Rocard45986c72018-12-18 18:22:59 -0800431};
Andy Hung8d31fd22023-06-26 19:20:57 -0700432
433} // namespace android