/*
 * Copyright (C) 2011 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 USE_LOG SLAndroidLogLevel_Verbose

#include "sles_allinclusive.h"
#include <media/IMediaPlayerService.h>
#include "android_LocAVPlayer.h"


namespace android {

//--------------------------------------------------------------------------------------------------
LocAVPlayer::LocAVPlayer(const AudioPlayback_Parameters* params, bool hasVideo) :
        GenericMediaPlayer(params, hasVideo)
{
    SL_LOGD("LocAVPlayer::LocAVPlayer()");

}


LocAVPlayer::~LocAVPlayer() {
    SL_LOGD("LocAVPlayer::~LocAVPlayer()");

}


//--------------------------------------------------
// Event handlers
void LocAVPlayer::onPrepare() {
    SL_LOGD("LocAVPlayer::onPrepare()");
    sp<IMediaPlayerService> mediaPlayerService(getMediaPlayerService());
    if (mediaPlayerService != NULL) {
        switch (mDataLocatorType) {
        case kDataLocatorUri:
            mPlayer = mediaPlayerService->create(mPlayerClient /*IMediaPlayerClient*/,
                    mPlaybackParams.sessionId);
            if (mPlayer == NULL) {
                SL_LOGE("media player service failed to create player by URI");
            } else if (mPlayer->setDataSource(mDataLocator.uriRef, NULL /*headers*/) != NO_ERROR) {
                SL_LOGE("setDataSource failed");
                mPlayer.clear();
            }
            break;
        case kDataLocatorFd:
            mPlayer = mediaPlayerService->create(mPlayerClient /*IMediaPlayerClient*/,
                    mPlaybackParams.sessionId);
            if (mPlayer == NULL) {
                SL_LOGE("media player service failed to create player by FD");
            } else if (mPlayer->setDataSource(mDataLocator.fdi.fd, mDataLocator.fdi.offset,
                    mDataLocator.fdi.length) != NO_ERROR) {
                SL_LOGE("setDataSource failed");
                mPlayer.clear();
            }
            // Binder dups the fd for use by mediaserver, so if we own the fd then OK to close now
            if (mDataLocator.fdi.mCloseAfterUse) {
                (void) ::close(mDataLocator.fdi.fd);
                mDataLocator.fdi.fd = -1;
                mDataLocator.fdi.mCloseAfterUse = false;
            }
            break;
        case kDataLocatorNone:
            SL_LOGE("no data locator for MediaPlayer object");
            break;
        default:
            SL_LOGE("unsupported data locator %d for MediaPlayer object", mDataLocatorType);
            break;
        }
    }
    if (mPlayer == NULL) {
        mStateFlags |= kFlagPreparedUnsuccessfully;
    }
    // blocks until mPlayer is prepared
    GenericMediaPlayer::onPrepare();
    SL_LOGD("LocAVPlayer::onPrepare() done");
}

} // namespace android
