/*
**
** Copyright 2008, 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 ANDROID_MEDIAPLAYERSERVICE_H
#define ANDROID_MEDIAPLAYERSERVICE_H

#include <arpa/inet.h>

#include <utils/threads.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/Vector.h>

#include <media/AudioSystem.h>
#include <media/MediaPlayerInterface.h>
#include <media/Metadata.h>
#include <media/stagefright/foundation/ABase.h>


#include <system/audio.h>

namespace android {

struct AudioPlaybackRate;
class AudioTrack;
struct AVSyncSettings;
class DeathNotifier;
class IDataSource;
class IMediaRecorder;
class IMediaMetadataRetriever;
class IRemoteDisplay;
class IRemoteDisplayClient;
class MediaRecorderClient;

#define CALLBACK_ANTAGONIZER 0
#if CALLBACK_ANTAGONIZER
class Antagonizer {
public:
    Antagonizer(const sp<MediaPlayerBase::Listener> &listener);
    void start() { mActive = true; }
    void stop() { mActive = false; }
    void kill();
private:
    static const int interval;
    Antagonizer();
    static int callbackThread(void* cookie);
    Mutex                         mLock;
    Condition                     mCondition;
    bool                          mExit;
    bool                          mActive;
    sp<MediaPlayerBase::Listener> mListener;
};
#endif

class MediaPlayerService : public BnMediaPlayerService
{
    class Client;

    class AudioOutput : public MediaPlayerBase::AudioSink
    {
        class CallbackData;

     public:
                                AudioOutput(
                                        audio_session_t sessionId,
                                        uid_t uid,
                                        int pid,
                                        const audio_attributes_t * attr,
                                        const sp<AudioSystem::AudioDeviceCallback>& deviceCallback);
        virtual                 ~AudioOutput();

        virtual bool            ready() const { return mTrack != 0; }
        virtual ssize_t         bufferSize() const;
        virtual ssize_t         frameCount() const;
        virtual ssize_t         channelCount() const;
        virtual ssize_t         frameSize() const;
        virtual uint32_t        latency() const;
        virtual float           msecsPerFrame() const;
        virtual status_t        getPosition(uint32_t *position) const;
        virtual status_t        getTimestamp(AudioTimestamp &ts) const;
        virtual int64_t         getPlayedOutDurationUs(int64_t nowUs) const;
        virtual status_t        getFramesWritten(uint32_t *frameswritten) const;
        virtual audio_session_t getSessionId() const;
        virtual uint32_t        getSampleRate() const;
        virtual int64_t         getBufferDurationInUs() const;

        virtual status_t        open(
                uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
                audio_format_t format, int bufferCount,
                AudioCallback cb, void *cookie,
                audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                const audio_offload_info_t *offloadInfo = NULL,
                bool doNotReconnect = false,
                uint32_t suggestedFrameCount = 0);

        virtual status_t        start();
        virtual ssize_t         write(const void* buffer, size_t size, bool blocking = true);
        virtual void            stop();
        virtual void            flush();
        virtual void            pause();
        virtual void            close();
                void            setAudioStreamType(audio_stream_type_t streamType);
        virtual audio_stream_type_t getAudioStreamType() const { return mStreamType; }
                void            setAudioAttributes(const audio_attributes_t * attributes);

                void            setVolume(float left, float right);
        virtual status_t        setPlaybackRate(const AudioPlaybackRate& rate);
        virtual status_t        getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);

                status_t        setAuxEffectSendLevel(float level);
                status_t        attachAuxEffect(int effectId);
        virtual status_t        dump(int fd, const Vector<String16>& args) const;

        static bool             isOnEmulator();
        static int              getMinBufferCount();
                void            setNextOutput(const sp<AudioOutput>& nextOutput);
                void            switchToNextOutput();
        virtual bool            needsTrailingPadding() { return mNextOutput == NULL; }
        virtual status_t        setParameters(const String8& keyValuePairs);
        virtual String8         getParameters(const String8& keys);

        virtual media::VolumeShaper::Status applyVolumeShaper(
                                        const sp<media::VolumeShaper::Configuration>& configuration,
                                        const sp<media::VolumeShaper::Operation>& operation) override;
        virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;

        // AudioRouting
        virtual status_t        setOutputDevice(audio_port_handle_t deviceId);
        virtual status_t        getRoutedDeviceId(audio_port_handle_t* deviceId);
        virtual status_t        enableAudioDeviceCallback(bool enabled);

    private:
        static void             setMinBufferCount();
        static void             CallbackWrapper(
                int event, void *me, void *info);
               void             deleteRecycledTrack_l();
               void             close_l();
           status_t             updateTrack();

        sp<AudioTrack>          mTrack;
        sp<AudioTrack>          mRecycledTrack;
        sp<AudioOutput>         mNextOutput;
        AudioCallback           mCallback;
        void *                  mCallbackCookie;
        CallbackData *          mCallbackData;
        audio_stream_type_t     mStreamType;
        audio_attributes_t *    mAttributes;
        float                   mLeftVolume;
        float                   mRightVolume;
        AudioPlaybackRate       mPlaybackRate;
        uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
        float                   mMsecsPerFrame;
        size_t                  mFrameSize;
        audio_session_t         mSessionId;
        uid_t                   mUid;
        int                     mPid;
        float                   mSendLevel;
        int                     mAuxEffectId;
        audio_output_flags_t    mFlags;
        sp<media::VolumeHandler>       mVolumeHandler;
        audio_port_handle_t     mSelectedDeviceId;
        audio_port_handle_t     mRoutedDeviceId;
        bool                    mDeviceCallbackEnabled;
        wp<AudioSystem::AudioDeviceCallback>        mDeviceCallback;
        mutable Mutex           mLock;

        // static variables below not protected by mutex
        static bool             mIsOnEmulator;
        static int              mMinBufferCount;  // 12 for emulator; otherwise 4

        // CallbackData is what is passed to the AudioTrack as the "user" data.
        // We need to be able to target this to a different Output on the fly,
        // so we can't use the Output itself for this.
        class CallbackData {
            friend AudioOutput;
        public:
            explicit CallbackData(AudioOutput *cookie) {
                mData = cookie;
                mSwitching = false;
            }
            AudioOutput *   getOutput() const { return mData; }
            void            setOutput(AudioOutput* newcookie) { mData = newcookie; }
            // lock/unlock are used by the callback before accessing the payload of this object
            void            lock() const { mLock.lock(); }
            void            unlock() const { mLock.unlock(); }

            // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
            // to the next sink.

            // tryBeginTrackSwitch() returns true only if it obtains the lock.
            bool            tryBeginTrackSwitch() {
                LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
                if (mLock.tryLock() != OK) {
                    return false;
                }
                mSwitching = true;
                return true;
            }
            void            endTrackSwitch() {
                if (mSwitching) {
                    mLock.unlock();
                }
                mSwitching = false;
            }
        private:
            AudioOutput *   mData;
            mutable Mutex   mLock; // a recursive mutex might make this unnecessary.
            bool            mSwitching;
            DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
        };

    }; // AudioOutput

public:
    static  void                instantiate();

    // IMediaPlayerService interface
    virtual sp<IMediaRecorder>  createMediaRecorder(const String16 &opPackageName);
    void    removeMediaRecorderClient(const wp<MediaRecorderClient>& client);
    virtual sp<IMediaMetadataRetriever> createMetadataRetriever();

    virtual sp<IMediaPlayer>    create(const sp<IMediaPlayerClient>& client,
                                       audio_session_t audioSessionId);

    virtual sp<IMediaCodecList> getCodecList() const;

    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
            const sp<IRemoteDisplayClient>& client, const String8& iface);
    virtual status_t            dump(int fd, const Vector<String16>& args);

            void                removeClient(const wp<Client>& client);
            bool                hasClient(wp<Client> client);

    enum {
        MEDIASERVER_PROCESS_DEATH = 0,
        MEDIAEXTRACTOR_PROCESS_DEATH = 1,
        MEDIACODEC_PROCESS_DEATH = 2,
        AUDIO_PROCESS_DEATH = 3,   // currently no need to track this
        CAMERA_PROCESS_DEATH = 4
    };

    // Collect info of the codec usage from media player and media recorder
    virtual void                addBatteryData(uint32_t params);
    // API for the Battery app to pull the data of codecs usage
    virtual status_t            pullBatteryData(Parcel* reply);
private:
    struct BatteryTracker {
        BatteryTracker();
        // Collect info of the codec usage from media player and media recorder
        void addBatteryData(uint32_t params);
        // API for the Battery app to pull the data of codecs usage
        status_t pullBatteryData(Parcel* reply);

    private:
        // For battery usage tracking purpose
        struct BatteryUsageInfo {
            // how many streams are being played by one UID
            int     refCount;
            // a temp variable to store the duration(ms) of audio codecs
            // when we start a audio codec, we minus the system time from audioLastTime
            // when we pause it, we add the system time back to the audioLastTime
            // so after the pause, audioLastTime = pause time - start time
            // if multiple audio streams are played (or recorded), then audioLastTime
            // = the total playing time of all the streams
            int32_t audioLastTime;
            // when all the audio streams are being paused, we assign audioLastTime to
            // this variable, so this value could be provided to the battery app
            // in the next pullBatteryData call
            int32_t audioTotalTime;

            int32_t videoLastTime;
            int32_t videoTotalTime;
        };
        KeyedVector<int, BatteryUsageInfo>    mBatteryData;

        enum {
            SPEAKER,
            OTHER_AUDIO_DEVICE,
            SPEAKER_AND_OTHER,
            NUM_AUDIO_DEVICES
        };

        struct BatteryAudioFlingerUsageInfo {
            int refCount; // how many audio streams are being played
            int deviceOn[NUM_AUDIO_DEVICES]; // whether the device is currently used
            int32_t lastTime[NUM_AUDIO_DEVICES]; // in ms
            // totalTime[]: total time of audio output devices usage
            int32_t totalTime[NUM_AUDIO_DEVICES]; // in ms
        };

        // This varialble is used to record the usage of audio output device
        // for battery app
        BatteryAudioFlingerUsageInfo mBatteryAudio;

        mutable Mutex mLock;
    };
    BatteryTracker mBatteryTracker;

    class Client : public BnMediaPlayer {
        // IMediaPlayer interface
        virtual void            disconnect();
        virtual status_t        setVideoSurfaceTexture(
                                        const sp<IGraphicBufferProducer>& bufferProducer);
        virtual status_t        setBufferingSettings(const BufferingSettings& buffering) override;
        virtual status_t        getBufferingSettings(
                                        BufferingSettings* buffering /* nonnull */) override;
        virtual status_t        prepareAsync();
        virtual status_t        start();
        virtual status_t        stop();
        virtual status_t        pause();
        virtual status_t        isPlaying(bool* state);
        virtual status_t        setPlaybackSettings(const AudioPlaybackRate& rate);
        virtual status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
        virtual status_t        setSyncSettings(const AVSyncSettings& rate, float videoFpsHint);
        virtual status_t        getSyncSettings(AVSyncSettings* rate /* nonnull */,
                                                float* videoFps /* nonnull */);
        virtual status_t        seekTo(
                int msec,
                MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC);
        virtual status_t        getCurrentPosition(int* msec);
        virtual status_t        getDuration(int* msec);
        virtual status_t        reset();
        virtual status_t        notifyAt(int64_t mediaTimeUs);
        virtual status_t        setAudioStreamType(audio_stream_type_t type);
        virtual status_t        setLooping(int loop);
        virtual status_t        setVolume(float leftVolume, float rightVolume);
        virtual status_t        invoke(const Parcel& request, Parcel *reply);
        virtual status_t        setMetadataFilter(const Parcel& filter);
        virtual status_t        getMetadata(bool update_only,
                                            bool apply_filter,
                                            Parcel *reply);
        virtual status_t        setAuxEffectSendLevel(float level);
        virtual status_t        attachAuxEffect(int effectId);
        virtual status_t        setParameter(int key, const Parcel &request);
        virtual status_t        getParameter(int key, Parcel *reply);
        virtual status_t        setRetransmitEndpoint(const struct sockaddr_in* endpoint);
        virtual status_t        getRetransmitEndpoint(struct sockaddr_in* endpoint);
        virtual status_t        setNextPlayer(const sp<IMediaPlayer>& player);

        virtual media::VolumeShaper::Status applyVolumeShaper(
                                        const sp<media::VolumeShaper::Configuration>& configuration,
                                        const sp<media::VolumeShaper::Operation>& operation) override;
        virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;

        sp<MediaPlayerBase>     createPlayer(player_type playerType);

        virtual status_t        setDataSource(
                        const sp<IMediaHTTPService> &httpService,
                        const char *url,
                        const KeyedVector<String8, String8> *headers);

        virtual status_t        setDataSource(int fd, int64_t offset, int64_t length);

        virtual status_t        setDataSource(const sp<IStreamSource> &source);
        virtual status_t        setDataSource(const sp<IDataSource> &source);


        sp<MediaPlayerBase>     setDataSource_pre(player_type playerType);
        status_t                setDataSource_post(const sp<MediaPlayerBase>& p,
                                                   status_t status);

                void            notify(int msg, int ext1, int ext2, const Parcel *obj);

                pid_t           pid() const { return mPid; }
        virtual status_t        dump(int fd, const Vector<String16>& args);

                audio_session_t getAudioSessionId() { return mAudioSessionId; }
        // Modular DRM
        virtual status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId);
        virtual status_t releaseDrm();
        // AudioRouting
        virtual status_t setOutputDevice(audio_port_handle_t deviceId);
        virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
        virtual status_t enableAudioDeviceCallback(bool enabled);

    private:
        class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
        {
        public:
            AudioDeviceUpdatedNotifier(const sp<MediaPlayerBase>& listener) {
                mListener = listener;
            }
            ~AudioDeviceUpdatedNotifier() {}

            virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
                                             audio_port_handle_t deviceId);

        private:
            wp<MediaPlayerBase> mListener;
        };

        friend class MediaPlayerService;
                                Client( const sp<MediaPlayerService>& service,
                                        pid_t pid,
                                        int32_t connId,
                                        const sp<IMediaPlayerClient>& client,
                                        audio_session_t audioSessionId,
                                        uid_t uid);
                                Client();
        virtual                 ~Client();

                void            deletePlayer();

        sp<MediaPlayerBase>     getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; }



        // @param type Of the metadata to be tested.
        // @return true if the metadata should be dropped according to
        //              the filters.
        bool shouldDropMetadata(media::Metadata::Type type) const;

        // Add a new element to the set of metadata updated. Noop if
        // the element exists already.
        // @param type Of the metadata to be recorded.
        void addNewMetadataUpdate(media::Metadata::Type type);

        // Disconnect from the currently connected ANativeWindow.
        void disconnectNativeWindow_l();

        status_t setAudioAttributes_l(const Parcel &request);

        class Listener : public MediaPlayerBase::Listener {
        public:
            Listener(const wp<Client> &client) : mClient(client) {}
            virtual ~Listener() {}
            virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
                sp<Client> client = mClient.promote();
                if (client != NULL) {
                    client->notify(msg, ext1, ext2, obj);
                }
            }
        private:
            wp<Client> mClient;
        };

        mutable     Mutex                         mLock;
                    sp<MediaPlayerBase>           mPlayer;
                    sp<MediaPlayerService>        mService;
                    sp<IMediaPlayerClient>        mClient;
                    sp<AudioOutput>               mAudioOutput;
                    pid_t                         mPid;
                    status_t                      mStatus;
                    bool                          mLoop;
                    int32_t                       mConnId;
                    audio_session_t               mAudioSessionId;
                    audio_attributes_t *          mAudioAttributes;
                    uid_t                         mUid;
                    sp<ANativeWindow>             mConnectedWindow;
                    sp<IBinder>                   mConnectedWindowBinder;
                    struct sockaddr_in            mRetransmitEndpoint;
                    bool                          mRetransmitEndpointValid;
                    sp<Client>                    mNextClient;
                    sp<MediaPlayerBase::Listener> mListener;

        // Metadata filters.
        media::Metadata::Filter mMetadataAllow;  // protected by mLock
        media::Metadata::Filter mMetadataDrop;  // protected by mLock

        // Metadata updated. For each MEDIA_INFO_METADATA_UPDATE
        // notification we try to update mMetadataUpdated which is a
        // set: no duplicate.
        // getMetadata clears this set.
        media::Metadata::Filter mMetadataUpdated;  // protected by mLock

        std::vector<DeathNotifier> mDeathNotifiers;
        sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedListener;
#if CALLBACK_ANTAGONIZER
                    Antagonizer*                  mAntagonizer;
#endif
    }; // Client

// ----------------------------------------------------------------------------

                            MediaPlayerService();
    virtual                 ~MediaPlayerService();

    mutable     Mutex                       mLock;
                SortedVector< wp<Client> >  mClients;
                SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
                int32_t                     mNextConnId;
};

// ----------------------------------------------------------------------------

}; // namespace android

#endif // ANDROID_MEDIAPLAYERSERVICE_H
