blob: 194a515c9faac4d0d4ad0202fac3ead1aedcf43b [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 Hung11e74242023-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 Hungfafbebc2023-06-23 19:27:19 -070023class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase {
Eric Laurent81784c32012-11-19 14:55:58 -080024public:
Andy Hung0c1e11e2023-07-06 20:56:16 -070025 TrackBase(IAfThreadBase* 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 Hungfafbebc2023-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 Hungfafbebc2023-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 Hungfafbebc2023-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 Hung0c1e11e2023-07-06 20:56:16 -070072 wp<IAfThreadBase> thread() const final { return mThread; }
Andy Hungc3d62f92019-03-14 13:38:51 -070073
Andy Hungfafbebc2023-06-23 19:27:19 -070074 const sp<ServerProxy>& serverProxy() const final { return mServerProxy; }
jiabinc658e452022-10-21 20:52:21 +000075
Andy Hung8946a282018-04-19 20:04:56 -070076#ifdef TEE_SINK
Andy Hungfafbebc2023-06-23 19:27:19 -070077 void dumpTee(int fd, const std::string &reason) const final {
78 mTee.dump(fd, reason);
79 }
Andy Hung8946a282018-04-19 20:04:56 -070080#endif
Andy Hungfafbebc2023-06-23 19:27:19 -070081 /** returns the buffer contents size converted to time in milliseconds
82 * for PCM Playback or Record streaming tracks. The return value is zero for
83 * PCM static tracks and not defined for non-PCM tracks.
84 *
85 * This may be called without the thread lock.
86 */
87 double bufferLatencyMs() const override {
Andy Hung920f6572022-10-06 12:09:49 -070088 return mServerProxy->framesReadySafe() * 1000. / sampleRate();
Andy Hungcef2daa2018-06-01 15:31:49 -070089 }
90
Andy Hungfafbebc2023-06-23 19:27:19 -070091 /** returns whether the track supports server latency computation.
92 * This is set in the constructor and constant throughout the track lifetime.
93 */
94 bool isServerLatencySupported() const final { return mServerLatencySupported; }
Andy Hungcef2daa2018-06-01 15:31:49 -070095
Andy Hungfafbebc2023-06-23 19:27:19 -070096 /** computes the server latency for PCM Playback or Record track
97 * to the device sink/source. This is the time for the next frame in the track buffer
98 * written or read from the server thread to the device source or sink.
99 *
100 * This may be called without the thread lock, but latencyMs and fromTrack
101 * may be not be synchronized. For example PatchPanel may not obtain the
102 * thread lock before calling.
103 *
104 * \param latencyMs on success is set to the latency in milliseconds of the
105 * next frame written/read by the server thread to/from the track buffer
106 * from the device source/sink.
107 * \param fromTrack on success is set to true if latency was computed directly
108 * from the track timestamp; otherwise set to false if latency was
109 * estimated from the server timestamp.
110 * fromTrack may be nullptr or omitted if not required.
111 *
112 * \returns OK or INVALID_OPERATION on failure.
113 */
114 status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final {
Andy Hungcef2daa2018-06-01 15:31:49 -0700115 if (!isServerLatencySupported()) {
116 return INVALID_OPERATION;
117 }
118
119 // if no thread lock is acquired, these atomics are not
120 // synchronized with each other, considered a benign race.
121
122 const double serverLatencyMs = mServerLatencyMs.load();
123 if (serverLatencyMs == 0.) {
124 return INVALID_OPERATION;
125 }
126 if (fromTrack != nullptr) {
127 *fromTrack = mServerLatencyFromTrack.load();
128 }
129 *latencyMs = serverLatencyMs;
130 return OK;
131 }
132
Andy Hungfafbebc2023-06-23 19:27:19 -0700133 /** computes the total client latency for PCM Playback or Record tracks
134 * for the next client app access to the device sink/source; i.e. the
135 * server latency plus the buffer latency.
136 *
137 * This may be called without the thread lock, but latencyMs and fromTrack
138 * may be not be synchronized. For example PatchPanel may not obtain the
139 * thread lock before calling.
140 *
141 * \param latencyMs on success is set to the latency in milliseconds of the
142 * next frame written/read by the client app to/from the track buffer
143 * from the device sink/source.
144 * \param fromTrack on success is set to true if latency was computed directly
145 * from the track timestamp; otherwise set to false if latency was
146 * estimated from the server timestamp.
147 * fromTrack may be nullptr or omitted if not required.
148 *
149 * \returns OK or INVALID_OPERATION on failure.
150 */
151 status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const {
Andy Hungcef2daa2018-06-01 15:31:49 -0700152 double serverLatencyMs;
153 status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
154 if (status == OK) {
155 *latencyMs = serverLatencyMs + bufferLatencyMs();
156 }
157 return status;
158 }
159
Andy Hungfafbebc2023-06-23 19:27:19 -0700160 // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
161 void getKernelFrameTime(FrameTime* ft) const final {
Andy Hung30282562018-08-08 18:27:03 -0700162 *ft = mKernelFrameTime.load();
163 }
164
Andy Hungfafbebc2023-06-23 19:27:19 -0700165 audio_format_t format() const final { return mFormat; }
166 int id() const final { return mId; }
Andy Hung30282562018-08-08 18:27:03 -0700167
Andy Hungfafbebc2023-06-23 19:27:19 -0700168 const char* getTrackStateAsString() const final {
Andy Hunge2e830f2019-12-03 12:54:46 -0800169 if (isTerminated()) {
170 return "TERMINATED";
171 }
172 switch (mState) {
173 case IDLE:
174 return "IDLE";
175 case STOPPING_1: // for Fast and Offload
176 return "STOPPING_1";
177 case STOPPING_2: // for Fast and Offload
178 return "STOPPING_2";
179 case STOPPED:
180 return "STOPPED";
181 case RESUMING:
182 return "RESUMING";
183 case ACTIVE:
184 return "ACTIVE";
185 case PAUSING:
186 return "PAUSING";
187 case PAUSED:
188 return "PAUSED";
189 case FLUSHED:
190 return "FLUSHED";
191 case STARTING_1: // for RecordTrack
192 return "STARTING_1";
193 case STARTING_2: // for RecordTrack
194 return "STARTING_2";
195 default:
196 return "UNKNOWN";
197 }
198 }
199
Andy Hungc2b11cb2020-04-22 09:04:01 -0700200 // Called by the PlaybackThread to indicate that the track is becoming active
201 // and a new interval should start with a given device list.
Andy Hungfafbebc2023-06-23 19:27:19 -0700202 void logBeginInterval(const std::string& devices) final {
Andy Hungc2b11cb2020-04-22 09:04:01 -0700203 mTrackMetrics.logBeginInterval(devices);
204 }
205
206 // Called by the PlaybackThread to indicate the track is no longer active.
Andy Hungfafbebc2023-06-23 19:27:19 -0700207 void logEndInterval() final {
Andy Hungc2b11cb2020-04-22 09:04:01 -0700208 mTrackMetrics.logEndInterval();
209 }
210
211 // Called to tally underrun frames in playback.
Andy Hungfafbebc2023-06-23 19:27:19 -0700212 void tallyUnderrunFrames(size_t /* frames */) override {}
Andy Hungc2b11cb2020-04-22 09:04:01 -0700213
Andy Hungfafbebc2023-06-23 19:27:19 -0700214 audio_channel_mask_t channelMask() const final { return mChannelMask; }
Eric Laurent94579172020-11-20 18:41:04 +0100215
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800216 /** @return true if the track has changed (metadata or volume) since
217 * the last time this function was called,
218 * true if this function was never called since the track creation,
219 * false otherwise.
220 * Thread safe.
221 */
Andy Hungfafbebc2023-06-23 19:27:19 -0700222 bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); }
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800223
224 /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
Andy Hungfafbebc2023-06-23 19:27:19 -0700225 void setMetadataHasChanged() final { mChangeNotified.clear(); }
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800226
Atneya Nair166663a2023-06-27 19:16:24 -0700227 /**
228 * Called when a track moves to active state to record its contribution to battery usage.
229 * Track state transitions should eventually be handled within the track class.
230 */
Andy Hungfafbebc2023-06-23 19:27:19 -0700231 void beginBatteryAttribution() final {
Atneya Nair166663a2023-06-27 19:16:24 -0700232 mBatteryStatsHolder.emplace(uid());
233 }
234
235 /**
236 * Called when a track moves out of the active state to record its contribution
237 * to battery usage.
238 */
Andy Hungfafbebc2023-06-23 19:27:19 -0700239 void endBatteryAttribution() final {
Atneya Nair166663a2023-06-27 19:16:24 -0700240 mBatteryStatsHolder.reset();
241 }
242
Eric Laurent81784c32012-11-19 14:55:58 -0800243protected:
Mikhail Naganovbf493082017-04-17 17:37:12 -0700244 DISALLOW_COPY_AND_ASSIGN(TrackBase);
Eric Laurent81784c32012-11-19 14:55:58 -0800245
Andy Hung689e82c2019-08-21 17:53:17 -0700246 void releaseCblk() {
247 if (mCblk != nullptr) {
Andy Hung959b5b82021-09-24 10:46:20 -0700248 mState.clear();
Andy Hung689e82c2019-08-21 17:53:17 -0700249 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
250 if (mClient == 0) {
251 free(mCblk);
252 }
253 mCblk = nullptr;
254 }
255 }
256
Eric Laurent81784c32012-11-19 14:55:58 -0800257 // AudioBufferProvider interface
Andy Hungfafbebc2023-06-23 19:27:19 -0700258 // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
259 void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
Eric Laurent81784c32012-11-19 14:55:58 -0800260
261 // ExtendedAudioBufferProvider interface is only needed for Track,
262 // but putting it in TrackBase avoids the complexity of virtual inheritance
Andy Hungfafbebc2023-06-23 19:27:19 -0700263 size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement.
Eric Laurent81784c32012-11-19 14:55:58 -0800264
Eric Laurent81784c32012-11-19 14:55:58 -0800265 uint32_t channelCount() const { return mChannelCount; }
266
Andy Hungfafbebc2023-06-23 19:27:19 -0700267 size_t frameSize() const final { return mFrameSize; }
Jean-Michel Trividdf87ef2019-08-20 15:42:04 -0700268
Andy Hungfafbebc2023-06-23 19:27:19 -0700269 uint32_t sampleRate() const override { return mSampleRate; }
Eric Laurent81784c32012-11-19 14:55:58 -0800270
Andy Hungfafbebc2023-06-23 19:27:19 -0700271 bool isStopped() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800272 return (mState == STOPPED || mState == FLUSHED);
273 }
274
Eric Laurentbfb1b832013-01-07 09:53:42 -0800275 // for fast tracks and offloaded tracks only
Andy Hungfafbebc2023-06-23 19:27:19 -0700276 bool isStopping() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800277 return mState == STOPPING_1 || mState == STOPPING_2;
278 }
Andy Hungfafbebc2023-06-23 19:27:19 -0700279 bool isStopping_1() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800280 return mState == STOPPING_1;
281 }
Andy Hungfafbebc2023-06-23 19:27:19 -0700282 bool isStopping_2() const final {
Eric Laurent81784c32012-11-19 14:55:58 -0800283 return mState == STOPPING_2;
284 }
285
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700286 // Upper case characters are final states.
287 // Lower case characters are transitory.
Andy Hunge2e830f2019-12-03 12:54:46 -0800288 const char *getTrackStateAsCodedString() const {
Andy Hung2c6c3bb2017-06-16 14:01:45 -0700289 if (isTerminated()) {
290 return "T ";
291 }
292 switch (mState) {
293 case IDLE:
294 return "I ";
295 case STOPPING_1: // for Fast and Offload
296 return "s1";
297 case STOPPING_2: // for Fast and Offload
298 return "s2";
299 case STOPPED:
300 return "S ";
301 case RESUMING:
302 return "r ";
303 case ACTIVE:
304 return "A ";
305 case PAUSING:
306 return "p ";
307 case PAUSED:
308 return "P ";
309 case FLUSHED:
310 return "F ";
311 case STARTING_1: // for RecordTrack
312 return "r1";
313 case STARTING_2: // for RecordTrack
314 return "r2";
315 default:
316 return "? ";
317 }
318 }
319
Glenn Kastene3aa6592012-12-04 12:22:46 -0800320 bool isOut() const { return mIsOut; }
Glenn Kastend79072e2016-01-06 08:41:20 -0800321 // true for Track, false for RecordTrack,
Eric Laurent81784c32012-11-19 14:55:58 -0800322 // this could be a track type if needed later
323
Andy Hung0c1e11e2023-07-06 20:56:16 -0700324 const wp<IAfThreadBase> mThread;
Dmitry Sidorenkova41c2732023-05-15 13:47:07 -0700325 const alloc_type mAllocType;
Eric Laurent81784c32012-11-19 14:55:58 -0800326 /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const
327 sp<IMemory> mCblkMemory;
328 audio_track_cblk_t* mCblk;
Glenn Kastend776ac62014-05-07 09:16:09 -0700329 sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only
Eric Laurent81784c32012-11-19 14:55:58 -0800330 void* mBuffer; // start of track buffer, typically in shared memory
Glenn Kastene3aa6592012-12-04 12:22:46 -0800331 // except for OutputTrack when it is in local memory
Andy Hung8fe68032017-06-05 16:17:51 -0700332 size_t mBufferSize; // size of mBuffer in bytes
Eric Laurent81784c32012-11-19 14:55:58 -0800333 // we don't really need a lock for these
Andy Hung959b5b82021-09-24 10:46:20 -0700334 MirroredVariable<track_state> mState;
Kevin Rocard1f564ac2018-03-29 13:53:10 -0700335 const audio_attributes_t mAttr;
Eric Laurent81784c32012-11-19 14:55:58 -0800336 const uint32_t mSampleRate; // initial sample rate only; for tracks which
337 // support dynamic rates, the current value is in control block
338 const audio_format_t mFormat;
339 const audio_channel_mask_t mChannelMask;
Glenn Kastenf6ed4232013-07-16 11:16:27 -0700340 const uint32_t mChannelCount;
Eric Laurent81784c32012-11-19 14:55:58 -0800341 const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory,
342 // where for AudioTrack (but not AudioRecord),
343 // 8-bit PCM samples are stored as 16-bit
344 const size_t mFrameCount;// size of track buffer given at createTrack() or
Eric Laurentf14db3c2017-12-08 14:20:36 -0800345 // createRecord(), and then adjusted as needed
Eric Laurent81784c32012-11-19 14:55:58 -0800346
Glenn Kastend848eb42016-03-08 13:42:11 -0800347 const audio_session_t mSessionId;
Andy Hung1f12a8a2016-11-07 16:10:30 -0800348 uid_t mUid;
Andy Hung068e08e2023-05-15 19:02:55 -0700349 std::list<sp<audioflinger::SyncEvent>> mSyncEvents;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800350 const bool mIsOut;
Eric Laurent5bba2f62016-03-18 11:14:14 -0700351 sp<ServerProxy> mServerProxy;
Glenn Kastenda6ef132013-01-10 12:31:01 -0800352 const int mId;
Andy Hung8946a282018-04-19 20:04:56 -0700353#ifdef TEE_SINK
354 NBAIO_Tee mTee;
355#endif
Eric Laurentbfb1b832013-01-07 09:53:42 -0800356 bool mTerminated;
Eric Laurent83b88082014-06-20 18:31:16 -0700357 track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
Eric Laurentaaa44472014-09-12 17:41:50 -0700358 audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to
Eric Laurent20b9ef02016-12-05 11:03:16 -0800359 audio_port_handle_t mPortId; // unique ID for this track used by audio policy
Eric Laurent6acd1d42017-01-04 14:23:29 -0800360 bool mIsInvalid; // non-resettable latch, set by invalidate()
Andy Hungcef2daa2018-06-01 15:31:49 -0700361
Andy Hungb68f5eb2019-12-03 16:49:17 -0800362 // It typically takes 5 threadloop mix iterations for latency to stabilize.
Andy Hung62921122020-05-18 10:47:31 -0700363 // However, this can be 12+ iterations for BT.
364 // To be sure, we wait for latency to dip (it usually increases at the start)
365 // to assess stability and then log to MediaMetrics.
366 // Rapid start / pause calls may cause inaccurate numbers.
367 static inline constexpr int32_t LOG_START_COUNTDOWN = 12;
368 int32_t mLogStartCountdown = 0; // Mixer period countdown
369 int64_t mLogStartTimeNs = 0; // Monotonic time at start()
370 int64_t mLogStartFrames = 0; // Timestamp frames at start()
371 double mLogLatencyMs = 0.; // Track the last log latency
Andy Hungb68f5eb2019-12-03 16:49:17 -0800372
Andy Hunga81a4b42022-05-19 19:24:51 -0700373 bool mLogForceVolumeUpdate = true; // force volume update to TrackMetrics.
374
Andy Hungc2b11cb2020-04-22 09:04:01 -0700375 TrackMetrics mTrackMetrics;
Andy Hungb68f5eb2019-12-03 16:49:17 -0800376
Andy Hungcef2daa2018-06-01 15:31:49 -0700377 bool mServerLatencySupported = false;
378 std::atomic<bool> mServerLatencyFromTrack{}; // latency from track or server timestamp.
379 std::atomic<double> mServerLatencyMs{}; // last latency pushed from server thread.
Andy Hung30282562018-08-08 18:27:03 -0700380 std::atomic<FrameTime> mKernelFrameTime{}; // last frame time on kernel side.
Eric Laurent09f1ed22019-04-24 17:45:17 -0700381 const pid_t mCreatorPid; // can be different from mclient->pid() for instance
382 // when created by NuPlayer on behalf of a client
Jasmine Chaeaa10e42021-05-11 10:11:14 +0800383
384 // If the last track change was notified to the client with readAndClearHasChanged
385 std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT;
Atneya Nair166663a2023-06-27 19:16:24 -0700386 // RAII object for battery stats book-keeping
387 std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder;
Eric Laurent83b88082014-06-20 18:31:16 -0700388};
389
Andy Hung062a7a32023-06-26 19:20:57 -0700390class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase
Kevin Rocard45986c72018-12-18 18:22:59 -0800391{
392public:
Andy Hung11e74242023-06-26 19:20:57 -0700393 PatchTrackBase(const sp<ClientProxy>& proxy,
Andy Hung7e888b32023-07-14 16:57:01 -0700394 IAfThreadBase* thread,
Kevin Rocard45986c72018-12-18 18:22:59 -0800395 const Timeout& timeout);
Andy Hung062a7a32023-06-26 19:20:57 -0700396 void setPeerTimeout(std::chrono::nanoseconds timeout) final;
397 void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final {
398 if (proxy) {
399 mPeerReferenceHold = holdReference ? proxy : nullptr;
400 mPeerProxy = proxy->asPatchProxyBufferProvider();
401 } else {
402 clearPeerProxy();
403 }
404 }
405 void clearPeerProxy() final {
Andy Hungabfab202019-03-07 19:45:54 -0800406 mPeerReferenceHold.clear();
407 mPeerProxy = nullptr;
408 }
Kevin Rocard45986c72018-12-18 18:22:59 -0800409
Andy Hung062a7a32023-06-26 19:20:57 -0700410 PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; }
411
Mikhail Naganovcaf59942019-09-25 14:05:29 -0700412 bool producesBufferOnDemand() const override { return false; }
413
Kevin Rocard45986c72018-12-18 18:22:59 -0800414protected:
415 const sp<ClientProxy> mProxy;
Andy Hungabfab202019-03-07 19:45:54 -0800416 sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access.
Kevin Rocard45986c72018-12-18 18:22:59 -0800417 PatchProxyBufferProvider* mPeerProxy = nullptr;
418 struct timespec mPeerTimeout{};
Kevin Rocard45986c72018-12-18 18:22:59 -0800419};
Andy Hung11e74242023-06-26 19:20:57 -0700420
421} // namespace android