/*
**
** Copyright 2017, 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.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaPlayer2Native"

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

#include <media/AudioSystem.h>
#include <media/DataSourceDesc.h>
#include <media/MediaAnalyticsItem.h>
#include <media/MemoryLeakTrackUtil.h>
#include <media/Metadata.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooperRoster.h>
#include <mediaplayer2/MediaPlayer2AudioOutput.h>
#include <mediaplayer2/mediaplayer2.h>

#include <utils/Log.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>

#include <system/audio.h>
#include <system/window.h>

#include <nuplayer2/NuPlayer2Driver.h>

#include <dirent.h>
#include <sys/stat.h>

namespace android {

extern ALooperRoster gLooperRoster;

namespace {

const int kDumpLockRetries = 50;
const int kDumpLockSleepUs = 20000;

class proxyListener : public MediaPlayer2InterfaceListener {
public:
    proxyListener(const wp<MediaPlayer2> &player)
        : mPlayer(player) { }

    ~proxyListener() { };

    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
            const PlayerMessage *obj) override {
        sp<MediaPlayer2> player = mPlayer.promote();
        if (player != NULL) {
            player->notify(srcId, msg, ext1, ext2, obj);
        }
    }

private:
    wp<MediaPlayer2> mPlayer;
};

Mutex sRecordLock;
SortedVector<wp<MediaPlayer2> > *sPlayers;

void ensureInit_l() {
    if (sPlayers == NULL) {
        sPlayers = new SortedVector<wp<MediaPlayer2> >();
    }
}

void addPlayer(const wp<MediaPlayer2>& player) {
    Mutex::Autolock lock(sRecordLock);
    ensureInit_l();
    sPlayers->add(player);
}

void removePlayer(const wp<MediaPlayer2>& player) {
    Mutex::Autolock lock(sRecordLock);
    ensureInit_l();
    sPlayers->remove(player);
}

/**
 * The only arguments this understands right now are -c, -von and -voff,
 * which are parsed by ALooperRoster::dump()
 */
status_t dumpPlayers(int fd, const Vector<String16>& args) {
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.

    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
        snprintf(buffer, SIZE, "Permission Denial: can't dump MediaPlayer2\n");
        result.append(buffer);
    } else {
        {
            Mutex::Autolock lock(sRecordLock);
            ensureInit_l();
            for (int i = 0, n = sPlayers->size(); i < n; ++i) {
                sp<MediaPlayer2> p = (*sPlayers)[i].promote();
                if (p != 0) {
                    p->dump(fd, args);
                }
                players.add(p);
            }
        }

        result.append(" Files opened and/or mapped:\n");
        snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
        FILE *f = fopen(buffer, "r");
        if (f) {
            while (!feof(f)) {
                fgets(buffer, SIZE, f);
                if (strstr(buffer, " /storage/") ||
                    strstr(buffer, " /system/sounds/") ||
                    strstr(buffer, " /data/") ||
                    strstr(buffer, " /system/media/")) {
                    result.append("  ");
                    result.append(buffer);
                }
            }
            fclose(f);
        } else {
            result.append("couldn't open ");
            result.append(buffer);
            result.append("\n");
        }

        snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
        DIR *d = opendir(buffer);
        if (d) {
            struct dirent *ent;
            while((ent = readdir(d)) != NULL) {
                if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
                    snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
                    struct stat s;
                    if (lstat(buffer, &s) == 0) {
                        if ((s.st_mode & S_IFMT) == S_IFLNK) {
                            char linkto[256];
                            int len = readlink(buffer, linkto, sizeof(linkto));
                            if(len > 0) {
                                if(len > 255) {
                                    linkto[252] = '.';
                                    linkto[253] = '.';
                                    linkto[254] = '.';
                                    linkto[255] = 0;
                                } else {
                                    linkto[len] = 0;
                                }
                                if (strstr(linkto, "/storage/") == linkto ||
                                    strstr(linkto, "/system/sounds/") == linkto ||
                                    strstr(linkto, "/data/") == linkto ||
                                    strstr(linkto, "/system/media/") == linkto) {
                                    result.append("  ");
                                    result.append(buffer);
                                    result.append(" -> ");
                                    result.append(linkto);
                                    result.append("\n");
                                }
                            }
                        } else {
                            result.append("  unexpected type for ");
                            result.append(buffer);
                            result.append("\n");
                        }
                    }
                }
            }
            closedir(d);
        } else {
            result.append("couldn't open ");
            result.append(buffer);
            result.append("\n");
        }

        gLooperRoster.dump(fd, args);

        bool dumpMem = false;
        bool unreachableMemory = false;
        for (size_t i = 0; i < args.size(); i++) {
            if (args[i] == String16("-m")) {
                dumpMem = true;
            } else if (args[i] == String16("--unreachable")) {
                unreachableMemory = true;
            }
        }
        if (dumpMem) {
            result.append("\nDumping memory:\n");
            std::string s = dumpMemoryAddresses(100 /* limit */);
            result.append(s.c_str(), s.size());
        }
        if (unreachableMemory) {
            result.append("\nDumping unreachable memory:\n");
            // TODO - should limit be an argument parameter?
            // TODO: enable GetUnreachableMemoryString if it's part of stable API
            //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
            //result.append(s.c_str(), s.size());
        }
    }
    write(fd, result.string(), result.size());
    return NO_ERROR;
}

}  // anonymous namespace

//static
sp<MediaPlayer2> MediaPlayer2::Create(int32_t sessionId) {
    sp<MediaPlayer2> player = new MediaPlayer2(sessionId);

    if (!player->init()) {
        return NULL;
    }

    ALOGV("Create new player(%p)", player.get());

    addPlayer(player);
    return player;
}

// static
status_t MediaPlayer2::DumpAll(int fd, const Vector<String16>& args) {
    return dumpPlayers(fd, args);
}

MediaPlayer2::MediaPlayer2(int32_t sessionId) {
    ALOGV("constructor");
    mSrcId = 0;
    mLockThreadId = 0;
    mListener = NULL;
    mStreamType = AUDIO_STREAM_MUSIC;
    mAudioAttributes = NULL;
    mCurrentPosition = -1;
    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
    mSeekPosition = -1;
    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
    mCurrentState = MEDIA_PLAYER2_IDLE;
    mLoop = false;
    mVolume = 1.0;
    mVideoWidth = mVideoHeight = 0;
    mSendLevel = 0;

    // TODO: get pid and uid from JAVA
    mPid = IPCThreadState::self()->getCallingPid();
    mUid = IPCThreadState::self()->getCallingUid();

    mAudioOutput = new MediaPlayer2AudioOutput(sessionId, mUid, mPid, NULL /*attributes*/);
}

MediaPlayer2::~MediaPlayer2() {
    ALOGV("destructor");
    disconnect();
    removePlayer(this);
}

bool MediaPlayer2::init() {
    // TODO: after merge with NuPlayer2Driver, MediaPlayer2 will have its own
    // looper for notification.
    return true;
}

void MediaPlayer2::disconnect() {
    ALOGV("disconnect");
    sp<MediaPlayer2Interface> p;
    {
        Mutex::Autolock _l(mLock);
        p = mPlayer;
        mPlayer.clear();
    }

    if (p != 0) {
        p->setListener(NULL);
        p->reset();
    }

    {
        Mutex::Autolock _l(mLock);
        disconnectNativeWindow_l();
    }
}

void MediaPlayer2::clear_l() {
    mCurrentPosition = -1;
    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
    mSeekPosition = -1;
    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
    mVideoWidth = mVideoHeight = 0;
}

status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener) {
    ALOGV("setListener");
    Mutex::Autolock _l(mLock);
    mListener = listener;
    return NO_ERROR;
}

status_t MediaPlayer2::getSrcId(int64_t *srcId) {
    if (srcId == NULL) {
        return BAD_VALUE;
    }

    Mutex::Autolock _l(mLock);
    *srcId = mSrcId;
    return OK;
}

status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd) {
    if (dsd == NULL) {
        return BAD_VALUE;
    }
    // Microsecond is used in NuPlayer2.
    if (dsd->mStartPositionMs > DataSourceDesc::kMaxTimeMs) {
        dsd->mStartPositionMs = DataSourceDesc::kMaxTimeMs;
        ALOGW("setDataSource, start poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
    }
    if (dsd->mEndPositionMs > DataSourceDesc::kMaxTimeMs) {
        dsd->mEndPositionMs = DataSourceDesc::kMaxTimeMs;
        ALOGW("setDataSource, end poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
    }
    ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);

    sp<MediaPlayer2Interface> oldPlayer;

    Mutex::Autolock _l(mLock);
    {
        if (!((mCurrentState & MEDIA_PLAYER2_IDLE)
              || mCurrentState == MEDIA_PLAYER2_STATE_ERROR)) {
            ALOGE("setDataSource called in wrong state %d", mCurrentState);
            return INVALID_OPERATION;
        }

        sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid);
        status_t err = player->initCheck();
        if (err != NO_ERROR) {
            ALOGE("Failed to create player object, initCheck failed(%d)", err);
            return err;
        }

        clear_l();

        player->setListener(new proxyListener(this));
        player->setAudioSink(mAudioOutput);

        err = player->setDataSource(dsd);
        if (err != OK) {
            ALOGE("setDataSource error: %d", err);
            return err;
        }

        sp<MediaPlayer2Interface> oldPlayer = mPlayer;
        mPlayer = player;
        mSrcId = dsd->mId;
        mCurrentState = MEDIA_PLAYER2_INITIALIZED;
    }

    if (oldPlayer != NULL) {
        oldPlayer->setListener(NULL);
        oldPlayer->reset();
    }

    return OK;
}

status_t MediaPlayer2::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
    if (dsd == NULL) {
        return BAD_VALUE;
    }
    ALOGV("prepareNextDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);

    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        ALOGE("prepareNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
        return INVALID_OPERATION;
    }
    return mPlayer->prepareNextDataSource(dsd);
}

status_t MediaPlayer2::playNextDataSource(int64_t srcId) {
    ALOGV("playNextDataSource srcId(%lld)", (long long)srcId);

    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
        return INVALID_OPERATION;
    }
    mSrcId = srcId;
    return mPlayer->playNextDataSource(srcId);
}

status_t MediaPlayer2::invoke(const PlayerMessage &request, PlayerMessage *reply) {
    Mutex::Autolock _l(mLock);
    const bool hasBeenInitialized =
            (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
            ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
    if ((mPlayer == NULL) || !hasBeenInitialized) {
        ALOGE("invoke() failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
        return INVALID_OPERATION;
    }
    return mPlayer->invoke(request, reply);
}

void MediaPlayer2::disconnectNativeWindow_l() {
    if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
        status_t err = native_window_api_disconnect(
                mConnectedWindow->getANativeWindow(), NATIVE_WINDOW_API_MEDIA);

        if (err != OK) {
            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
                  strerror(-err), err);
        }
    }
    mConnectedWindow.clear();
}

status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) {
    ANativeWindow *anw = (nww == NULL ? NULL : nww->getANativeWindow());
    ALOGV("setVideoSurfaceTexture(%p)", anw);
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return NO_INIT;
    }

    if (anw != NULL) {
        if (mConnectedWindow != NULL
            && mConnectedWindow->getANativeWindow() == anw) {
            return OK;
        }
        status_t err = native_window_api_connect(anw, NATIVE_WINDOW_API_MEDIA);

        if (err != OK) {
            ALOGE("setVideoSurfaceTexture failed: %d", err);
            // Note that we must do the reset before disconnecting from the ANW.
            // Otherwise queue/dequeue calls could be made on the disconnected
            // ANW, which may result in errors.
            mPlayer->reset();
            disconnectNativeWindow_l();
            return err;
        }
    }

    // Note that we must set the player's new GraphicBufferProducer before
    // disconnecting the old one.  Otherwise queue/dequeue calls could be made
    // on the disconnected ANW, which may result in errors.
    status_t err = mPlayer->setVideoSurfaceTexture(nww);

    disconnectNativeWindow_l();

    if (err == OK) {
        mConnectedWindow = nww;
        mLock.unlock();
    } else if (anw != NULL) {
        mLock.unlock();
        status_t err = native_window_api_disconnect(anw, NATIVE_WINDOW_API_MEDIA);

        if (err != OK) {
            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
                  strerror(-err), err);
        }
    }

    return err;
}

status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
    ALOGV("getBufferingSettings");

    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return NO_INIT;
    }

    status_t ret = mPlayer->getBufferingSettings(buffering);
    if (ret == NO_ERROR) {
        ALOGV("getBufferingSettings{%s}", buffering->toString().string());
    } else {
        ALOGE("getBufferingSettings returned %d", ret);
    }
    return ret;
}

status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
    ALOGV("setBufferingSettings{%s}", buffering.toString().string());

    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return NO_INIT;
    }
    return mPlayer->setBufferingSettings(buffering);
}

status_t MediaPlayer2::setAudioAttributes_l(const jobject attributes) {
    if (mAudioOutput != NULL) {
        mAudioOutput->setAudioAttributes(attributes);
    }
    return NO_ERROR;
}

status_t MediaPlayer2::prepareAsync() {
    ALOGV("prepareAsync");
    Mutex::Autolock _l(mLock);
    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
        if (mAudioAttributes != NULL) {
            status_t err = setAudioAttributes_l(mAudioAttributes->getJObject());
            if (err != OK) {
                return err;
            }
        }
        mCurrentState = MEDIA_PLAYER2_PREPARING;
        return mPlayer->prepareAsync();
    }
    ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
    return INVALID_OPERATION;
}

status_t MediaPlayer2::start() {
    ALOGV("start");

    status_t ret = NO_ERROR;
    Mutex::Autolock _l(mLock);

    mLockThreadId = getThreadId();

    if (mCurrentState & MEDIA_PLAYER2_STARTED) {
        ret = NO_ERROR;
    } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
                    MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
        mPlayer->setLooping(mLoop);

        if (mAudioOutput != 0) {
            mAudioOutput->setVolume(mVolume);
        }

        if (mAudioOutput != 0) {
            mAudioOutput->setAuxEffectSendLevel(mSendLevel);
        }
        mCurrentState = MEDIA_PLAYER2_STARTED;
        ret = mPlayer->start();
        if (ret != NO_ERROR) {
            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
        } else {
            if (mCurrentState == MEDIA_PLAYER2_PLAYBACK_COMPLETE) {
                ALOGV("playback completed immediately following start()");
            }
        }
    } else {
        ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
        ret = INVALID_OPERATION;
    }

    mLockThreadId = 0;

    return ret;
}

status_t MediaPlayer2::pause() {
    ALOGV("pause");
    Mutex::Autolock _l(mLock);
    if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
        return NO_ERROR;
    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED))) {
        status_t ret = mPlayer->pause();
        if (ret != NO_ERROR) {
            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
        } else {
            mCurrentState = MEDIA_PLAYER2_PAUSED;
        }
        return ret;
    }
    ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
    return INVALID_OPERATION;
}

bool MediaPlayer2::isPlaying() {
    Mutex::Autolock _l(mLock);
    if (mPlayer != 0) {
        bool temp = mPlayer->isPlaying();
        ALOGV("isPlaying: %d", temp);
        if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
            ALOGE("internal/external state mismatch corrected");
            mCurrentState = MEDIA_PLAYER2_PAUSED;
        } else if ((mCurrentState & MEDIA_PLAYER2_PAUSED) && temp) {
            ALOGE("internal/external state mismatch corrected");
            mCurrentState = MEDIA_PLAYER2_STARTED;
        }
        return temp;
    }
    ALOGV("isPlaying: no active player");
    return false;
}

mediaplayer2_states MediaPlayer2::getState() {
    Mutex::Autolock _l(mLock);
    if (mCurrentState & MEDIA_PLAYER2_STATE_ERROR) {
        return MEDIAPLAYER2_STATE_ERROR;
    }
    if (mPlayer == 0
        || (mCurrentState &
            (MEDIA_PLAYER2_IDLE | MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_PREPARING))) {
        return MEDIAPLAYER2_STATE_IDLE;
    }
    if (mCurrentState & MEDIA_PLAYER2_STARTED) {
        return MEDIAPLAYER2_STATE_PLAYING;
    }
    if (mCurrentState & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
        return MEDIAPLAYER2_STATE_PAUSED;
    }
    // now only mCurrentState & MEDIA_PLAYER2_PREPARED is true
    return MEDIAPLAYER2_STATE_PREPARED;
}

status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate) {
    ALOGV("setPlaybackSettings: %f %f %d %d",
            rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
    // Negative speed and pitch does not make sense. Further validation will
    // be done by the respective mediaplayers.
    if (rate.mSpeed <= 0.f || rate.mPitch < 0.f) {
        return BAD_VALUE;
    }
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return INVALID_OPERATION;
    }

    status_t err = mPlayer->setPlaybackSettings(rate);
    return err;
}

status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return INVALID_OPERATION;
    }
    status_t ret = mPlayer->getPlaybackSettings(rate);
    if (ret == NO_ERROR) {
        ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
                rate->mSpeed, rate->mPitch, rate->mFallbackMode, rate->mStretchMode);
    } else {
        ALOGV("getPlaybackSettings returned %d", ret);
    }
    return ret;
}

status_t MediaPlayer2::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) {
    ALOGV("setSyncSettings: %u %u %f %f",
            sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) return INVALID_OPERATION;
    return mPlayer->setSyncSettings(sync, videoFpsHint);
}

status_t MediaPlayer2::getSyncSettings(
        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return INVALID_OPERATION;
    }
    status_t ret = mPlayer->getSyncSettings(sync, videoFps);
    if (ret == NO_ERROR) {
        ALOGV("getSyncSettings(%u, %u, %f, %f)",
                sync->mSource, sync->mAudioAdjustMode, sync->mTolerance, *videoFps);
    } else {
        ALOGV("getSyncSettings returned %d", ret);
    }
    return ret;

}

status_t MediaPlayer2::getVideoWidth(int *w) {
    ALOGV("getVideoWidth");
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return INVALID_OPERATION;
    }
    *w = mVideoWidth;
    return NO_ERROR;
}

status_t MediaPlayer2::getVideoHeight(int *h) {
    ALOGV("getVideoHeight");
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return INVALID_OPERATION;
    }
    *h = mVideoHeight;
    return NO_ERROR;
}

status_t MediaPlayer2::getCurrentPosition(int64_t *msec) {
    ALOGV("getCurrentPosition");
    Mutex::Autolock _l(mLock);
    if (mPlayer == 0) {
        return INVALID_OPERATION;
    }
    if (mCurrentPosition >= 0) {
        ALOGV("Using cached seek position: %lld", (long long)mCurrentPosition);
        *msec = mCurrentPosition;
        return NO_ERROR;
    }
    status_t ret = mPlayer->getCurrentPosition(msec);
    if (ret == NO_ERROR) {
        ALOGV("getCurrentPosition = %lld", (long long)*msec);
    } else {
        ALOGE("getCurrentPosition returned %d", ret);
    }
    return ret;
}

status_t MediaPlayer2::getDuration(int64_t *msec) {
    Mutex::Autolock _l(mLock);
    ALOGV("getDuration_l");
    bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
    if (mPlayer == 0 || !isValidState) {
        ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
                mPlayer.get(), mCurrentState);
        return INVALID_OPERATION;
    }
    int64_t durationMs;
    status_t ret = mPlayer->getDuration(&durationMs);

    if (ret == NO_ERROR) {
        ALOGV("getDuration = %lld", (long long)durationMs);
    } else {
        ALOGE("getDuration returned %d", ret);
        // Do not enter error state just because no duration was available.
        durationMs = -1;
    }

    if (msec) {
        *msec = durationMs;
    }
    return OK;
}

status_t MediaPlayer2::seekTo_l(int64_t msec, MediaPlayer2SeekMode mode) {
    ALOGV("seekTo (%lld, %d)", (long long)msec, mode);
    if ((mPlayer == 0) || !(mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
        ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u",
              mPlayer.get(), mCurrentState);
        return INVALID_OPERATION;
    }
    if (msec < 0) {
        ALOGW("Attempt to seek to invalid position: %lld", (long long)msec);
        msec = 0;
    }

    int64_t durationMs;
    status_t err = mPlayer->getDuration(&durationMs);

    if (err != OK) {
        ALOGW("Stream has no duration and is therefore not seekable.");
        return err;
    }

    if (msec > durationMs) {
        ALOGW("Attempt to seek to past end of file: request = %lld, durationMs = %lld",
              (long long)msec, (long long)durationMs);

        msec = durationMs;
    }

    // cache duration
    mCurrentPosition = msec;
    mCurrentSeekMode = mode;
    if (mSeekPosition < 0) {
        mSeekPosition = msec;
        mSeekMode = mode;
        return mPlayer->seekTo(msec, mode);
    }
    ALOGV("Seek in progress - queue up seekTo[%lld, %d]", (long long)msec, mode);
    return NO_ERROR;
}

status_t MediaPlayer2::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
    mLockThreadId = getThreadId();
    Mutex::Autolock _l(mLock);
    status_t result = seekTo_l(msec, mode);
    mLockThreadId = 0;

    return result;
}

status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs) {
    Mutex::Autolock _l(mLock);
    if (mPlayer != 0) {
        return INVALID_OPERATION;
    }

    return mPlayer->notifyAt(mediaTimeUs);
}

status_t MediaPlayer2::reset_l() {
    mLoop = false;
    if (mCurrentState == MEDIA_PLAYER2_IDLE) {
        return NO_ERROR;
    }
    if (mPlayer != 0) {
        status_t ret = mPlayer->reset();
        if (ret != NO_ERROR) {
            ALOGE("reset() failed with return code (%d)", ret);
            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
        } else {
            mPlayer->setListener(NULL);
            mCurrentState = MEDIA_PLAYER2_IDLE;
        }
        // setDataSource has to be called again to create a
        // new mediaplayer.
        mPlayer = 0;
        return ret;
    }
    clear_l();
    return NO_ERROR;
}

status_t MediaPlayer2::reset() {
    ALOGV("reset");
    mLockThreadId = getThreadId();
    Mutex::Autolock _l(mLock);
    status_t result = reset_l();
    mLockThreadId = 0;

    return result;
}

status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type) {
    ALOGV("MediaPlayer2::setAudioStreamType");
    Mutex::Autolock _l(mLock);
    if (mStreamType == type) return NO_ERROR;
    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
                MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) {
        // Can't change the stream type after prepare
        ALOGE("setAudioStream called in state %d", mCurrentState);
        return INVALID_OPERATION;
    }
    // cache
    mStreamType = type;
    return OK;
}

status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type) {
    ALOGV("getAudioStreamType");
    Mutex::Autolock _l(mLock);
    *type = mStreamType;
    return OK;
}

status_t MediaPlayer2::setLooping(int loop) {
    ALOGV("MediaPlayer2::setLooping");
    Mutex::Autolock _l(mLock);
    mLoop = (loop != 0);
    if (mPlayer != 0) {
        return mPlayer->setLooping(loop);
    }
    return OK;
}

bool MediaPlayer2::isLooping() {
    ALOGV("isLooping");
    Mutex::Autolock _l(mLock);
    if (mPlayer != 0) {
        return mLoop;
    }
    ALOGV("isLooping: no active player");
    return false;
}

status_t MediaPlayer2::setVolume(float volume) {
    ALOGV("MediaPlayer2::setVolume(%f)", volume);
    Mutex::Autolock _l(mLock);
    mVolume = volume;
    if (mAudioOutput != 0) {
        mAudioOutput->setVolume(volume);
    }
    return OK;
}

status_t MediaPlayer2::setAudioSessionId(int32_t sessionId) {
    ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
    Mutex::Autolock _l(mLock);
    if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
        ALOGE("setAudioSessionId called in state %d", mCurrentState);
        return INVALID_OPERATION;
    }
    if (sessionId < 0) {
        return BAD_VALUE;
    }
    if (mAudioOutput != NULL && sessionId != mAudioOutput->getSessionId()) {
        mAudioOutput->setSessionId(sessionId);
    }
    return NO_ERROR;
}

int32_t MediaPlayer2::getAudioSessionId() {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput != NULL) {
        return mAudioOutput->getSessionId();
    }
    return 0;
}

status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
    ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
    Mutex::Autolock _l(mLock);
    mSendLevel = level;
    if (mAudioOutput != 0) {
        return mAudioOutput->setAuxEffectSendLevel(level);
    }
    return OK;
}

status_t MediaPlayer2::attachAuxEffect(int effectId) {
    ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == 0 ||
        (mCurrentState & MEDIA_PLAYER2_IDLE) ||
        (mCurrentState == MEDIA_PLAYER2_STATE_ERROR )) {
        ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
        return INVALID_OPERATION;
    }

    return mAudioOutput->attachAuxEffect(effectId);
}

// always call with lock held
status_t MediaPlayer2::checkState_l() {
    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
        // Can't change the audio attributes after prepare
        ALOGE("trying to set audio attributes called in state %d", mCurrentState);
        return INVALID_OPERATION;
    }
    return OK;
}

status_t MediaPlayer2::setAudioAttributes(const jobject attributes) {
    ALOGV("MediaPlayer2::setAudioAttributes");
    status_t status = INVALID_OPERATION;
    Mutex::Autolock _l(mLock);
    if (checkState_l() != OK) {
        return status;
    }
    mAudioAttributes = new JObjectHolder(attributes);
    status = setAudioAttributes_l(attributes);
    return status;
}

jobject MediaPlayer2::getAudioAttributes() {
    ALOGV("MediaPlayer2::getAudioAttributes)");
    Mutex::Autolock _l(mLock);
    return mAudioAttributes != NULL ? mAudioAttributes->getJObject() : NULL;
}

status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
    ALOGV("MediaPlayer2::getParameter(%d)", key);
    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        ALOGV("getParameter: no active player");
        return INVALID_OPERATION;
    }

    status_t status =  mPlayer->getParameter(key, reply);
    if (status != OK) {
        ALOGD("getParameter returns %d", status);
    }
    return status;
}

void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *obj) {
    ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
          (long long)srcId, msg, ext1, ext2);

    bool send = true;
    bool locked = false;

    // TODO: In the future, we might be on the same thread if the app is
    // running in the same process as the media server. In that case,
    // this will deadlock.
    //
    // The threadId hack below works around this for the care of prepare,
    // seekTo, start, and reset within the same process.
    // FIXME: Remember, this is a hack, it's not even a hack that is applied
    // consistently for all use-cases, this needs to be revisited.
    if (mLockThreadId != getThreadId()) {
        mLock.lock();
        locked = true;
    }

    // Allows calls from JNI in idle state to notify errors
    if (!(msg == MEDIA2_ERROR && mCurrentState == MEDIA_PLAYER2_IDLE) && mPlayer == 0) {
        ALOGV("notify(%lld, %d, %d, %d) callback on disconnected mediaplayer",
              (long long)srcId, msg, ext1, ext2);
        if (locked) mLock.unlock();   // release the lock when done.
        return;
    }

    switch (msg) {
    case MEDIA2_NOP: // interface test message
        break;
    case MEDIA2_PREPARED:
        ALOGV("MediaPlayer2::notify() prepared");
        mCurrentState = MEDIA_PLAYER2_PREPARED;
        break;
    case MEDIA2_DRM_INFO:
        ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
              (long long)srcId, msg, ext1, ext2, obj);
        break;
    case MEDIA2_PLAYBACK_COMPLETE:
        ALOGV("playback complete");
        if (mCurrentState == MEDIA_PLAYER2_IDLE) {
            ALOGE("playback complete in idle state");
        }
        if (!mLoop) {
            mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
        }
        break;
    case MEDIA2_ERROR:
        // Always log errors.
        // ext1: Media framework error code.
        // ext2: Implementation dependant error code.
        ALOGE("error (%d, %d)", ext1, ext2);
        mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
        break;
    case MEDIA2_INFO:
        // ext1: Media framework error code.
        // ext2: Implementation dependant error code.
        if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
            ALOGW("info/warning (%d, %d)", ext1, ext2);
        }
        break;
    case MEDIA2_SEEK_COMPLETE:
        ALOGV("Received seek complete");
        if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
            ALOGV("Executing queued seekTo(%lld, %d)",
                  (long long)mCurrentPosition, mCurrentSeekMode);
            mSeekPosition = -1;
            mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
            seekTo_l(mCurrentPosition, mCurrentSeekMode);
        }
        else {
            ALOGV("All seeks complete - return to regularly scheduled program");
            mCurrentPosition = mSeekPosition = -1;
            mCurrentSeekMode = mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
        }
        break;
    case MEDIA2_BUFFERING_UPDATE:
        ALOGV("buffering %d", ext1);
        break;
    case MEDIA2_SET_VIDEO_SIZE:
        ALOGV("New video size %d x %d", ext1, ext2);
        mVideoWidth = ext1;
        mVideoHeight = ext2;
        break;
    case MEDIA2_NOTIFY_TIME:
        ALOGV("Received notify time message");
        break;
    case MEDIA2_TIMED_TEXT:
        ALOGV("Received timed text message");
        break;
    case MEDIA2_SUBTITLE_DATA:
        ALOGV("Received subtitle data message");
        break;
    case MEDIA2_META_DATA:
        ALOGV("Received timed metadata message");
        break;
    default:
        ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
        break;
    }

    sp<MediaPlayer2Listener> listener = mListener;
    if (locked) mLock.unlock();

    // this prevents re-entrant calls into client code
    if ((listener != 0) && send) {
        Mutex::Autolock _l(mNotifyLock);
        ALOGV("callback application");
        listener->notify(srcId, msg, ext1, ext2, obj);
        ALOGV("back from callback");
    }
}

// Modular DRM
status_t MediaPlayer2::prepareDrm(
        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
    // TODO change to ALOGV
    ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
            drmSessionId.array(), drmSessionId.size());
    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        return NO_INIT;
    }

    // Only allowed it in player's preparing/prepared state.
    // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
    // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
    // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
    if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
        ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState);
        return INVALID_OPERATION;
    }

    if (drmSessionId.isEmpty()) {
        ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
        return INVALID_OPERATION;
    }

    // Passing down to mediaserver mainly for creating the crypto
    status_t status = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
    ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);

    // TODO change to ALOGV
    ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);

    return status;
}

status_t MediaPlayer2::releaseDrm(int64_t srcId) {
    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        return NO_INIT;
    }

    // Not allowing releaseDrm in an active/resumable state
    if (mCurrentState & (MEDIA_PLAYER2_STARTED |
                         MEDIA_PLAYER2_PAUSED |
                         MEDIA_PLAYER2_PLAYBACK_COMPLETE |
                         MEDIA_PLAYER2_STATE_ERROR)) {
        ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
        return INVALID_OPERATION;
    }

    status_t status = mPlayer->releaseDrm(srcId);
    // TODO change to ALOGV
    ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
    if (status != OK) {
        ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
        // Overriding to OK so the client proceed with its own cleanup
        // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
        status = OK;
    }

    return status;
}

status_t MediaPlayer2::setPreferredDevice(jobject device) {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == NULL) {
        ALOGV("setPreferredDevice: audio sink not init");
        return NO_INIT;
    }
    return mAudioOutput->setPreferredDevice(device);
}

jobject MediaPlayer2::getRoutedDevice() {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == NULL) {
        ALOGV("getRoutedDevice: audio sink not init");
        return nullptr;
    }
    return mAudioOutput->getRoutedDevice();
}

status_t MediaPlayer2::addAudioDeviceCallback(jobject routingDelegate) {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == NULL) {
        ALOGV("addAudioDeviceCallback: player not init");
        return NO_INIT;
    }
    return mAudioOutput->addAudioDeviceCallback(routingDelegate);
}

status_t MediaPlayer2::removeAudioDeviceCallback(jobject listener) {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == NULL) {
        ALOGV("addAudioDeviceCallback: player not init");
        return NO_INIT;
    }
    return mAudioOutput->removeAudioDeviceCallback(listener);
}

status_t MediaPlayer2::dump(int fd, const Vector<String16>& args) {
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    result.append(" MediaPlayer2\n");
    snprintf(buffer, 255, "  pid(%d), looping(%s)\n", mPid, mLoop?"true": "false");
    result.append(buffer);

    sp<MediaPlayer2Interface> player;
    sp<MediaPlayer2AudioOutput> audioOutput;
    bool locked = false;
    for (int i = 0; i < kDumpLockRetries; ++i) {
        if (mLock.tryLock() == NO_ERROR) {
            locked = true;
            break;
        }
        usleep(kDumpLockSleepUs);
    }

    if (locked) {
        player = mPlayer;
        audioOutput = mAudioOutput;
        mLock.unlock();
    } else {
        result.append("  lock is taken, no dump from player and audio output\n");
    }
    write(fd, result.string(), result.size());

    if (player != NULL) {
        player->dump(fd, args);
    }
    if (audioOutput != 0) {
        audioOutput->dump(fd, args);
    }
    write(fd, "\n", 1);
    return NO_ERROR;
}

} // namespace android
