blob: 8f3146897818bb67475679520979f8c3dc7be5b7 [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
20namespace android {
Eric Laurent81784c32012-11-19 14:55:58 -080021
22// base for record and playback
Andy Hungd29af632023-06-23 19:27:19 -070023class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase {
Eric Laurent81784c32012-11-19 14:55:58 -080024public:
Andy Hung8d31fd22023-06-26 19:20:57 -070025 TrackBase(AudioFlinger::ThreadBase* thread,
Eric Laurent81784c32012-11-19 14:55:58 -080026 const sp<Client>& client,
Kevin Rocard1f564ac2018-03-29 13:53:10 -070027 const audio_attributes_t& mAttr,
Eric Laurent81784c32012-11-19 14:55:58 -080028 uint32_t sampleRate,
29 audio_format_t format,
30 audio_channel_mask_t channelMask,
31 size_t frameCount,
Eric Laurent83b88082014-06-20 18:31:16 -070032 void *buffer,
Andy Hung8fe68032017-06-05 16:17:51 -070033 size_t bufferSize,
Glenn Kastend848eb42016-03-08 13:42:11 -080034 audio_session_t sessionId,
Eric Laurent09f1ed22019-04-24 17:45:17 -070035 pid_t creatorPid,
Andy Hung1f12a8a2016-11-07 16:10:30 -080036 uid_t uid,
Glenn Kastend776ac62014-05-07 09:16:09 -070037 bool isOut,
Dmitry Sidorenkova41c2732023-05-15 13:47:07 -070038 const alloc_type alloc = ALLOC_CBLK,
Eric Laurent20b9ef02016-12-05 11:03:16 -080039 track_type type = TYPE_DEFAULT,
Andy Hungb68f5eb2019-12-03 16:49:17 -080040 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
41 std::string metricsId = {});
Andy Hungd29af632023-06-23 19:27:19 -070042 ~TrackBase() override;
43 status_t initCheck() const override;
44 sp<IMemory> getCblk() const final { return mCblkMemory; }
45 audio_track_cblk_t* cblk() const final { return mCblk; }
46 audio_session_t sessionId() const final { return mSessionId; }
47 uid_t uid() const final { return mUid; }
48 pid_t creatorPid() const final { return mCreatorPid; }
49 audio_port_handle_t portId() const final { return mPortId; }
50 status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
51 track_state state() const final { return mState; }
52 void setState(track_state state) final { mState = state; }
53 sp<IMemory> getBuffers() const final { return mBufferMemory; }
54 void* buffer() const final { return mBuffer; }
55 size_t bufferSize() const final { return mBufferSize; }
Eric Laurent81784c32012-11-19 14:55:58 -080056
Andy Hungd29af632023-06-23 19:27:19 -070057 bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); }
58 bool isPatchTrack() const final { return (mType == TYPE_PATCH); }
59 bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); }
60 void invalidate() override {
Andy Hungb68f5eb2019-12-03 16:49:17 -080061 if (mIsInvalid) return;
Andy Hungc2b11cb2020-04-22 09:04:01 -070062 mTrackMetrics.logInvalidate();
Andy Hungb68f5eb2019-12-03 16:49:17 -080063 mIsInvalid = true;
64 }
Andy Hungd29af632023-06-23 19:27:19 -070065 bool isInvalid() const final { return mIsInvalid; }
66 void terminate() final { mTerminated = true; }
67 bool isTerminated() const final { return mTerminated; }
68 audio_attributes_t attributes() const final { return mAttr; }
69 bool isSpatialized() const override { return false; }
70 bool isBitPerfect() const override { return false; }
Eric Laurent6acd1d42017-01-04 14:23:29 -080071
Andy Hungd29af632023-06-23 19:27:19 -070072 // TODO(b/288339104) type
73 wp<Thread> thread() const final { return mThread; }
Andy Hungc3d62f92019-03-14 13:38:51 -070074
Andy Hungd29af632023-06-23 19:27:19 -070075 const sp<ServerProxy>& serverProxy() const final { return mServerProxy; }
jiabinc658e452022-10-21 20:52:21 +000076
Andy Hung8946a282018-04-19 20:04:56 -070077#ifdef TEE_SINK
Andy Hungd29af632023-06-23 19:27:19 -070078 void dumpTee(int fd, const std::string &reason) const final {
79 mTee.dump(fd, reason);
80 }
Andy Hung8946a282018-04-19 20:04:56 -070081#endif
Andy Hungd29af632023-06-23 19:27:19 -070082 /** returns the buffer contents size converted to time in milliseconds
83 * for PCM Playback or Record streaming tracks. The return value is zero for
84 * PCM static tracks and not defined for non-PCM tracks.
85 *
86 * This may be called without the thread lock.
87 */
88 double bufferLatencyMs() const override {
Andy Hung920f6572022-10-06 12:09:49 -070089 return mServerProxy->framesReadySafe() * 1000. / sampleRate();
Andy Hungcef2daa2018-06-01 15:31:49 -070090 }
91
Andy Hungd29af632023-06-23 19:27:19 -070092 /** returns whether the track supports server latency computation.
93 * This is set in the constructor and constant throughout the track lifetime.
94 */
95 bool isServerLatencySupported() const final { return mServerLatencySupported; }
Andy Hungcef2daa2018-06-01 15:31:49 -070096
Andy Hungd29af632023-06-23 19:27:19 -070097 /** computes the server latency for PCM Playback or Record track
98 * to the device sink/source. This is the time for the next frame in the track buffer
99 * written or read from the server thread to the device source or sink.
100 *
101 * This may be called without the thread lock, but latencyMs and fromTrack
102 * may be not be synchronized. For example PatchPanel may not obtain the
103 * thread lock before calling.
104 *
105 * \param latencyMs on success is set to the latency in milliseconds of the
106 * next frame written/read by the server thread to/from the track buffer
107 * from the device source/sink.
108 * \param fromTrack on success is set to true if latency was computed directly
109 * from the track timestamp; otherwise set to false if latency was
110 * estimated from the server timestamp.
111 * fromTrack may be nullptr or omitted if not required.
112 *
113 * \returns OK or INVALID_OPERATION on failure.
114 */
115 status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final {
Andy Hungcef2daa2018-06-01 15:31:49 -0700116 if (!isServerLatencySupported()) {
117 return INVALID_OPERATION;
118 }
119
120 // if no thread lock is acquired, these atomics are not
121 // synchronized with each other, considered a benign race.
122
123 const double serverLatencyMs = mServerLatencyMs.load();
124 if (serverLatencyMs == 0.) {
125 return INVALID_OPERATION;
126 }
127 if (fromTrack != nullptr) {
128 *fromTrack = mServerLatencyFromTrack.load();
129 }
130 *latencyMs = serverLatencyMs;
131 return OK;
132 }
133
Andy Hungd29af632023-06-23 19:27:19 -0700134 /** computes the total client latency for PCM Playback or Record tracks
135 * for the next client app access to the device sink/source; i.e. the
136 * server latency plus the buffer latency.
137 *
138 * This may be called without the thread lock, but latencyMs and fromTrack
139 * may be not be synchronized. For example PatchPanel may not obtain the
140 * thread lock before calling.
141 *
142 * \param latencyMs on success is set to the latency in milliseconds of the
143 * next frame written/read by the client app to/from the track buffer
144 * from the device sink/source.
145 * \param fromTrack on success is set to true if latency was computed directly
146 * from the track timestamp; otherwise set to false if latency was
147 * estimated from the server timestamp.
148 * fromTrack may be nullptr or omitted if not required.
149 *
150 * \returns OK or INVALID_OPERATION on failure.
151 */
152 status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const {
Andy Hungcef2daa2018-06-01 15:31:49 -0700153 double serverLatencyMs;
154 status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
155 if (status == OK) {
156 *latencyMs = serverLatencyMs + bufferLatencyMs();
157 }
158 return status;
159 }
160
Andy Hungd29af632023-06-23 19:27:19 -0700161 // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
162 void getKernelFrameTime(FrameTime* ft) const final {
Andy Hung30282562018-08-08 18:27:03 -0700163 *ft = mKernelFrameTime.load();
164 }
165
Andy Hungd29af632023-06-23 19:27:19 -0700166 audio_format_t format() const final { return mFormat; }
167 int id() const final { return mId; }
Andy Hung30282562018-08-08 18:27:03 -0700168
Andy Hungd29af632023-06-23 19:27:19 -0700169 const char* getTrackStateAsString() const final {
Andy Hunge2e830f2019-12-03 12:54:46 -0800170 if (isTerminated()) {
171 return "TERMINATED";
172 }
173 switch (mState) {
174 case IDLE:
175 return "IDLE";
176 case STOPPING_1: // for Fast and Offload
177 return "STOPPING_1";
178 case STOPPING_2: // for Fast and Offload
179 return "STOPPING_2";
180 case STOPPED:
181 return "STOPPED";
182 case RESUMING:
183 return "RESUMING";
184 case ACTIVE:
185 return "ACTIVE";
186 case PAUSING:
187 return "PAUSING";
188 case PAUSED:
189 return "PAUSED";
190 case FLUSHED:
191 return "FLUSHED";
192 case STARTING_1: // for RecordTrack
193 return "STARTING_1";
194 case STARTING_2: // for RecordTrack
195 return "STARTING_2";
196 default:
197 return "UNKNOWN";
198 }
199 }
200
Andy Hungc2b11cb2020-04-22 09:04:01 -0700201 // Called by the PlaybackThread to indicate that the track is becoming active
202 // and a new interval should start with a given device list.
Andy Hungd29af632023-06-23 19:27:19 -0700203 void logBeginInterval(const std::string& devices) final {
Andy Hungc2b11cb2020-04-22 09:04:01 -0700204 mTrackMetrics.logBeginInterval(devices);
205 }
206
207 // Called by the PlaybackThread to indicate the track is no longer active.
Andy Hungd29af632023-06-23 19:27:19 -0700208 void logEndInterval() final {
Andy Hungc2b11cb2020-04-22 09:04:01 -0700209 mTrackMetrics.logEndInterval();
210 }
211
212 // Called to tally underrun frames in playback.
Andy Hungd29af632023-06-23 19:27:19 -0700213 void tallyUnderrunFrames(size_t /* frames */) override {}
Andy Hungc2b11cb2020-04-22 09:04:01 -0700214
Andy Hungd29af632023-06-23 19:27:19 -0700215 audio_channel_mask_t channelMask() const final { return mChannelMask; }
Eric Laurent94579172020-11-20 18:41:04 +0100216
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800217 /** @return true if the track has changed (metadata or volume) since
218 * the last time this function was called,
219 * true if this function was never called since the track creation,
220 * false otherwise.
221 * Thread safe.
222 */
Andy Hungd29af632023-06-23 19:27:19 -0700223 bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); }
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800224
225 /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
Andy Hungd29af632023-06-23 19:27:19 -0700226 void setMetadataHasChanged() final { mChangeNotified.clear(); }
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800227
Atneya Nair166663a2023-06-27 19:16:24 -0700228 /**
229 * Called when a track moves to active state to record its contribution to battery usage.
230 * Track state transitions should eventually be handled within the track class.
231 */
Andy Hungd29af632023-06-23 19:27:19 -0700232 void beginBatteryAttribution() final {
Atneya Nair166663a2023-06-27 19:16:24 -0700233 mBatteryStatsHolder.emplace(uid());
234 }
235
236 /**
237 * Called when a track moves out of the active state to record its contribution
238 * to battery usage.
239 */
Andy Hungd29af632023-06-23 19:27:19 -0700240 void endBatteryAttribution() final {
Atneya Nair166663a2023-06-27 19:16:24 -0700241 mBatteryStatsHolder.reset();
242 }
243
Eric Laurent81784c32012-11-19 14:55:58 -0800244protected:
Mikhail Naganovbf493082017-04-17 17:37:12 -0700245 DISALLOW_COPY_AND_ASSIGN(TrackBase);
Eric Laurent81784c32012-11-19 14:55:58 -0800246
Andy Hung689e82c2019-08-21 17:53:17 -0700247 void releaseCblk() {
248 if (mCblk != nullptr) {
Andy Hung959b5b82021-09-24 10:46:20 -0700249 mState.clear();
Andy Hung689e82c2019-08-21 17:53:17 -0700250 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
251 if (mClient == 0) {
252 free(mCblk);
253 }
254 mCblk = nullptr;
255 }
256 }
257
Eric Laurent81784c32012-11-19 14:55:58 -0800258 // AudioBufferProvider interface
Andy Hungd29af632023-06-23 19:27:19 -0700259 // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
260 void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
Eric Laurent81784c32012-11-19 14:55:58 -0800261
262 // ExtendedAudioBufferProvider interface is only needed for Track,
263 // but putting it in TrackBase avoids the complexity of virtual inheritance
Andy Hungd29af632023-06-23 19:27:19 -0700264 size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement.
Eric Laurent81784c32012-11-19 14:55:58 -0800265
Eric Laurent81784c32012-11-19 14:55:58 -0800266 uint32_t channelCount() const { return mChannelCount; }
267
Andy Hungd29af632023-06-23 19:27:19 -0700268 size_t frameSize() const final { return mFrameSize; }
Jean-Michel Trividdf87ef2019-08-20 15:42:04 -0700269
Andy Hungd29af632023-06-23 19:27:19 -0700270 uint32_t sampleRate() const override { return mSampleRate; }
Eric Laurent81784c32012-11-19 14:55:58 -0800271
Andy Hungd29af632023-06-23 19:27:19 -0700272 bool isStopped() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800273 return (mState == STOPPED || mState == FLUSHED);
274 }
275
Eric Laurentbfb1b832013-01-07 09:53:42 -0800276 // for fast tracks and offloaded tracks only
Andy Hungd29af632023-06-23 19:27:19 -0700277 bool isStopping() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800278 return mState == STOPPING_1 || mState == STOPPING_2;
279 }
Andy Hungd29af632023-06-23 19:27:19 -0700280 bool isStopping_1() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800281 return mState == STOPPING_1;
282 }
Andy Hungd29af632023-06-23 19:27:19 -0700283 bool isStopping_2() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800284 return mState == STOPPING_2;
285 }
286
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700287 // Upper case characters are final states.
288 // Lower case characters are transitory.
Andy Hunge2e830f2019-12-03 12:54:46 -0800289 const char *getTrackStateAsCodedString() const {
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700290 if (isTerminated()) {
291 return "T ";
292 }
293 switch (mState) {
294 case IDLE:
295 return "I ";
296 case STOPPING_1: // for Fast and Offload
297 return "s1";
298 case STOPPING_2: // for Fast and Offload
299 return "s2";
300 case STOPPED:
301 return "S ";
302 case RESUMING:
303 return "r ";
304 case ACTIVE:
305 return "A ";
306 case PAUSING:
307 return "p ";
308 case PAUSED:
309 return "P ";
310 case FLUSHED:
311 return "F ";
312 case STARTING_1: // for RecordTrack
313 return "r1";
314 case STARTING_2: // for RecordTrack
315 return "r2";
316 default:
317 return "? ";
318 }
319 }
320
Glenn Kastene3aa6592012-12-04 12:22:46 -0800321 bool isOut() const { return mIsOut; }
Glenn Kastend79072e2016-01-06 08:41:20 -0800322 // true for Track, false for RecordTrack,
Eric Laurent81784c32012-11-19 14:55:58 -0800323 // this could be a track type if needed later
324
Andy Hung8d31fd22023-06-26 19:20:57 -0700325 const wp<AudioFlinger::ThreadBase> mThread;
Dmitry Sidorenkova41c2732023-05-15 13:47:07 -0700326 const alloc_type mAllocType;
Eric Laurent81784c32012-11-19 14:55:58 -0800327 /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const
328 sp<IMemory> mCblkMemory;
329 audio_track_cblk_t* mCblk;
Glenn Kastend776ac62014-05-07 09:16:09 -0700330 sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only
Eric Laurent81784c32012-11-19 14:55:58 -0800331 void* mBuffer; // start of track buffer, typically in shared memory
Glenn Kastene3aa6592012-12-04 12:22:46 -0800332 // except for OutputTrack when it is in local memory
Andy Hung8fe68032017-06-05 16:17:51 -0700333 size_t mBufferSize; // size of mBuffer in bytes
Eric Laurent81784c32012-11-19 14:55:58 -0800334 // we don't really need a lock for these
Andy Hung959b5b82021-09-24 10:46:20 -0700335 MirroredVariable<track_state> mState;
Kevin Rocard1f564ac2018-03-29 13:53:10 -0700336 const audio_attributes_t mAttr;
Eric Laurent81784c32012-11-19 14:55:58 -0800337 const uint32_t mSampleRate; // initial sample rate only; for tracks which
338 // support dynamic rates, the current value is in control block
339 const audio_format_t mFormat;
340 const audio_channel_mask_t mChannelMask;
Glenn Kastenf6ed4232013-07-16 11:16:27 -0700341 const uint32_t mChannelCount;
Eric Laurent81784c32012-11-19 14:55:58 -0800342 const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory,
343 // where for AudioTrack (but not AudioRecord),
344 // 8-bit PCM samples are stored as 16-bit
345 const size_t mFrameCount;// size of track buffer given at createTrack() or
Eric Laurentf14db3c2017-12-08 14:20:36 -0800346 // createRecord(), and then adjusted as needed
Eric Laurent81784c32012-11-19 14:55:58 -0800347
Glenn Kastend848eb42016-03-08 13:42:11 -0800348 const audio_session_t mSessionId;
Andy Hung1f12a8a2016-11-07 16:10:30 -0800349 uid_t mUid;
Andy Hung068e08e2023-05-15 19:02:55 -0700350 std::list<sp<audioflinger::SyncEvent>> mSyncEvents;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800351 const bool mIsOut;
Eric Laurent5bba2f62016-03-18 11:14:14 -0700352 sp<ServerProxy> mServerProxy;
Glenn Kastenda6ef132013-01-10 12:31:01 -0800353 const int mId;
Andy Hung8946a282018-04-19 20:04:56 -0700354#ifdef TEE_SINK
355 NBAIO_Tee mTee;
356#endif
Eric Laurentbfb1b832013-01-07 09:53:42 -0800357 bool mTerminated;
Eric Laurent83b88082014-06-20 18:31:16 -0700358 track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
Eric Laurentaaa44472014-09-12 17:41:50 -0700359 audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to
Eric Laurent20b9ef02016-12-05 11:03:16 -0800360 audio_port_handle_t mPortId; // unique ID for this track used by audio policy
Eric Laurent6acd1d42017-01-04 14:23:29 -0800361 bool mIsInvalid; // non-resettable latch, set by invalidate()
Andy Hungcef2daa2018-06-01 15:31:49 -0700362
Andy Hungb68f5eb2019-12-03 16:49:17 -0800363 // It typically takes 5 threadloop mix iterations for latency to stabilize.
Andy Hung62921122020-05-18 10:47:31 -0700364 // However, this can be 12+ iterations for BT.
365 // To be sure, we wait for latency to dip (it usually increases at the start)
366 // to assess stability and then log to MediaMetrics.
367 // Rapid start / pause calls may cause inaccurate numbers.
368 static inline constexpr int32_t LOG_START_COUNTDOWN = 12;
369 int32_t mLogStartCountdown = 0; // Mixer period countdown
370 int64_t mLogStartTimeNs = 0; // Monotonic time at start()
371 int64_t mLogStartFrames = 0; // Timestamp frames at start()
372 double mLogLatencyMs = 0.; // Track the last log latency
Andy Hungb68f5eb2019-12-03 16:49:17 -0800373
Andy Hunga81a4b42022-05-19 19:24:51 -0700374 bool mLogForceVolumeUpdate = true; // force volume update to TrackMetrics.
375
Andy Hungc2b11cb2020-04-22 09:04:01 -0700376 TrackMetrics mTrackMetrics;
Andy Hungb68f5eb2019-12-03 16:49:17 -0800377
Andy Hungcef2daa2018-06-01 15:31:49 -0700378 bool mServerLatencySupported = false;
379 std::atomic<bool> mServerLatencyFromTrack{}; // latency from track or server timestamp.
380 std::atomic<double> mServerLatencyMs{}; // last latency pushed from server thread.
Andy Hung30282562018-08-08 18:27:03 -0700381 std::atomic<FrameTime> mKernelFrameTime{}; // last frame time on kernel side.
Eric Laurent09f1ed22019-04-24 17:45:17 -0700382 const pid_t mCreatorPid; // can be different from mclient->pid() for instance
383 // when created by NuPlayer on behalf of a client
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800384
385 // If the last track change was notified to the client with readAndClearHasChanged
386 std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT;
Atneya Nair166663a2023-06-27 19:16:24 -0700387 // RAII object for battery stats book-keeping
388 std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder;
Eric Laurent83b88082014-06-20 18:31:16 -0700389};
390
Andy Hungca9be052023-06-26 19:20:57 -0700391class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase
Kevin Rocard45986c72018-12-18 18:22:59 -0800392{
393public:
Andy Hung8d31fd22023-06-26 19:20:57 -0700394 PatchTrackBase(const sp<ClientProxy>& proxy,
395 const AudioFlinger::ThreadBase& thread,
Kevin Rocard45986c72018-12-18 18:22:59 -0800396 const Timeout& timeout);
Andy Hungca9be052023-06-26 19:20:57 -0700397 void setPeerTimeout(std::chrono::nanoseconds timeout) final;
398 void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final {
399 if (proxy) {
400 mPeerReferenceHold = holdReference ? proxy : nullptr;
401 mPeerProxy = proxy->asPatchProxyBufferProvider();
402 } else {
403 clearPeerProxy();
404 }
405 }
406 void clearPeerProxy() final {
Andy Hungabfab202019-03-07 19:45:54 -0800407 mPeerReferenceHold.clear();
408 mPeerProxy = nullptr;
409 }
Kevin Rocard45986c72018-12-18 18:22:59 -0800410
Andy Hungca9be052023-06-26 19:20:57 -0700411 PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; }
412
Mikhail Naganovcaf59942019-09-25 14:05:29 -0700413 bool producesBufferOnDemand() const override { return false; }
414
Kevin Rocard45986c72018-12-18 18:22:59 -0800415protected:
416 const sp<ClientProxy> mProxy;
Andy Hungabfab202019-03-07 19:45:54 -0800417 sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access.
Kevin Rocard45986c72018-12-18 18:22:59 -0800418 PatchProxyBufferProvider* mPeerProxy = nullptr;
419 struct timespec mPeerTimeout{};
Kevin Rocard45986c72018-12-18 18:22:59 -0800420};
Andy Hung8d31fd22023-06-26 19:20:57 -0700421
422} // namespace android