xref: /aosp_15_r20/frameworks/av/services/audioflinger/TrackBase.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2012, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker **     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker #pragma once
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include "Configuration.h"  // TEE_SINK
21*ec779b8eSAndroid Build Coastguard Worker #include "IAfTrack.h"
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker #include <afutils/NBAIO_Tee.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <android-base/macros.h>  // DISALLOW_COPY_AND_ASSIGN
25*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/Trace.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <datapath/TrackMetrics.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/BatteryNotifier.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <psh_utils/AudioPowerManager.h>
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker #include <atomic>    // avoid transitive dependency
31*ec779b8eSAndroid Build Coastguard Worker #include <list>      // avoid transitive dependency
32*ec779b8eSAndroid Build Coastguard Worker #include <optional>  // avoid transitive dependency
33*ec779b8eSAndroid Build Coastguard Worker 
34*ec779b8eSAndroid Build Coastguard Worker namespace android {
35*ec779b8eSAndroid Build Coastguard Worker 
36*ec779b8eSAndroid Build Coastguard Worker // base for record and playback
37*ec779b8eSAndroid Build Coastguard Worker class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase {
38*ec779b8eSAndroid Build Coastguard Worker public:
39*ec779b8eSAndroid Build Coastguard Worker     TrackBase(IAfThreadBase* thread,
40*ec779b8eSAndroid Build Coastguard Worker                                 const sp<Client>& client,
41*ec779b8eSAndroid Build Coastguard Worker                                 const audio_attributes_t& mAttr,
42*ec779b8eSAndroid Build Coastguard Worker                                 uint32_t sampleRate,
43*ec779b8eSAndroid Build Coastguard Worker                                 audio_format_t format,
44*ec779b8eSAndroid Build Coastguard Worker                                 audio_channel_mask_t channelMask,
45*ec779b8eSAndroid Build Coastguard Worker                                 size_t frameCount,
46*ec779b8eSAndroid Build Coastguard Worker                                 void *buffer,
47*ec779b8eSAndroid Build Coastguard Worker                                 size_t bufferSize,
48*ec779b8eSAndroid Build Coastguard Worker                                 audio_session_t sessionId,
49*ec779b8eSAndroid Build Coastguard Worker                                 pid_t creatorPid,
50*ec779b8eSAndroid Build Coastguard Worker                                 uid_t uid,
51*ec779b8eSAndroid Build Coastguard Worker                                 bool isOut,
52*ec779b8eSAndroid Build Coastguard Worker                                 const alloc_type alloc = ALLOC_CBLK,
53*ec779b8eSAndroid Build Coastguard Worker                                 track_type type = TYPE_DEFAULT,
54*ec779b8eSAndroid Build Coastguard Worker                                 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
55*ec779b8eSAndroid Build Coastguard Worker                                 std::string metricsId = {});
56*ec779b8eSAndroid Build Coastguard Worker     ~TrackBase() override;
57*ec779b8eSAndroid Build Coastguard Worker     status_t initCheck() const override;
getCblk()58*ec779b8eSAndroid Build Coastguard Worker     sp<IMemory> getCblk() const final { return mCblkMemory; }
cblk()59*ec779b8eSAndroid Build Coastguard Worker     audio_track_cblk_t* cblk() const final { return mCblk; }
sessionId()60*ec779b8eSAndroid Build Coastguard Worker     audio_session_t sessionId() const final { return mSessionId; }
uid()61*ec779b8eSAndroid Build Coastguard Worker     uid_t uid() const final { return mUid; }
creatorPid()62*ec779b8eSAndroid Build Coastguard Worker     pid_t creatorPid() const final { return mCreatorPid; }
portId()63*ec779b8eSAndroid Build Coastguard Worker     audio_port_handle_t portId() const final { return mPortId; }
64*ec779b8eSAndroid Build Coastguard Worker     status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
state()65*ec779b8eSAndroid Build Coastguard Worker     track_state state() const final { return mState; }
setState(track_state state)66*ec779b8eSAndroid Build Coastguard Worker     void setState(track_state state) final { mState = state; }
getBuffers()67*ec779b8eSAndroid Build Coastguard Worker     sp<IMemory> getBuffers() const final { return mBufferMemory; }
buffer()68*ec779b8eSAndroid Build Coastguard Worker     void* buffer() const final { return mBuffer; }
bufferSize()69*ec779b8eSAndroid Build Coastguard Worker     size_t bufferSize() const final { return mBufferSize; }
70*ec779b8eSAndroid Build Coastguard Worker 
isOutputTrack()71*ec779b8eSAndroid Build Coastguard Worker     bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); }
isPatchTrack()72*ec779b8eSAndroid Build Coastguard Worker     bool isPatchTrack() const final { return (mType == TYPE_PATCH); }
isExternalTrack()73*ec779b8eSAndroid Build Coastguard Worker     bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); }
invalidate()74*ec779b8eSAndroid Build Coastguard Worker     void invalidate() override {
75*ec779b8eSAndroid Build Coastguard Worker                             if (mIsInvalid) return;
76*ec779b8eSAndroid Build Coastguard Worker                             mTrackMetrics.logInvalidate();
77*ec779b8eSAndroid Build Coastguard Worker                             mIsInvalid = true;
78*ec779b8eSAndroid Build Coastguard Worker                         }
isInvalid()79*ec779b8eSAndroid Build Coastguard Worker     bool isInvalid() const final { return mIsInvalid; }
terminate()80*ec779b8eSAndroid Build Coastguard Worker     void terminate() final { mTerminated = true; }
isTerminated()81*ec779b8eSAndroid Build Coastguard Worker     bool isTerminated() const final { return mTerminated; }
attributes()82*ec779b8eSAndroid Build Coastguard Worker     audio_attributes_t attributes() const final { return mAttr; }
isSpatialized()83*ec779b8eSAndroid Build Coastguard Worker     bool isSpatialized() const override { return false; }
isBitPerfect()84*ec779b8eSAndroid Build Coastguard Worker     bool isBitPerfect() const override { return false; }
85*ec779b8eSAndroid Build Coastguard Worker 
thread()86*ec779b8eSAndroid Build Coastguard Worker     wp<IAfThreadBase> thread() const final { return mThread; }
87*ec779b8eSAndroid Build Coastguard Worker 
serverProxy()88*ec779b8eSAndroid Build Coastguard Worker     const sp<ServerProxy>& serverProxy() const final { return mServerProxy; }
89*ec779b8eSAndroid Build Coastguard Worker 
90*ec779b8eSAndroid Build Coastguard Worker #ifdef TEE_SINK
dumpTee(int fd,const std::string & reason)91*ec779b8eSAndroid Build Coastguard Worker     void dumpTee(int fd, const std::string &reason) const final {
92*ec779b8eSAndroid Build Coastguard Worker         mTee.dump(fd, reason);
93*ec779b8eSAndroid Build Coastguard Worker     }
94*ec779b8eSAndroid Build Coastguard Worker #endif
95*ec779b8eSAndroid Build Coastguard Worker     /** returns the buffer contents size converted to time in milliseconds
96*ec779b8eSAndroid Build Coastguard Worker      * for PCM Playback or Record streaming tracks. The return value is zero for
97*ec779b8eSAndroid Build Coastguard Worker      * PCM static tracks and not defined for non-PCM tracks.
98*ec779b8eSAndroid Build Coastguard Worker      *
99*ec779b8eSAndroid Build Coastguard Worker      * This may be called without the thread lock.
100*ec779b8eSAndroid Build Coastguard Worker      */
bufferLatencyMs()101*ec779b8eSAndroid Build Coastguard Worker     double bufferLatencyMs() const override {
102*ec779b8eSAndroid Build Coastguard Worker                             return mServerProxy->framesReadySafe() * 1000. / sampleRate();
103*ec779b8eSAndroid Build Coastguard Worker                         }
104*ec779b8eSAndroid Build Coastguard Worker 
105*ec779b8eSAndroid Build Coastguard Worker     /** returns whether the track supports server latency computation.
106*ec779b8eSAndroid Build Coastguard Worker      * This is set in the constructor and constant throughout the track lifetime.
107*ec779b8eSAndroid Build Coastguard Worker      */
isServerLatencySupported()108*ec779b8eSAndroid Build Coastguard Worker     bool isServerLatencySupported() const final { return mServerLatencySupported; }
109*ec779b8eSAndroid Build Coastguard Worker 
110*ec779b8eSAndroid Build Coastguard Worker     /** computes the server latency for PCM Playback or Record track
111*ec779b8eSAndroid Build Coastguard Worker      * to the device sink/source.  This is the time for the next frame in the track buffer
112*ec779b8eSAndroid Build Coastguard Worker      * written or read from the server thread to the device source or sink.
113*ec779b8eSAndroid Build Coastguard Worker      *
114*ec779b8eSAndroid Build Coastguard Worker      * This may be called without the thread lock, but latencyMs and fromTrack
115*ec779b8eSAndroid Build Coastguard Worker      * may be not be synchronized. For example PatchPanel may not obtain the
116*ec779b8eSAndroid Build Coastguard Worker      * thread lock before calling.
117*ec779b8eSAndroid Build Coastguard Worker      *
118*ec779b8eSAndroid Build Coastguard Worker      * \param latencyMs on success is set to the latency in milliseconds of the
119*ec779b8eSAndroid Build Coastguard Worker      *        next frame written/read by the server thread to/from the track buffer
120*ec779b8eSAndroid Build Coastguard Worker      *        from the device source/sink.
121*ec779b8eSAndroid Build Coastguard Worker      * \param fromTrack on success is set to true if latency was computed directly
122*ec779b8eSAndroid Build Coastguard Worker      *        from the track timestamp; otherwise set to false if latency was
123*ec779b8eSAndroid Build Coastguard Worker      *        estimated from the server timestamp.
124*ec779b8eSAndroid Build Coastguard Worker      *        fromTrack may be nullptr or omitted if not required.
125*ec779b8eSAndroid Build Coastguard Worker      *
126*ec779b8eSAndroid Build Coastguard Worker      * \returns OK or INVALID_OPERATION on failure.
127*ec779b8eSAndroid Build Coastguard Worker      */
128*ec779b8eSAndroid Build Coastguard Worker     status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final {
129*ec779b8eSAndroid Build Coastguard Worker                             if (!isServerLatencySupported()) {
130*ec779b8eSAndroid Build Coastguard Worker                                 return INVALID_OPERATION;
131*ec779b8eSAndroid Build Coastguard Worker                             }
132*ec779b8eSAndroid Build Coastguard Worker 
133*ec779b8eSAndroid Build Coastguard Worker                             // if no thread lock is acquired, these atomics are not
134*ec779b8eSAndroid Build Coastguard Worker                             // synchronized with each other, considered a benign race.
135*ec779b8eSAndroid Build Coastguard Worker 
136*ec779b8eSAndroid Build Coastguard Worker                             const double serverLatencyMs = mServerLatencyMs.load();
137*ec779b8eSAndroid Build Coastguard Worker                             if (serverLatencyMs == 0.) {
138*ec779b8eSAndroid Build Coastguard Worker                                 return INVALID_OPERATION;
139*ec779b8eSAndroid Build Coastguard Worker                             }
140*ec779b8eSAndroid Build Coastguard Worker                             if (fromTrack != nullptr) {
141*ec779b8eSAndroid Build Coastguard Worker                                 *fromTrack = mServerLatencyFromTrack.load();
142*ec779b8eSAndroid Build Coastguard Worker                             }
143*ec779b8eSAndroid Build Coastguard Worker                             *latencyMs = serverLatencyMs;
144*ec779b8eSAndroid Build Coastguard Worker                             return OK;
145*ec779b8eSAndroid Build Coastguard Worker                         }
146*ec779b8eSAndroid Build Coastguard Worker 
147*ec779b8eSAndroid Build Coastguard Worker     /** computes the total client latency for PCM Playback or Record tracks
148*ec779b8eSAndroid Build Coastguard Worker      * for the next client app access to the device sink/source; i.e. the
149*ec779b8eSAndroid Build Coastguard Worker      * server latency plus the buffer latency.
150*ec779b8eSAndroid Build Coastguard Worker      *
151*ec779b8eSAndroid Build Coastguard Worker      * This may be called without the thread lock, but latencyMs and fromTrack
152*ec779b8eSAndroid Build Coastguard Worker      * may be not be synchronized. For example PatchPanel may not obtain the
153*ec779b8eSAndroid Build Coastguard Worker      * thread lock before calling.
154*ec779b8eSAndroid Build Coastguard Worker      *
155*ec779b8eSAndroid Build Coastguard Worker      * \param latencyMs on success is set to the latency in milliseconds of the
156*ec779b8eSAndroid Build Coastguard Worker      *        next frame written/read by the client app to/from the track buffer
157*ec779b8eSAndroid Build Coastguard Worker      *        from the device sink/source.
158*ec779b8eSAndroid Build Coastguard Worker      * \param fromTrack on success is set to true if latency was computed directly
159*ec779b8eSAndroid Build Coastguard Worker      *        from the track timestamp; otherwise set to false if latency was
160*ec779b8eSAndroid Build Coastguard Worker      *        estimated from the server timestamp.
161*ec779b8eSAndroid Build Coastguard Worker      *        fromTrack may be nullptr or omitted if not required.
162*ec779b8eSAndroid Build Coastguard Worker      *
163*ec779b8eSAndroid Build Coastguard Worker      * \returns OK or INVALID_OPERATION on failure.
164*ec779b8eSAndroid Build Coastguard Worker      */
165*ec779b8eSAndroid Build Coastguard Worker     status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const {
166*ec779b8eSAndroid Build Coastguard Worker                             double serverLatencyMs;
167*ec779b8eSAndroid Build Coastguard Worker                             status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
168*ec779b8eSAndroid Build Coastguard Worker                             if (status == OK) {
169*ec779b8eSAndroid Build Coastguard Worker                                 *latencyMs = serverLatencyMs + bufferLatencyMs();
170*ec779b8eSAndroid Build Coastguard Worker                             }
171*ec779b8eSAndroid Build Coastguard Worker                             return status;
172*ec779b8eSAndroid Build Coastguard Worker                         }
173*ec779b8eSAndroid Build Coastguard Worker 
174*ec779b8eSAndroid Build Coastguard Worker     // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
getKernelFrameTime(FrameTime * ft)175*ec779b8eSAndroid Build Coastguard Worker     void getKernelFrameTime(FrameTime* ft) const final {
176*ec779b8eSAndroid Build Coastguard Worker                            *ft = mKernelFrameTime.load();
177*ec779b8eSAndroid Build Coastguard Worker                         }
178*ec779b8eSAndroid Build Coastguard Worker 
format()179*ec779b8eSAndroid Build Coastguard Worker     audio_format_t format() const final { return mFormat; }
id()180*ec779b8eSAndroid Build Coastguard Worker     int id() const final { return mId; }
181*ec779b8eSAndroid Build Coastguard Worker 
getTrackStateAsString()182*ec779b8eSAndroid Build Coastguard Worker     const char* getTrackStateAsString() const final {
183*ec779b8eSAndroid Build Coastguard Worker         if (isTerminated()) {
184*ec779b8eSAndroid Build Coastguard Worker             return "TERMINATED";
185*ec779b8eSAndroid Build Coastguard Worker         }
186*ec779b8eSAndroid Build Coastguard Worker         switch (mState) {
187*ec779b8eSAndroid Build Coastguard Worker         case IDLE:
188*ec779b8eSAndroid Build Coastguard Worker             return "IDLE";
189*ec779b8eSAndroid Build Coastguard Worker         case STOPPING_1: // for Fast and Offload
190*ec779b8eSAndroid Build Coastguard Worker             return "STOPPING_1";
191*ec779b8eSAndroid Build Coastguard Worker         case STOPPING_2: // for Fast and Offload
192*ec779b8eSAndroid Build Coastguard Worker             return "STOPPING_2";
193*ec779b8eSAndroid Build Coastguard Worker         case STOPPED:
194*ec779b8eSAndroid Build Coastguard Worker             return "STOPPED";
195*ec779b8eSAndroid Build Coastguard Worker         case RESUMING:
196*ec779b8eSAndroid Build Coastguard Worker             return "RESUMING";
197*ec779b8eSAndroid Build Coastguard Worker         case ACTIVE:
198*ec779b8eSAndroid Build Coastguard Worker             return "ACTIVE";
199*ec779b8eSAndroid Build Coastguard Worker         case PAUSING:
200*ec779b8eSAndroid Build Coastguard Worker             return "PAUSING";
201*ec779b8eSAndroid Build Coastguard Worker         case PAUSED:
202*ec779b8eSAndroid Build Coastguard Worker             return "PAUSED";
203*ec779b8eSAndroid Build Coastguard Worker         case FLUSHED:
204*ec779b8eSAndroid Build Coastguard Worker             return "FLUSHED";
205*ec779b8eSAndroid Build Coastguard Worker         case STARTING_1: // for RecordTrack
206*ec779b8eSAndroid Build Coastguard Worker             return "STARTING_1";
207*ec779b8eSAndroid Build Coastguard Worker         case STARTING_2: // for RecordTrack
208*ec779b8eSAndroid Build Coastguard Worker             return "STARTING_2";
209*ec779b8eSAndroid Build Coastguard Worker         default:
210*ec779b8eSAndroid Build Coastguard Worker             return "UNKNOWN";
211*ec779b8eSAndroid Build Coastguard Worker         }
212*ec779b8eSAndroid Build Coastguard Worker     }
213*ec779b8eSAndroid Build Coastguard Worker 
getTraceSuffix()214*ec779b8eSAndroid Build Coastguard Worker     const std::string& getTraceSuffix() const final { return mTraceSuffix; }
215*ec779b8eSAndroid Build Coastguard Worker     // Called by the PlaybackThread to indicate that the track is becoming active
216*ec779b8eSAndroid Build Coastguard Worker     // and a new interval should start with a given device list.
217*ec779b8eSAndroid Build Coastguard Worker     void logBeginInterval(const std::string& devices) final;
218*ec779b8eSAndroid Build Coastguard Worker 
219*ec779b8eSAndroid Build Coastguard Worker     // Called by the PlaybackThread to indicate the track is no longer active.
220*ec779b8eSAndroid Build Coastguard Worker     void logEndInterval() final;
221*ec779b8eSAndroid Build Coastguard Worker 
222*ec779b8eSAndroid Build Coastguard Worker     // Called by the PlaybackThread when ATRACE is enabled.
223*ec779b8eSAndroid Build Coastguard Worker     void logRefreshInterval(const std::string& devices) final;
224*ec779b8eSAndroid Build Coastguard Worker 
225*ec779b8eSAndroid Build Coastguard Worker     // Called to tally underrun frames in playback.
tallyUnderrunFrames(size_t)226*ec779b8eSAndroid Build Coastguard Worker     void tallyUnderrunFrames(size_t /* frames */) override {}
227*ec779b8eSAndroid Build Coastguard Worker 
channelMask()228*ec779b8eSAndroid Build Coastguard Worker     audio_channel_mask_t channelMask() const final { return mChannelMask; }
229*ec779b8eSAndroid Build Coastguard Worker 
230*ec779b8eSAndroid Build Coastguard Worker     /** @return true if the track has changed (metadata or volume) since
231*ec779b8eSAndroid Build Coastguard Worker      *          the last time this function was called,
232*ec779b8eSAndroid Build Coastguard Worker      *          true if this function was never called since the track creation,
233*ec779b8eSAndroid Build Coastguard Worker      *          false otherwise.
234*ec779b8eSAndroid Build Coastguard Worker      *  Thread safe.
235*ec779b8eSAndroid Build Coastguard Worker      */
readAndClearHasChanged()236*ec779b8eSAndroid Build Coastguard Worker     bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); }
237*ec779b8eSAndroid Build Coastguard Worker 
238*ec779b8eSAndroid Build Coastguard Worker     /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
setMetadataHasChanged()239*ec779b8eSAndroid Build Coastguard Worker     void setMetadataHasChanged() final { mChangeNotified.clear(); }
240*ec779b8eSAndroid Build Coastguard Worker 
241*ec779b8eSAndroid Build Coastguard Worker     /**
242*ec779b8eSAndroid Build Coastguard Worker      * Called when a track moves to active state to record its contribution to battery usage.
243*ec779b8eSAndroid Build Coastguard Worker      * Track state transitions should eventually be handled within the track class.
244*ec779b8eSAndroid Build Coastguard Worker      */
245*ec779b8eSAndroid Build Coastguard Worker     void beginBatteryAttribution() final;
246*ec779b8eSAndroid Build Coastguard Worker 
247*ec779b8eSAndroid Build Coastguard Worker     /**
248*ec779b8eSAndroid Build Coastguard Worker      * Called when a track moves out of the active state to record its contribution
249*ec779b8eSAndroid Build Coastguard Worker      * to battery usage.
250*ec779b8eSAndroid Build Coastguard Worker      */
251*ec779b8eSAndroid Build Coastguard Worker     void endBatteryAttribution() final;
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker protected:
254*ec779b8eSAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(TrackBase);
255*ec779b8eSAndroid Build Coastguard Worker 
releaseCblk()256*ec779b8eSAndroid Build Coastguard Worker     void releaseCblk() {
257*ec779b8eSAndroid Build Coastguard Worker         if (mCblk != nullptr) {
258*ec779b8eSAndroid Build Coastguard Worker             mState.clear();
259*ec779b8eSAndroid Build Coastguard Worker             mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
260*ec779b8eSAndroid Build Coastguard Worker             if (mClient == 0) {
261*ec779b8eSAndroid Build Coastguard Worker                 free(mCblk);
262*ec779b8eSAndroid Build Coastguard Worker             }
263*ec779b8eSAndroid Build Coastguard Worker             mCblk = nullptr;
264*ec779b8eSAndroid Build Coastguard Worker         }
265*ec779b8eSAndroid Build Coastguard Worker     }
266*ec779b8eSAndroid Build Coastguard Worker 
267*ec779b8eSAndroid Build Coastguard Worker     // AudioBufferProvider interface
268*ec779b8eSAndroid Build Coastguard Worker     // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
269*ec779b8eSAndroid Build Coastguard Worker     void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
270*ec779b8eSAndroid Build Coastguard Worker 
271*ec779b8eSAndroid Build Coastguard Worker     // ExtendedAudioBufferProvider interface is only needed for Track,
272*ec779b8eSAndroid Build Coastguard Worker     // but putting it in TrackBase avoids the complexity of virtual inheritance
framesReady()273*ec779b8eSAndroid Build Coastguard Worker     size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement.
274*ec779b8eSAndroid Build Coastguard Worker 
channelCount()275*ec779b8eSAndroid Build Coastguard Worker     uint32_t channelCount() const { return mChannelCount; }
276*ec779b8eSAndroid Build Coastguard Worker 
frameSize()277*ec779b8eSAndroid Build Coastguard Worker     size_t frameSize() const final { return mFrameSize; }
278*ec779b8eSAndroid Build Coastguard Worker 
sampleRate()279*ec779b8eSAndroid Build Coastguard Worker     uint32_t sampleRate() const override { return mSampleRate; }
280*ec779b8eSAndroid Build Coastguard Worker 
isStopped()281*ec779b8eSAndroid Build Coastguard Worker     bool isStopped() const final {
282*ec779b8eSAndroid Build Coastguard Worker         return (mState == STOPPED || mState == FLUSHED);
283*ec779b8eSAndroid Build Coastguard Worker     }
284*ec779b8eSAndroid Build Coastguard Worker 
285*ec779b8eSAndroid Build Coastguard Worker     // for fast tracks and offloaded tracks only
isStopping()286*ec779b8eSAndroid Build Coastguard Worker     bool isStopping() const final {
287*ec779b8eSAndroid Build Coastguard Worker         return mState == STOPPING_1 || mState == STOPPING_2;
288*ec779b8eSAndroid Build Coastguard Worker     }
isStopping_1()289*ec779b8eSAndroid Build Coastguard Worker     bool isStopping_1() const final {
290*ec779b8eSAndroid Build Coastguard Worker         return mState == STOPPING_1;
291*ec779b8eSAndroid Build Coastguard Worker     }
isStopping_2()292*ec779b8eSAndroid Build Coastguard Worker     bool isStopping_2() const final {
293*ec779b8eSAndroid Build Coastguard Worker         return mState == STOPPING_2;
294*ec779b8eSAndroid Build Coastguard Worker     }
295*ec779b8eSAndroid Build Coastguard Worker 
296*ec779b8eSAndroid Build Coastguard Worker     // Upper case characters are final states.
297*ec779b8eSAndroid Build Coastguard Worker     // Lower case characters are transitory.
getTrackStateAsCodedString()298*ec779b8eSAndroid Build Coastguard Worker     const char *getTrackStateAsCodedString() const {
299*ec779b8eSAndroid Build Coastguard Worker         if (isTerminated()) {
300*ec779b8eSAndroid Build Coastguard Worker             return "T ";
301*ec779b8eSAndroid Build Coastguard Worker         }
302*ec779b8eSAndroid Build Coastguard Worker         switch (mState) {
303*ec779b8eSAndroid Build Coastguard Worker         case IDLE:
304*ec779b8eSAndroid Build Coastguard Worker             return "I ";
305*ec779b8eSAndroid Build Coastguard Worker         case STOPPING_1: // for Fast and Offload
306*ec779b8eSAndroid Build Coastguard Worker             return "s1";
307*ec779b8eSAndroid Build Coastguard Worker         case STOPPING_2: // for Fast and Offload
308*ec779b8eSAndroid Build Coastguard Worker             return "s2";
309*ec779b8eSAndroid Build Coastguard Worker         case STOPPED:
310*ec779b8eSAndroid Build Coastguard Worker             return "S ";
311*ec779b8eSAndroid Build Coastguard Worker         case RESUMING:
312*ec779b8eSAndroid Build Coastguard Worker             return "r ";
313*ec779b8eSAndroid Build Coastguard Worker         case ACTIVE:
314*ec779b8eSAndroid Build Coastguard Worker             return "A ";
315*ec779b8eSAndroid Build Coastguard Worker         case PAUSING:
316*ec779b8eSAndroid Build Coastguard Worker             return "p ";
317*ec779b8eSAndroid Build Coastguard Worker         case PAUSED:
318*ec779b8eSAndroid Build Coastguard Worker             return "P ";
319*ec779b8eSAndroid Build Coastguard Worker         case FLUSHED:
320*ec779b8eSAndroid Build Coastguard Worker             return "F ";
321*ec779b8eSAndroid Build Coastguard Worker         case STARTING_1: // for RecordTrack
322*ec779b8eSAndroid Build Coastguard Worker             return "r1";
323*ec779b8eSAndroid Build Coastguard Worker         case STARTING_2: // for RecordTrack
324*ec779b8eSAndroid Build Coastguard Worker             return "r2";
325*ec779b8eSAndroid Build Coastguard Worker         default:
326*ec779b8eSAndroid Build Coastguard Worker             return "? ";
327*ec779b8eSAndroid Build Coastguard Worker         }
328*ec779b8eSAndroid Build Coastguard Worker     }
329*ec779b8eSAndroid Build Coastguard Worker 
isOut()330*ec779b8eSAndroid Build Coastguard Worker     bool isOut() const { return mIsOut; }
331*ec779b8eSAndroid Build Coastguard Worker                                     // true for Track, false for RecordTrack,
332*ec779b8eSAndroid Build Coastguard Worker                                     // this could be a track type if needed later
333*ec779b8eSAndroid Build Coastguard Worker 
334*ec779b8eSAndroid Build Coastguard Worker     void deferRestartIfDisabled();
restartIfDisabled()335*ec779b8eSAndroid Build Coastguard Worker     virtual void restartIfDisabled() {}
336*ec779b8eSAndroid Build Coastguard Worker 
337*ec779b8eSAndroid Build Coastguard Worker     virtual std::string trackFlagsAsString() const = 0;
338*ec779b8eSAndroid Build Coastguard Worker 
339*ec779b8eSAndroid Build Coastguard Worker     audio_utils::trace::Object createDeviceIntervalTrace(const std::string& devices);
340*ec779b8eSAndroid Build Coastguard Worker 
341*ec779b8eSAndroid Build Coastguard Worker     const wp<IAfThreadBase> mThread;
342*ec779b8eSAndroid Build Coastguard Worker     const alloc_type     mAllocType;
343*ec779b8eSAndroid Build Coastguard Worker     /*const*/ sp<Client> mClient;   // see explanation at ~TrackBase() why not const
344*ec779b8eSAndroid Build Coastguard Worker     sp<IMemory>         mCblkMemory;
345*ec779b8eSAndroid Build Coastguard Worker     audio_track_cblk_t* mCblk;
346*ec779b8eSAndroid Build Coastguard Worker     sp<IMemory>         mBufferMemory;  // currently non-0 for fast RecordTrack only
347*ec779b8eSAndroid Build Coastguard Worker     void*               mBuffer;    // start of track buffer, typically in shared memory
348*ec779b8eSAndroid Build Coastguard Worker                                     // except for OutputTrack when it is in local memory
349*ec779b8eSAndroid Build Coastguard Worker     size_t              mBufferSize; // size of mBuffer in bytes
350*ec779b8eSAndroid Build Coastguard Worker     // we don't really need a lock for these
351*ec779b8eSAndroid Build Coastguard Worker     MirroredVariable<track_state>  mState;
352*ec779b8eSAndroid Build Coastguard Worker     audio_attributes_t  mAttr;
353*ec779b8eSAndroid Build Coastguard Worker     const uint32_t      mSampleRate;    // initial sample rate only; for tracks which
354*ec779b8eSAndroid Build Coastguard Worker                         // support dynamic rates, the current value is in control block
355*ec779b8eSAndroid Build Coastguard Worker     const audio_format_t mFormat;
356*ec779b8eSAndroid Build Coastguard Worker     const audio_channel_mask_t mChannelMask;
357*ec779b8eSAndroid Build Coastguard Worker     const uint32_t      mChannelCount;
358*ec779b8eSAndroid Build Coastguard Worker     const size_t        mFrameSize; // AudioFlinger's view of frame size in shared memory,
359*ec779b8eSAndroid Build Coastguard Worker                                     // where for AudioTrack (but not AudioRecord),
360*ec779b8eSAndroid Build Coastguard Worker                                     // 8-bit PCM samples are stored as 16-bit
361*ec779b8eSAndroid Build Coastguard Worker     const size_t        mFrameCount;// size of track buffer given at createTrack() or
362*ec779b8eSAndroid Build Coastguard Worker                                     // createRecord(), and then adjusted as needed
363*ec779b8eSAndroid Build Coastguard Worker 
364*ec779b8eSAndroid Build Coastguard Worker     const audio_session_t mSessionId;
365*ec779b8eSAndroid Build Coastguard Worker     uid_t               mUid;
366*ec779b8eSAndroid Build Coastguard Worker     std::list<sp<audioflinger::SyncEvent>> mSyncEvents;
367*ec779b8eSAndroid Build Coastguard Worker     const bool          mIsOut;
368*ec779b8eSAndroid Build Coastguard Worker     sp<ServerProxy>     mServerProxy;
369*ec779b8eSAndroid Build Coastguard Worker     const int           mId;
370*ec779b8eSAndroid Build Coastguard Worker #ifdef TEE_SINK
371*ec779b8eSAndroid Build Coastguard Worker     NBAIO_Tee           mTee;
372*ec779b8eSAndroid Build Coastguard Worker #endif
373*ec779b8eSAndroid Build Coastguard Worker     bool                mTerminated;
374*ec779b8eSAndroid Build Coastguard Worker     track_type          mType;      // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
375*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t   mThreadIoHandle; // I/O handle of the thread the track is attached to
376*ec779b8eSAndroid Build Coastguard Worker     audio_port_handle_t mPortId; // unique ID for this track used by audio policy
377*ec779b8eSAndroid Build Coastguard Worker     bool                mIsInvalid; // non-resettable latch, set by invalidate()
378*ec779b8eSAndroid Build Coastguard Worker 
379*ec779b8eSAndroid Build Coastguard Worker     // It typically takes 5 threadloop mix iterations for latency to stabilize.
380*ec779b8eSAndroid Build Coastguard Worker     // However, this can be 12+ iterations for BT.
381*ec779b8eSAndroid Build Coastguard Worker     // To be sure, we wait for latency to dip (it usually increases at the start)
382*ec779b8eSAndroid Build Coastguard Worker     // to assess stability and then log to MediaMetrics.
383*ec779b8eSAndroid Build Coastguard Worker     // Rapid start / pause calls may cause inaccurate numbers.
384*ec779b8eSAndroid Build Coastguard Worker     static inline constexpr int32_t LOG_START_COUNTDOWN = 12;
385*ec779b8eSAndroid Build Coastguard Worker     int32_t             mLogStartCountdown = 0; // Mixer period countdown
386*ec779b8eSAndroid Build Coastguard Worker     int64_t             mLogStartTimeNs = 0;    // Monotonic time at start()
387*ec779b8eSAndroid Build Coastguard Worker     int64_t             mLogStartFrames = 0;    // Timestamp frames at start()
388*ec779b8eSAndroid Build Coastguard Worker     double              mLogLatencyMs = 0.;     // Track the last log latency
389*ec779b8eSAndroid Build Coastguard Worker 
390*ec779b8eSAndroid Build Coastguard Worker     bool                mLogForceVolumeUpdate = true; // force volume update to TrackMetrics.
391*ec779b8eSAndroid Build Coastguard Worker 
392*ec779b8eSAndroid Build Coastguard Worker     audio_utils::trace::Object mLastTrace;  // accessed by PlaybackThread or RecordThread
393*ec779b8eSAndroid Build Coastguard Worker     TrackMetrics        mTrackMetrics;
394*ec779b8eSAndroid Build Coastguard Worker 
395*ec779b8eSAndroid Build Coastguard Worker     bool                mServerLatencySupported = false;
396*ec779b8eSAndroid Build Coastguard Worker     std::atomic<bool>   mServerLatencyFromTrack{}; // latency from track or server timestamp.
397*ec779b8eSAndroid Build Coastguard Worker     std::atomic<double> mServerLatencyMs{};        // last latency pushed from server thread.
398*ec779b8eSAndroid Build Coastguard Worker     std::atomic<FrameTime> mKernelFrameTime{};     // last frame time on kernel side.
399*ec779b8eSAndroid Build Coastguard Worker     const pid_t         mCreatorPid;  // can be different from mclient->pid() for instance
400*ec779b8eSAndroid Build Coastguard Worker                                       // when created by NuPlayer on behalf of a client
401*ec779b8eSAndroid Build Coastguard Worker 
402*ec779b8eSAndroid Build Coastguard Worker     const std::string mTraceSuffix;
403*ec779b8eSAndroid Build Coastguard Worker     const std::string mTraceActionId;
404*ec779b8eSAndroid Build Coastguard Worker     const std::string mTraceIntervalId;
405*ec779b8eSAndroid Build Coastguard Worker 
406*ec779b8eSAndroid Build Coastguard Worker     // If the last track change was notified to the client with readAndClearHasChanged
407*ec779b8eSAndroid Build Coastguard Worker     std::atomic_flag    mChangeNotified = ATOMIC_FLAG_INIT;
408*ec779b8eSAndroid Build Coastguard Worker     // RAII object for battery stats book-keeping
409*ec779b8eSAndroid Build Coastguard Worker     std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder;
410*ec779b8eSAndroid Build Coastguard Worker     std::unique_ptr<media::psh_utils::Token> mTrackToken;
411*ec779b8eSAndroid Build Coastguard Worker };
412*ec779b8eSAndroid Build Coastguard Worker 
413*ec779b8eSAndroid Build Coastguard Worker class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase
414*ec779b8eSAndroid Build Coastguard Worker {
415*ec779b8eSAndroid Build Coastguard Worker public:
416*ec779b8eSAndroid Build Coastguard Worker                         PatchTrackBase(const sp<ClientProxy>& proxy,
417*ec779b8eSAndroid Build Coastguard Worker                                        IAfThreadBase* thread,
418*ec779b8eSAndroid Build Coastguard Worker                                        const Timeout& timeout);
419*ec779b8eSAndroid Build Coastguard Worker             void setPeerTimeout(std::chrono::nanoseconds timeout) final;
setPeerProxy(const sp<IAfPatchTrackBase> & proxy,bool holdReference)420*ec779b8eSAndroid Build Coastguard Worker             void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final {
421*ec779b8eSAndroid Build Coastguard Worker                 if (proxy) {
422*ec779b8eSAndroid Build Coastguard Worker                     mPeerReferenceHold = holdReference ? proxy : nullptr;
423*ec779b8eSAndroid Build Coastguard Worker                     mPeerProxy = proxy->asPatchProxyBufferProvider();
424*ec779b8eSAndroid Build Coastguard Worker                 } else {
425*ec779b8eSAndroid Build Coastguard Worker                     clearPeerProxy();
426*ec779b8eSAndroid Build Coastguard Worker                 }
427*ec779b8eSAndroid Build Coastguard Worker             }
clearPeerProxy()428*ec779b8eSAndroid Build Coastguard Worker             void clearPeerProxy() final {
429*ec779b8eSAndroid Build Coastguard Worker                             mPeerReferenceHold.clear();
430*ec779b8eSAndroid Build Coastguard Worker                             mPeerProxy = nullptr;
431*ec779b8eSAndroid Build Coastguard Worker                         }
432*ec779b8eSAndroid Build Coastguard Worker 
asPatchProxyBufferProvider()433*ec779b8eSAndroid Build Coastguard Worker             PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; }
434*ec779b8eSAndroid Build Coastguard Worker 
producesBufferOnDemand()435*ec779b8eSAndroid Build Coastguard Worker             bool        producesBufferOnDemand() const override { return false; }
436*ec779b8eSAndroid Build Coastguard Worker 
437*ec779b8eSAndroid Build Coastguard Worker protected:
438*ec779b8eSAndroid Build Coastguard Worker     const sp<ClientProxy>       mProxy;
439*ec779b8eSAndroid Build Coastguard Worker     sp<RefBase>                 mPeerReferenceHold;   // keeps mPeerProxy alive during access.
440*ec779b8eSAndroid Build Coastguard Worker     PatchProxyBufferProvider*   mPeerProxy = nullptr;
441*ec779b8eSAndroid Build Coastguard Worker     struct timespec             mPeerTimeout{};
442*ec779b8eSAndroid Build Coastguard Worker };
443*ec779b8eSAndroid Build Coastguard Worker 
444*ec779b8eSAndroid Build Coastguard Worker } // namespace android
445