/*
**
** 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;

// marshalling tag indicating flattened utf16 tags
// keep in sync with frameworks/base/media/java/android/media/AudioAttributes.java
const int32_t kAudioAttributesMarshallTagFlattenTags = 1;

// Audio attributes format in a parcel:
//
//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                       usage                                   |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                       content_type                            |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                       source                                  |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                       flags                                   |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                       kAudioAttributesMarshallTagFlattenTags  | // ignore tags if not found
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                       flattened tags in UTF16                 |
// |                         ...                                   |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// @param p Parcel that contains audio attributes.
// @param[out] attributes On exit points to an initialized audio_attributes_t structure
// @param[out] status On exit contains the status code to be returned.
void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attributes) {
    attributes->usage = (audio_usage_t) parcel.readInt32();
    attributes->content_type = (audio_content_type_t) parcel.readInt32();
    attributes->source = (audio_source_t) parcel.readInt32();
    attributes->flags = (audio_flags_mask_t) parcel.readInt32();
    const bool hasFlattenedTag = (parcel.readInt32() == kAudioAttributesMarshallTagFlattenTags);
    if (hasFlattenedTag) {
        // the tags are UTF16, convert to UTF8
        String16 tags = parcel.readString16();
        ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size());
        if (realTagSize <= 0) {
            strcpy(attributes->tags, "");
        } else {
            // copy the flattened string into the attributes as the destination for the conversion:
            // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
            size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
                    AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
            utf16_to_utf8(tags.string(), tagSize, attributes->tags,
                    sizeof(attributes->tags) / sizeof(attributes->tags[0]));
        }
    } else {
        ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");
        strcpy(attributes->tags, "");
    }
}

class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback {
public:
    AudioDeviceUpdatedNotifier(const sp<MediaPlayer2Interface>& listener)
        : mListener(listener) { }

    ~AudioDeviceUpdatedNotifier() { }

    virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
                                     audio_port_handle_t deviceId) override {
        sp<MediaPlayer2Interface> listener = mListener.promote();
        if (listener != NULL) {
            listener->sendEvent(0, MEDIA2_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
        } else {
            ALOGW("listener for process %d death is gone", MEDIA2_AUDIO_ROUTING_CHANGED);
        }
    }

private:
    wp<MediaPlayer2Interface> mListener;
};

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() {
    sp<MediaPlayer2> player = new MediaPlayer2();

    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() {
    ALOGV("constructor");
    mSrcId = 0;
    mLockThreadId = 0;
    mListener = NULL;
    mStreamType = AUDIO_STREAM_MUSIC;
    mAudioAttributesParcel = NULL;
    mCurrentPosition = -1;
    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
    mSeekPosition = -1;
    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
    mCurrentState = MEDIA_PLAYER2_IDLE;
    mLoop = false;
    mLeftVolume = mRightVolume = 1.0;
    mVideoWidth = mVideoHeight = 0;
    mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
    AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
    mSendLevel = 0;

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

    mAudioAttributes = NULL;
}

MediaPlayer2::~MediaPlayer2() {
    ALOGV("destructor");
    if (mAudioAttributesParcel != NULL) {
        delete mAudioAttributesParcel;
        mAudioAttributesParcel = NULL;
    }
    AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
    disconnect();
    removePlayer(this);
    if (mAudioAttributes != NULL) {
        free(mAudioAttributes);
    }
}

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;
    }
    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));
        mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid,
                mPid, mAudioAttributes, new AudioDeviceUpdatedNotifier(player));
        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 Parcel &parcel) {
    if (mAudioAttributes != NULL) {
        free(mAudioAttributes);
    }
    mAudioAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
    if (mAudioAttributes == NULL) {
        return NO_MEMORY;
    }
    unmarshallAudioAttributes(parcel, mAudioAttributes);

    ALOGV("setAudioAttributes_l() usage=%d content=%d flags=0x%x tags=%s",
            mAudioAttributes->usage, mAudioAttributes->content_type, mAudioAttributes->flags,
            mAudioAttributes->tags);

    if (mAudioOutput != 0) {
        mAudioOutput->setAudioAttributes(mAudioAttributes);
    }
    return NO_ERROR;
}

status_t MediaPlayer2::prepareAsync() {
    ALOGV("prepareAsync");
    Mutex::Autolock _l(mLock);
    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
        if (mAudioAttributesParcel != NULL) {
            status_t err = setAudioAttributes_l(*mAudioAttributesParcel);
            if (err != OK) {
                return err;
            }
        } else if (mAudioOutput != 0) {
            mAudioOutput->setAudioStreamType(mStreamType);
        }
        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(mLeftVolume, mRightVolume);
        }

        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 leftVolume, float rightVolume) {
    ALOGV("MediaPlayer2::setVolume(%f, %f)", leftVolume, rightVolume);
    Mutex::Autolock _l(mLock);
    mLeftVolume = leftVolume;
    mRightVolume = rightVolume;
    if (mAudioOutput != 0) {
        mAudioOutput->setVolume(leftVolume, rightVolume);
    }
    return OK;
}

status_t MediaPlayer2::setAudioSessionId(audio_session_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 (sessionId != mAudioSessionId) {
        AudioSystem::acquireAudioSessionId(sessionId, -1);
        AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
        mAudioSessionId = sessionId;
    }
    return NO_ERROR;
}

audio_session_t MediaPlayer2::getAudioSessionId() {
    Mutex::Autolock _l(mLock);
    return mAudioSessionId;
}

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::checkStateForKeySet_l(int key) {
    switch(key) {
    case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
        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;
        }
        break;
    default:
        // parameter doesn't require player state check
        break;
    }
    return OK;
}

status_t MediaPlayer2::setParameter(int key, const Parcel& request) {
    ALOGV("MediaPlayer2::setParameter(%d)", key);
    status_t status = INVALID_OPERATION;
    Mutex::Autolock _l(mLock);
    if (checkStateForKeySet_l(key) != OK) {
        return status;
    }
    switch (key) {
    case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
        // save the marshalled audio attributes
        if (mAudioAttributesParcel != NULL) {
            delete mAudioAttributesParcel;
        }
        mAudioAttributesParcel = new Parcel();
        mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
        status = setAudioAttributes_l(request);
        if (status != OK) {
            return status;
        }
        break;
    default:
        ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
        break;
    }

    if (mPlayer != NULL) {
        status = mPlayer->setParameter(key, request);
    }
    return status;
}

status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
    ALOGV("MediaPlayer2::getParameter(%d)", key);
    Mutex::Autolock _l(mLock);
    if (key == MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES) {
        if (reply == NULL) {
            return BAD_VALUE;
        }
        if (mAudioAttributesParcel != NULL) {
            reply->appendFrom(mAudioAttributesParcel, 0, mAudioAttributesParcel->dataSize());
        }
        return OK;
    }

    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(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(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() {
    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();
    // 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::setOutputDevice(audio_port_handle_t deviceId) {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == NULL) {
        ALOGV("setOutputDevice: audio sink not init");
        return NO_INIT;
    }
    return mAudioOutput->setOutputDevice(deviceId);
}

audio_port_handle_t MediaPlayer2::getRoutedDeviceId() {
    Mutex::Autolock _l(mLock);
    if (mAudioOutput == NULL) {
        ALOGV("getRoutedDeviceId: audio sink not init");
        return AUDIO_PORT_HANDLE_NONE;
    }
    audio_port_handle_t deviceId;
    status_t status = mAudioOutput->getRoutedDeviceId(&deviceId);
    if (status != NO_ERROR) {
        return AUDIO_PORT_HANDLE_NONE;
    }
    return deviceId;
}

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

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
