/*
**
** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#ifndef INCLUDING_FROM_AUDIOFLINGER_H
    #error This header file should only be included from AudioFlinger.h
#endif

// base for record and playback
class TrackBase : public ExtendedAudioBufferProvider, public RefBase {

public:
    enum track_state {
        IDLE,
        FLUSHED,        // for PlaybackTracks only
        STOPPED,
        // next 2 states are currently used for fast tracks
        // and offloaded tracks only
        STOPPING_1,     // waiting for first underrun
        STOPPING_2,     // waiting for presentation complete
        RESUMING,       // for PlaybackTracks only
        ACTIVE,
        PAUSING,
        PAUSED,
        STARTING_1,     // for RecordTrack only
        STARTING_2,     // for RecordTrack only
    };

    // where to allocate the data buffer
    enum alloc_type {
        ALLOC_CBLK,     // allocate immediately after control block
        ALLOC_READONLY, // allocate from a separate read-only heap per thread
        ALLOC_PIPE,     // do not allocate; use the pipe buffer
        ALLOC_LOCAL,    // allocate a local buffer
        ALLOC_NONE,     // do not allocate:use the buffer passed to TrackBase constructor
    };

    enum track_type {
        TYPE_DEFAULT,
        TYPE_OUTPUT,
        TYPE_PATCH,
    };

                        TrackBase(ThreadBase *thread,
                                const sp<Client>& client,
                                const audio_attributes_t& mAttr,
                                uint32_t sampleRate,
                                audio_format_t format,
                                audio_channel_mask_t channelMask,
                                size_t frameCount,
                                void *buffer,
                                size_t bufferSize,
                                audio_session_t sessionId,
                                pid_t creatorPid,
                                uid_t uid,
                                bool isOut,
                                alloc_type alloc = ALLOC_CBLK,
                                track_type type = TYPE_DEFAULT,
                                audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
                                std::string metricsId = {});
    virtual             ~TrackBase();
    virtual status_t    initCheck() const;

    virtual status_t    start(AudioSystem::sync_event_t event,
                             audio_session_t triggerSession) = 0;
    virtual void        stop() = 0;
            sp<IMemory> getCblk() const { return mCblkMemory; }
            audio_track_cblk_t* cblk() const { return mCblk; }
            audio_session_t sessionId() const { return mSessionId; }
            uid_t       uid() const { return mUid; }
            pid_t       creatorPid() const { return mCreatorPid; }

            audio_port_handle_t portId() const { return mPortId; }
    virtual status_t    setSyncEvent(const sp<SyncEvent>& event);

            sp<IMemory> getBuffers() const { return mBufferMemory; }
            void*       buffer() const { return mBuffer; }
            size_t      bufferSize() const { return mBufferSize; }
    virtual bool        isFastTrack() const = 0;
    virtual bool        isDirect() const = 0;
            bool        isOutputTrack() const { return (mType == TYPE_OUTPUT); }
            bool        isPatchTrack() const { return (mType == TYPE_PATCH); }
            bool        isExternalTrack() const { return !isOutputTrack() && !isPatchTrack(); }

    virtual void        invalidate() {
                            if (mIsInvalid) return;
                            mTrackMetrics.logInvalidate();
                            mIsInvalid = true;
                        }
            bool        isInvalid() const { return mIsInvalid; }

            void        terminate() { mTerminated = true; }
            bool        isTerminated() const { return mTerminated; }

    audio_attributes_t  attributes() const { return mAttr; }

#ifdef TEE_SINK
           void         dumpTee(int fd, const std::string &reason) const {
                                mTee.dump(fd, reason);
                        }
#endif

            /** returns the buffer contents size converted to time in milliseconds
             * for PCM Playback or Record streaming tracks. The return value is zero for
             * PCM static tracks and not defined for non-PCM tracks.
             *
             * This may be called without the thread lock.
             */
    virtual double      bufferLatencyMs() const {
                            return mServerProxy->framesReadySafe() * 1000 / sampleRate();
                        }

            /** returns whether the track supports server latency computation.
             * This is set in the constructor and constant throughout the track lifetime.
             */

            bool        isServerLatencySupported() const { return mServerLatencySupported; }

            /** computes the server latency for PCM Playback or Record track
             * to the device sink/source.  This is the time for the next frame in the track buffer
             * written or read from the server thread to the device source or sink.
             *
             * This may be called without the thread lock, but latencyMs and fromTrack
             * may be not be synchronized. For example PatchPanel may not obtain the
             * thread lock before calling.
             *
             * \param latencyMs on success is set to the latency in milliseconds of the
             *        next frame written/read by the server thread to/from the track buffer
             *        from the device source/sink.
             * \param fromTrack on success is set to true if latency was computed directly
             *        from the track timestamp; otherwise set to false if latency was
             *        estimated from the server timestamp.
             *        fromTrack may be nullptr or omitted if not required.
             *
             * \returns OK or INVALID_OPERATION on failure.
             */
            status_t    getServerLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
                            if (!isServerLatencySupported()) {
                                return INVALID_OPERATION;
                            }

                            // if no thread lock is acquired, these atomics are not
                            // synchronized with each other, considered a benign race.

                            const double serverLatencyMs = mServerLatencyMs.load();
                            if (serverLatencyMs == 0.) {
                                return INVALID_OPERATION;
                            }
                            if (fromTrack != nullptr) {
                                *fromTrack = mServerLatencyFromTrack.load();
                            }
                            *latencyMs = serverLatencyMs;
                            return OK;
                        }

            /** computes the total client latency for PCM Playback or Record tracks
             * for the next client app access to the device sink/source; i.e. the
             * server latency plus the buffer latency.
             *
             * This may be called without the thread lock, but latencyMs and fromTrack
             * may be not be synchronized. For example PatchPanel may not obtain the
             * thread lock before calling.
             *
             * \param latencyMs on success is set to the latency in milliseconds of the
             *        next frame written/read by the client app to/from the track buffer
             *        from the device sink/source.
             * \param fromTrack on success is set to true if latency was computed directly
             *        from the track timestamp; otherwise set to false if latency was
             *        estimated from the server timestamp.
             *        fromTrack may be nullptr or omitted if not required.
             *
             * \returns OK or INVALID_OPERATION on failure.
             */
            status_t    getTrackLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
                            double serverLatencyMs;
                            status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
                            if (status == OK) {
                                *latencyMs = serverLatencyMs + bufferLatencyMs();
                            }
                            return status;
                        }

           // TODO: Consider making this external.
           struct FrameTime {
               int64_t frames;
               int64_t timeNs;
           };

           // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
           void         getKernelFrameTime(FrameTime *ft) const {
                           *ft = mKernelFrameTime.load();
                        }

           audio_format_t format() const { return mFormat; }
           int id() const { return mId; }

    const char *getTrackStateAsString() const {
        if (isTerminated()) {
            return "TERMINATED";
        }
        switch (mState) {
        case IDLE:
            return "IDLE";
        case STOPPING_1: // for Fast and Offload
            return "STOPPING_1";
        case STOPPING_2: // for Fast and Offload
            return "STOPPING_2";
        case STOPPED:
            return "STOPPED";
        case RESUMING:
            return "RESUMING";
        case ACTIVE:
            return "ACTIVE";
        case PAUSING:
            return "PAUSING";
        case PAUSED:
            return "PAUSED";
        case FLUSHED:
            return "FLUSHED";
        case STARTING_1: // for RecordTrack
            return "STARTING_1";
        case STARTING_2: // for RecordTrack
            return "STARTING_2";
        default:
            return "UNKNOWN";
        }
    }

    // Called by the PlaybackThread to indicate that the track is becoming active
    // and a new interval should start with a given device list.
    void logBeginInterval(const std::string& devices) {
        mTrackMetrics.logBeginInterval(devices);
    }

    // Called by the PlaybackThread to indicate the track is no longer active.
    void logEndInterval() {
        mTrackMetrics.logEndInterval();
    }

    // Called to tally underrun frames in playback.
    virtual void tallyUnderrunFrames(size_t /* frames */) {}

protected:
    DISALLOW_COPY_AND_ASSIGN(TrackBase);

    void releaseCblk() {
        if (mCblk != nullptr) {
            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
            if (mClient == 0) {
                free(mCblk);
            }
            mCblk = nullptr;
        }
    }

    // AudioBufferProvider interface
    virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
    virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);

    // ExtendedAudioBufferProvider interface is only needed for Track,
    // but putting it in TrackBase avoids the complexity of virtual inheritance
    virtual size_t  framesReady() const { return SIZE_MAX; }

    uint32_t channelCount() const { return mChannelCount; }

    size_t frameSize() const { return mFrameSize; }

    audio_channel_mask_t channelMask() const { return mChannelMask; }

    virtual uint32_t sampleRate() const { return mSampleRate; }

    bool isStopped() const {
        return (mState == STOPPED || mState == FLUSHED);
    }

    // for fast tracks and offloaded tracks only
    bool isStopping() const {
        return mState == STOPPING_1 || mState == STOPPING_2;
    }
    bool isStopping_1() const {
        return mState == STOPPING_1;
    }
    bool isStopping_2() const {
        return mState == STOPPING_2;
    }

    // Upper case characters are final states.
    // Lower case characters are transitory.
    const char *getTrackStateAsCodedString() const {
        if (isTerminated()) {
            return "T ";
        }
        switch (mState) {
        case IDLE:
            return "I ";
        case STOPPING_1: // for Fast and Offload
            return "s1";
        case STOPPING_2: // for Fast and Offload
            return "s2";
        case STOPPED:
            return "S ";
        case RESUMING:
            return "r ";
        case ACTIVE:
            return "A ";
        case PAUSING:
            return "p ";
        case PAUSED:
            return "P ";
        case FLUSHED:
            return "F ";
        case STARTING_1: // for RecordTrack
            return "r1";
        case STARTING_2: // for RecordTrack
            return "r2";
        default:
            return "? ";
        }
    }

    bool isOut() const { return mIsOut; }
                                    // true for Track, false for RecordTrack,
                                    // this could be a track type if needed later

    const wp<ThreadBase> mThread;
    /*const*/ sp<Client> mClient;   // see explanation at ~TrackBase() why not const
    sp<IMemory>         mCblkMemory;
    audio_track_cblk_t* mCblk;
    sp<IMemory>         mBufferMemory;  // currently non-0 for fast RecordTrack only
    void*               mBuffer;    // start of track buffer, typically in shared memory
                                    // except for OutputTrack when it is in local memory
    size_t              mBufferSize; // size of mBuffer in bytes
    // we don't really need a lock for these
    track_state         mState;
    const audio_attributes_t mAttr;
    const uint32_t      mSampleRate;    // initial sample rate only; for tracks which
                        // support dynamic rates, the current value is in control block
    const audio_format_t mFormat;
    const audio_channel_mask_t mChannelMask;
    const uint32_t      mChannelCount;
    const size_t        mFrameSize; // AudioFlinger's view of frame size in shared memory,
                                    // where for AudioTrack (but not AudioRecord),
                                    // 8-bit PCM samples are stored as 16-bit
    const size_t        mFrameCount;// size of track buffer given at createTrack() or
                                    // createRecord(), and then adjusted as needed

    const audio_session_t mSessionId;
    uid_t               mUid;
    Vector < sp<SyncEvent> >mSyncEvents;
    const bool          mIsOut;
    sp<ServerProxy>     mServerProxy;
    const int           mId;
#ifdef TEE_SINK
    NBAIO_Tee           mTee;
#endif
    bool                mTerminated;
    track_type          mType;      // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
    audio_io_handle_t   mThreadIoHandle; // I/O handle of the thread the track is attached to
    audio_port_handle_t mPortId; // unique ID for this track used by audio policy
    bool                mIsInvalid; // non-resettable latch, set by invalidate()

    // It typically takes 5 threadloop mix iterations for latency to stabilize.
    // However, this can be 12+ iterations for BT.
    // To be sure, we wait for latency to dip (it usually increases at the start)
    // to assess stability and then log to MediaMetrics.
    // Rapid start / pause calls may cause inaccurate numbers.
    static inline constexpr int32_t LOG_START_COUNTDOWN = 12;
    int32_t             mLogStartCountdown = 0; // Mixer period countdown
    int64_t             mLogStartTimeNs = 0;    // Monotonic time at start()
    int64_t             mLogStartFrames = 0;    // Timestamp frames at start()
    double              mLogLatencyMs = 0.;     // Track the last log latency

    TrackMetrics        mTrackMetrics;

    bool                mServerLatencySupported = false;
    std::atomic<bool>   mServerLatencyFromTrack{}; // latency from track or server timestamp.
    std::atomic<double> mServerLatencyMs{};        // last latency pushed from server thread.
    std::atomic<FrameTime> mKernelFrameTime{};     // last frame time on kernel side.
    const pid_t         mCreatorPid;  // can be different from mclient->pid() for instance
                                      // when created by NuPlayer on behalf of a client
};

// PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
// it provides buffer access methods that map those of a ClientProxy (see AudioTrackShared.h)
class PatchProxyBufferProvider
{
public:

    virtual ~PatchProxyBufferProvider() {}

    virtual bool        producesBufferOnDemand() const = 0;
    virtual status_t    obtainBuffer(Proxy::Buffer* buffer,
                                     const struct timespec *requested = NULL) = 0;
    virtual void        releaseBuffer(Proxy::Buffer* buffer) = 0;
};

class PatchTrackBase : public PatchProxyBufferProvider
{
public:
    using Timeout = std::optional<std::chrono::nanoseconds>;
                        PatchTrackBase(sp<ClientProxy> proxy, const ThreadBase& thread,
                                       const Timeout& timeout);
            void        setPeerTimeout(std::chrono::nanoseconds timeout);
            template <typename T>
            void        setPeerProxy(const sp<T> &proxy, bool holdReference) {
                            mPeerReferenceHold = holdReference ? proxy : nullptr;
                            mPeerProxy = proxy.get();
                        }
            void        clearPeerProxy() {
                            mPeerReferenceHold.clear();
                            mPeerProxy = nullptr;
                        }

            bool        producesBufferOnDemand() const override { return false; }

protected:
    const sp<ClientProxy>       mProxy;
    sp<RefBase>                 mPeerReferenceHold;   // keeps mPeerProxy alive during access.
    PatchProxyBufferProvider*   mPeerProxy = nullptr;
    struct timespec             mPeerTimeout{};

};
