1/*
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "MediaPlayerNative"
20
21#include <fcntl.h>
22#include <inttypes.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <unistd.h>
26
27#include <utils/Log.h>
28
29#include <binder/IServiceManager.h>
30#include <binder/IPCThreadState.h>
31
32#include <gui/Surface.h>
33
34#include <media/mediaplayer.h>
35#include <media/AudioResamplerPublic.h>
36#include <media/AudioSystem.h>
37#include <media/AVSyncSettings.h>
38#include <media/IDataSource.h>
39#include <media/MediaAnalyticsItem.h>
40
41#include <binder/MemoryBase.h>
42
43#include <utils/KeyedVector.h>
44#include <utils/String8.h>
45
46#include <system/audio.h>
47#include <system/window.h>
48
49namespace android {
50
51MediaPlayer::MediaPlayer()
52{
53    ALOGV("constructor");
54    mListener = NULL;
55    mCookie = NULL;
56    mStreamType = AUDIO_STREAM_MUSIC;
57    mAudioAttributesParcel = NULL;
58    mCurrentPosition = -1;
59    mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
60    mSeekPosition = -1;
61    mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
62    mCurrentState = MEDIA_PLAYER_IDLE;
63    mPrepareSync = false;
64    mPrepareStatus = NO_ERROR;
65    mLoop = false;
66    mLeftVolume = mRightVolume = 1.0;
67    mVideoWidth = mVideoHeight = 0;
68    mLockThreadId = 0;
69    mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
70    AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
71    mSendLevel = 0;
72    mRetransmitEndpointValid = false;
73}
74
75MediaPlayer::~MediaPlayer()
76{
77    ALOGV("destructor");
78    if (mAudioAttributesParcel != NULL) {
79        delete mAudioAttributesParcel;
80        mAudioAttributesParcel = NULL;
81    }
82    AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
83    disconnect();
84    IPCThreadState::self()->flushCommands();
85}
86
87void MediaPlayer::disconnect()
88{
89    ALOGV("disconnect");
90    sp<IMediaPlayer> p;
91    {
92        Mutex::Autolock _l(mLock);
93        p = mPlayer;
94        mPlayer.clear();
95    }
96
97    if (p != 0) {
98        p->disconnect();
99    }
100}
101
102// always call with lock held
103void MediaPlayer::clear_l()
104{
105    mCurrentPosition = -1;
106    mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
107    mSeekPosition = -1;
108    mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
109    mVideoWidth = mVideoHeight = 0;
110    mRetransmitEndpointValid = false;
111}
112
113status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
114{
115    ALOGV("setListener");
116    Mutex::Autolock _l(mLock);
117    mListener = listener;
118    return NO_ERROR;
119}
120
121
122status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)
123{
124    status_t err = UNKNOWN_ERROR;
125    sp<IMediaPlayer> p;
126    { // scope for the lock
127        Mutex::Autolock _l(mLock);
128
129        if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
130                (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
131            ALOGE("attachNewPlayer called in state %d", mCurrentState);
132            return INVALID_OPERATION;
133        }
134
135        clear_l();
136        p = mPlayer;
137        mPlayer = player;
138        if (player != 0) {
139            mCurrentState = MEDIA_PLAYER_INITIALIZED;
140            player->getDefaultBufferingSettings(&mCurrentBufferingSettings);
141            err = NO_ERROR;
142        } else {
143            mCurrentBufferingSettings = BufferingSettings();
144            ALOGE("Unable to create media player");
145        }
146    }
147
148    if (p != 0) {
149        p->disconnect();
150    }
151
152    return err;
153}
154
155status_t MediaPlayer::setDataSource(
156        const sp<IMediaHTTPService> &httpService,
157        const char *url, const KeyedVector<String8, String8> *headers)
158{
159    ALOGV("setDataSource(%s)", url);
160    status_t err = BAD_VALUE;
161    if (url != NULL) {
162        const sp<IMediaPlayerService> service(getMediaPlayerService());
163        if (service != 0) {
164            sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
165            if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
166                (NO_ERROR != player->setDataSource(httpService, url, headers))) {
167                player.clear();
168            }
169            err = attachNewPlayer(player);
170        }
171    }
172    return err;
173}
174
175status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
176{
177    ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
178    status_t err = UNKNOWN_ERROR;
179    const sp<IMediaPlayerService> service(getMediaPlayerService());
180    if (service != 0) {
181        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
182        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
183            (NO_ERROR != player->setDataSource(fd, offset, length))) {
184            player.clear();
185        }
186        err = attachNewPlayer(player);
187    }
188    return err;
189}
190
191status_t MediaPlayer::setDataSource(const sp<IDataSource> &source)
192{
193    ALOGV("setDataSource(IDataSource)");
194    status_t err = UNKNOWN_ERROR;
195    const sp<IMediaPlayerService> service(getMediaPlayerService());
196    if (service != 0) {
197        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
198        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
199            (NO_ERROR != player->setDataSource(source))) {
200            player.clear();
201        }
202        err = attachNewPlayer(player);
203    }
204    return err;
205}
206
207status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
208{
209    Mutex::Autolock _l(mLock);
210    const bool hasBeenInitialized =
211            (mCurrentState != MEDIA_PLAYER_STATE_ERROR) &&
212            ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE);
213    if ((mPlayer != NULL) && hasBeenInitialized) {
214        ALOGV("invoke %zu", request.dataSize());
215        return  mPlayer->invoke(request, reply);
216    }
217    ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
218    return INVALID_OPERATION;
219}
220
221status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
222{
223    ALOGD("setMetadataFilter");
224    Mutex::Autolock lock(mLock);
225    if (mPlayer == NULL) {
226        return NO_INIT;
227    }
228    return mPlayer->setMetadataFilter(filter);
229}
230
231status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
232{
233    ALOGD("getMetadata");
234    Mutex::Autolock lock(mLock);
235    if (mPlayer == NULL) {
236        return NO_INIT;
237    }
238    return mPlayer->getMetadata(update_only, apply_filter, metadata);
239}
240
241status_t MediaPlayer::setVideoSurfaceTexture(
242        const sp<IGraphicBufferProducer>& bufferProducer)
243{
244    ALOGV("setVideoSurfaceTexture");
245    Mutex::Autolock _l(mLock);
246    if (mPlayer == 0) return NO_INIT;
247    return mPlayer->setVideoSurfaceTexture(bufferProducer);
248}
249
250status_t MediaPlayer::getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */)
251{
252    ALOGV("getDefaultBufferingSettings");
253
254    Mutex::Autolock _l(mLock);
255    if (mPlayer == 0) {
256        return NO_INIT;
257    }
258    return mPlayer->getDefaultBufferingSettings(buffering);
259}
260
261status_t MediaPlayer::getBufferingSettings(BufferingSettings* buffering /* nonnull */)
262{
263    ALOGV("getBufferingSettings");
264
265    Mutex::Autolock _l(mLock);
266    if (mPlayer == 0) {
267        return NO_INIT;
268    }
269    *buffering = mCurrentBufferingSettings;
270    return NO_ERROR;
271}
272
273status_t MediaPlayer::setBufferingSettings(const BufferingSettings& buffering)
274{
275    ALOGV("setBufferingSettings");
276
277    Mutex::Autolock _l(mLock);
278    if (mPlayer == 0) {
279        return NO_INIT;
280    }
281    status_t err =  mPlayer->setBufferingSettings(buffering);
282    if (err == NO_ERROR) {
283        mCurrentBufferingSettings = buffering;
284    }
285    return err;
286}
287
288// must call with lock held
289status_t MediaPlayer::prepareAsync_l()
290{
291    if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
292        if (mAudioAttributesParcel != NULL) {
293            mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel);
294        } else {
295            mPlayer->setAudioStreamType(mStreamType);
296        }
297        mCurrentState = MEDIA_PLAYER_PREPARING;
298        return mPlayer->prepareAsync();
299    }
300    ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
301    return INVALID_OPERATION;
302}
303
304// TODO: In case of error, prepareAsync provides the caller with 2 error codes,
305// one defined in the Android framework and one provided by the implementation
306// that generated the error. The sync version of prepare returns only 1 error
307// code.
308status_t MediaPlayer::prepare()
309{
310    ALOGV("prepare");
311    Mutex::Autolock _l(mLock);
312    mLockThreadId = getThreadId();
313    if (mPrepareSync) {
314        mLockThreadId = 0;
315        return -EALREADY;
316    }
317    mPrepareSync = true;
318    status_t ret = prepareAsync_l();
319    if (ret != NO_ERROR) {
320        mLockThreadId = 0;
321        return ret;
322    }
323
324    if (mPrepareSync) {
325        mSignal.wait(mLock);  // wait for prepare done
326        mPrepareSync = false;
327    }
328    ALOGV("prepare complete - status=%d", mPrepareStatus);
329    mLockThreadId = 0;
330    return mPrepareStatus;
331}
332
333status_t MediaPlayer::prepareAsync()
334{
335    ALOGV("prepareAsync");
336    Mutex::Autolock _l(mLock);
337    return prepareAsync_l();
338}
339
340status_t MediaPlayer::start()
341{
342    ALOGV("start");
343
344    status_t ret = NO_ERROR;
345    Mutex::Autolock _l(mLock);
346
347    mLockThreadId = getThreadId();
348
349    if (mCurrentState & MEDIA_PLAYER_STARTED) {
350        ret = NO_ERROR;
351    } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
352                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
353        mPlayer->setLooping(mLoop);
354        mPlayer->setVolume(mLeftVolume, mRightVolume);
355        mPlayer->setAuxEffectSendLevel(mSendLevel);
356        mCurrentState = MEDIA_PLAYER_STARTED;
357        ret = mPlayer->start();
358        if (ret != NO_ERROR) {
359            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
360        } else {
361            if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
362                ALOGV("playback completed immediately following start()");
363            }
364        }
365    } else {
366        ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
367        ret = INVALID_OPERATION;
368    }
369
370    mLockThreadId = 0;
371
372    return ret;
373}
374
375status_t MediaPlayer::stop()
376{
377    ALOGV("stop");
378    Mutex::Autolock _l(mLock);
379    if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
380    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
381                    MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
382        status_t ret = mPlayer->stop();
383        if (ret != NO_ERROR) {
384            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
385        } else {
386            mCurrentState = MEDIA_PLAYER_STOPPED;
387        }
388        return ret;
389    }
390    ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
391    return INVALID_OPERATION;
392}
393
394status_t MediaPlayer::pause()
395{
396    ALOGV("pause");
397    Mutex::Autolock _l(mLock);
398    if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE))
399        return NO_ERROR;
400    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
401        status_t ret = mPlayer->pause();
402        if (ret != NO_ERROR) {
403            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
404        } else {
405            mCurrentState = MEDIA_PLAYER_PAUSED;
406        }
407        return ret;
408    }
409    ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
410    return INVALID_OPERATION;
411}
412
413bool MediaPlayer::isPlaying()
414{
415    Mutex::Autolock _l(mLock);
416    if (mPlayer != 0) {
417        bool temp = false;
418        mPlayer->isPlaying(&temp);
419        ALOGV("isPlaying: %d", temp);
420        if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) {
421            ALOGE("internal/external state mismatch corrected");
422            mCurrentState = MEDIA_PLAYER_PAUSED;
423        } else if ((mCurrentState & MEDIA_PLAYER_PAUSED) && temp) {
424            ALOGE("internal/external state mismatch corrected");
425            mCurrentState = MEDIA_PLAYER_STARTED;
426        }
427        return temp;
428    }
429    ALOGV("isPlaying: no active player");
430    return false;
431}
432
433status_t MediaPlayer::setPlaybackSettings(const AudioPlaybackRate& rate)
434{
435    ALOGV("setPlaybackSettings: %f %f %d %d",
436            rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
437    // Negative speed and pitch does not make sense. Further validation will
438    // be done by the respective mediaplayers.
439    if (rate.mSpeed < 0.f || rate.mPitch < 0.f) {
440        return BAD_VALUE;
441    }
442    Mutex::Autolock _l(mLock);
443    if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER_STOPPED)) {
444        return INVALID_OPERATION;
445    }
446
447    if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER_STARTED)
448            && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED
449                    | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
450        mPlayer->setLooping(mLoop);
451        mPlayer->setVolume(mLeftVolume, mRightVolume);
452        mPlayer->setAuxEffectSendLevel(mSendLevel);
453    }
454
455    status_t err = mPlayer->setPlaybackSettings(rate);
456    if (err == OK) {
457        if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) {
458            mCurrentState = MEDIA_PLAYER_PAUSED;
459        } else if (rate.mSpeed != 0.f
460                && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED
461                    | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
462            mCurrentState = MEDIA_PLAYER_STARTED;
463        }
464    }
465    return err;
466}
467
468status_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
469{
470    Mutex::Autolock _l(mLock);
471    if (mPlayer == 0) return INVALID_OPERATION;
472    return mPlayer->getPlaybackSettings(rate);
473}
474
475status_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
476{
477    ALOGV("setSyncSettings: %u %u %f %f",
478            sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
479    Mutex::Autolock _l(mLock);
480    if (mPlayer == 0) return INVALID_OPERATION;
481    return mPlayer->setSyncSettings(sync, videoFpsHint);
482}
483
484status_t MediaPlayer::getSyncSettings(
485        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
486{
487    Mutex::Autolock _l(mLock);
488    if (mPlayer == 0) return INVALID_OPERATION;
489    return mPlayer->getSyncSettings(sync, videoFps);
490}
491
492status_t MediaPlayer::getVideoWidth(int *w)
493{
494    ALOGV("getVideoWidth");
495    Mutex::Autolock _l(mLock);
496    if (mPlayer == 0) return INVALID_OPERATION;
497    *w = mVideoWidth;
498    return NO_ERROR;
499}
500
501status_t MediaPlayer::getVideoHeight(int *h)
502{
503    ALOGV("getVideoHeight");
504    Mutex::Autolock _l(mLock);
505    if (mPlayer == 0) return INVALID_OPERATION;
506    *h = mVideoHeight;
507    return NO_ERROR;
508}
509
510status_t MediaPlayer::getCurrentPosition(int *msec)
511{
512    ALOGV("getCurrentPosition");
513    Mutex::Autolock _l(mLock);
514    if (mPlayer != 0) {
515        if (mCurrentPosition >= 0) {
516            ALOGV("Using cached seek position: %d", mCurrentPosition);
517            *msec = mCurrentPosition;
518            return NO_ERROR;
519        }
520        return mPlayer->getCurrentPosition(msec);
521    }
522    return INVALID_OPERATION;
523}
524
525status_t MediaPlayer::getDuration_l(int *msec)
526{
527    ALOGV("getDuration_l");
528    bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
529            MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
530    if (mPlayer != 0 && isValidState) {
531        int durationMs;
532        status_t ret = mPlayer->getDuration(&durationMs);
533
534        if (ret != OK) {
535            // Do not enter error state just because no duration was available.
536            durationMs = -1;
537            ret = OK;
538        }
539
540        if (msec) {
541            *msec = durationMs;
542        }
543        return ret;
544    }
545    ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
546            mPlayer.get(), mCurrentState);
547    return INVALID_OPERATION;
548}
549
550status_t MediaPlayer::getDuration(int *msec)
551{
552    Mutex::Autolock _l(mLock);
553    return getDuration_l(msec);
554}
555
556status_t MediaPlayer::seekTo_l(int msec, MediaPlayerSeekMode mode)
557{
558    ALOGV("seekTo (%d, %d)", msec, mode);
559    if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
560            MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
561        if ( msec < 0 ) {
562            ALOGW("Attempt to seek to invalid position: %d", msec);
563            msec = 0;
564        }
565
566        int durationMs;
567        status_t err = mPlayer->getDuration(&durationMs);
568
569        if (err != OK) {
570            ALOGW("Stream has no duration and is therefore not seekable.");
571            return err;
572        }
573
574        if (msec > durationMs) {
575            ALOGW("Attempt to seek to past end of file: request = %d, "
576                  "durationMs = %d",
577                  msec,
578                  durationMs);
579
580            msec = durationMs;
581        }
582
583        // cache duration
584        mCurrentPosition = msec;
585        mCurrentSeekMode = mode;
586        if (mSeekPosition < 0) {
587            mSeekPosition = msec;
588            mSeekMode = mode;
589            return mPlayer->seekTo(msec, mode);
590        }
591        else {
592            ALOGV("Seek in progress - queue up seekTo[%d, %d]", msec, mode);
593            return NO_ERROR;
594        }
595    }
596    ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(),
597            mCurrentState);
598    return INVALID_OPERATION;
599}
600
601status_t MediaPlayer::seekTo(int msec, MediaPlayerSeekMode mode)
602{
603    mLockThreadId = getThreadId();
604    Mutex::Autolock _l(mLock);
605    status_t result = seekTo_l(msec, mode);
606    mLockThreadId = 0;
607
608    return result;
609}
610
611status_t MediaPlayer::reset_l()
612{
613    mLoop = false;
614    if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
615    mPrepareSync = false;
616    if (mPlayer != 0) {
617        status_t ret = mPlayer->reset();
618        if (ret != NO_ERROR) {
619            ALOGE("reset() failed with return code (%d)", ret);
620            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
621        } else {
622            mPlayer->disconnect();
623            mCurrentState = MEDIA_PLAYER_IDLE;
624        }
625        // setDataSource has to be called again to create a
626        // new mediaplayer.
627        mPlayer = 0;
628        mCurrentBufferingSettings = BufferingSettings();
629        return ret;
630    }
631    clear_l();
632    return NO_ERROR;
633}
634
635status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) {
636    Mutex::Autolock _l(mLock);
637
638    if (player == NULL) {
639        return UNKNOWN_ERROR;
640    }
641
642    if (mRetransmitEndpointValid) {
643        return player->setRetransmitEndpoint(&mRetransmitEndpoint);
644    }
645
646    return OK;
647}
648
649status_t MediaPlayer::reset()
650{
651    ALOGV("reset");
652    Mutex::Autolock _l(mLock);
653    return reset_l();
654}
655
656status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type)
657{
658    ALOGV("MediaPlayer::setAudioStreamType");
659    Mutex::Autolock _l(mLock);
660    if (mStreamType == type) return NO_ERROR;
661    if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
662                MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) {
663        // Can't change the stream type after prepare
664        ALOGE("setAudioStream called in state %d", mCurrentState);
665        return INVALID_OPERATION;
666    }
667    // cache
668    mStreamType = type;
669    return OK;
670}
671
672status_t MediaPlayer::getAudioStreamType(audio_stream_type_t *type)
673{
674    ALOGV("getAudioStreamType");
675    Mutex::Autolock _l(mLock);
676    *type = mStreamType;
677    return OK;
678}
679
680status_t MediaPlayer::setLooping(int loop)
681{
682    ALOGV("MediaPlayer::setLooping");
683    Mutex::Autolock _l(mLock);
684    mLoop = (loop != 0);
685    if (mPlayer != 0) {
686        return mPlayer->setLooping(loop);
687    }
688    return OK;
689}
690
691bool MediaPlayer::isLooping() {
692    ALOGV("isLooping");
693    Mutex::Autolock _l(mLock);
694    if (mPlayer != 0) {
695        return mLoop;
696    }
697    ALOGV("isLooping: no active player");
698    return false;
699}
700
701status_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
702{
703    ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume);
704    Mutex::Autolock _l(mLock);
705    mLeftVolume = leftVolume;
706    mRightVolume = rightVolume;
707    if (mPlayer != 0) {
708        return mPlayer->setVolume(leftVolume, rightVolume);
709    }
710    return OK;
711}
712
713status_t MediaPlayer::setAudioSessionId(audio_session_t sessionId)
714{
715    ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
716    Mutex::Autolock _l(mLock);
717    if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
718        ALOGE("setAudioSessionId called in state %d", mCurrentState);
719        return INVALID_OPERATION;
720    }
721    if (sessionId < 0) {
722        return BAD_VALUE;
723    }
724    if (sessionId != mAudioSessionId) {
725        AudioSystem::acquireAudioSessionId(sessionId, -1);
726        AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
727        mAudioSessionId = sessionId;
728    }
729    return NO_ERROR;
730}
731
732audio_session_t MediaPlayer::getAudioSessionId()
733{
734    Mutex::Autolock _l(mLock);
735    return mAudioSessionId;
736}
737
738status_t MediaPlayer::setAuxEffectSendLevel(float level)
739{
740    ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
741    Mutex::Autolock _l(mLock);
742    mSendLevel = level;
743    if (mPlayer != 0) {
744        return mPlayer->setAuxEffectSendLevel(level);
745    }
746    return OK;
747}
748
749status_t MediaPlayer::attachAuxEffect(int effectId)
750{
751    ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
752    Mutex::Autolock _l(mLock);
753    if (mPlayer == 0 ||
754        (mCurrentState & MEDIA_PLAYER_IDLE) ||
755        (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
756        ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
757        return INVALID_OPERATION;
758    }
759
760    return mPlayer->attachAuxEffect(effectId);
761}
762
763// always call with lock held
764status_t MediaPlayer::checkStateForKeySet_l(int key)
765{
766    switch(key) {
767    case KEY_PARAMETER_AUDIO_ATTRIBUTES:
768        if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
769                MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) {
770            // Can't change the audio attributes after prepare
771            ALOGE("trying to set audio attributes called in state %d", mCurrentState);
772            return INVALID_OPERATION;
773        }
774        break;
775    default:
776        // parameter doesn't require player state check
777        break;
778    }
779    return OK;
780}
781
782status_t MediaPlayer::setParameter(int key, const Parcel& request)
783{
784    ALOGV("MediaPlayer::setParameter(%d)", key);
785    status_t status = INVALID_OPERATION;
786    Mutex::Autolock _l(mLock);
787    if (checkStateForKeySet_l(key) != OK) {
788        return status;
789    }
790    switch (key) {
791    case KEY_PARAMETER_AUDIO_ATTRIBUTES:
792        // save the marshalled audio attributes
793        if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; };
794        mAudioAttributesParcel = new Parcel();
795        mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
796        status = OK;
797        break;
798    default:
799        ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
800        break;
801    }
802
803    if (mPlayer != NULL) {
804        status = mPlayer->setParameter(key, request);
805    }
806    return status;
807}
808
809status_t MediaPlayer::getParameter(int key, Parcel *reply)
810{
811    ALOGV("MediaPlayer::getParameter(%d)", key);
812    Mutex::Autolock _l(mLock);
813    if (mPlayer != NULL) {
814        status_t status =  mPlayer->getParameter(key, reply);
815        if (status != OK) {
816            ALOGD("getParameter returns %d", status);
817        }
818        return status;
819    }
820    ALOGV("getParameter: no active player");
821    return INVALID_OPERATION;
822}
823
824status_t MediaPlayer::setRetransmitEndpoint(const char* addrString,
825                                            uint16_t port) {
826    ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)",
827            addrString ? addrString : "(null)", port);
828
829    Mutex::Autolock _l(mLock);
830    if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE))
831        return INVALID_OPERATION;
832
833    if (NULL == addrString) {
834        mRetransmitEndpointValid = false;
835        return OK;
836    }
837
838    struct in_addr saddr;
839    if(!inet_aton(addrString, &saddr)) {
840        return BAD_VALUE;
841    }
842
843    memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint));
844    mRetransmitEndpoint.sin_family = AF_INET;
845    mRetransmitEndpoint.sin_addr   = saddr;
846    mRetransmitEndpoint.sin_port   = htons(port);
847    mRetransmitEndpointValid       = true;
848
849    return OK;
850}
851
852void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
853{
854    ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
855    bool send = true;
856    bool locked = false;
857
858    // TODO: In the future, we might be on the same thread if the app is
859    // running in the same process as the media server. In that case,
860    // this will deadlock.
861    //
862    // The threadId hack below works around this for the care of prepare,
863    // seekTo and start within the same process.
864    // FIXME: Remember, this is a hack, it's not even a hack that is applied
865    // consistently for all use-cases, this needs to be revisited.
866    if (mLockThreadId != getThreadId()) {
867        mLock.lock();
868        locked = true;
869    }
870
871    // Allows calls from JNI in idle state to notify errors
872    if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {
873        ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
874        if (locked) mLock.unlock();   // release the lock when done.
875        return;
876    }
877
878    switch (msg) {
879    case MEDIA_NOP: // interface test message
880        break;
881    case MEDIA_PREPARED:
882        ALOGV("MediaPlayer::notify() prepared");
883        mCurrentState = MEDIA_PLAYER_PREPARED;
884        if (mPrepareSync) {
885            ALOGV("signal application thread");
886            mPrepareSync = false;
887            mPrepareStatus = NO_ERROR;
888            mSignal.signal();
889        }
890        break;
891    case MEDIA_DRM_INFO:
892        ALOGV("MediaPlayer::notify() MEDIA_DRM_INFO(%d, %d, %d, %p)", msg, ext1, ext2, obj);
893        break;
894    case MEDIA_PLAYBACK_COMPLETE:
895        ALOGV("playback complete");
896        if (mCurrentState == MEDIA_PLAYER_IDLE) {
897            ALOGE("playback complete in idle state");
898        }
899        if (!mLoop) {
900            mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE;
901        }
902        break;
903    case MEDIA_ERROR:
904        // Always log errors.
905        // ext1: Media framework error code.
906        // ext2: Implementation dependant error code.
907        ALOGE("error (%d, %d)", ext1, ext2);
908        mCurrentState = MEDIA_PLAYER_STATE_ERROR;
909        if (mPrepareSync)
910        {
911            ALOGV("signal application thread");
912            mPrepareSync = false;
913            mPrepareStatus = ext1;
914            mSignal.signal();
915            send = false;
916        }
917        break;
918    case MEDIA_INFO:
919        // ext1: Media framework error code.
920        // ext2: Implementation dependant error code.
921        if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
922            ALOGW("info/warning (%d, %d)", ext1, ext2);
923        }
924        break;
925    case MEDIA_SEEK_COMPLETE:
926        ALOGV("Received seek complete");
927        if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
928            ALOGV("Executing queued seekTo(%d, %d)", mCurrentPosition, mCurrentSeekMode);
929            mSeekPosition = -1;
930            mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
931            seekTo_l(mCurrentPosition, mCurrentSeekMode);
932        }
933        else {
934            ALOGV("All seeks complete - return to regularly scheduled program");
935            mCurrentPosition = mSeekPosition = -1;
936            mCurrentSeekMode = mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
937        }
938        break;
939    case MEDIA_BUFFERING_UPDATE:
940        ALOGV("buffering %d", ext1);
941        break;
942    case MEDIA_SET_VIDEO_SIZE:
943        ALOGV("New video size %d x %d", ext1, ext2);
944        mVideoWidth = ext1;
945        mVideoHeight = ext2;
946        break;
947    case MEDIA_TIMED_TEXT:
948        ALOGV("Received timed text message");
949        break;
950    case MEDIA_SUBTITLE_DATA:
951        ALOGV("Received subtitle data message");
952        break;
953    case MEDIA_META_DATA:
954        ALOGV("Received timed metadata message");
955        break;
956    default:
957        ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
958        break;
959    }
960
961    sp<MediaPlayerListener> listener = mListener;
962    if (locked) mLock.unlock();
963
964    // this prevents re-entrant calls into client code
965    if ((listener != 0) && send) {
966        Mutex::Autolock _l(mNotifyLock);
967        ALOGV("callback application");
968        listener->notify(msg, ext1, ext2, obj);
969        ALOGV("back from callback");
970    }
971}
972
973void MediaPlayer::died()
974{
975    ALOGV("died");
976    notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
977}
978
979status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
980    Mutex::Autolock _l(mLock);
981    if (mPlayer == NULL) {
982        return NO_INIT;
983    }
984
985    if (next != NULL && !(next->mCurrentState &
986            (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
987        ALOGE("next player is not prepared");
988        return INVALID_OPERATION;
989    }
990
991    return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
992}
993
994VolumeShaper::Status MediaPlayer::applyVolumeShaper(
995        const sp<VolumeShaper::Configuration>& configuration,
996        const sp<VolumeShaper::Operation>& operation)
997{
998    Mutex::Autolock _l(mLock);
999    if (mPlayer == nullptr) {
1000        return VolumeShaper::Status(NO_INIT);
1001    }
1002    VolumeShaper::Status status = mPlayer->applyVolumeShaper(configuration, operation);
1003    return status;
1004}
1005
1006sp<VolumeShaper::State> MediaPlayer::getVolumeShaperState(int id)
1007{
1008    Mutex::Autolock _l(mLock);
1009    if (mPlayer == nullptr) {
1010        return nullptr;
1011    }
1012    return mPlayer->getVolumeShaperState(id);
1013}
1014
1015// Modular DRM
1016status_t MediaPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
1017{
1018    // TODO change to ALOGV
1019    ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
1020            drmSessionId.array(), drmSessionId.size());
1021    Mutex::Autolock _l(mLock);
1022    if (mPlayer == NULL) {
1023        return NO_INIT;
1024    }
1025
1026    // Only allowed it in player's preparing/prepared state.
1027    // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
1028    // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
1029    // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
1030    if (!(mCurrentState & (MEDIA_PLAYER_PREPARING | MEDIA_PLAYER_PREPARED))) {
1031        ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState);
1032        return INVALID_OPERATION;
1033    }
1034
1035    if (drmSessionId.isEmpty()) {
1036        ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
1037        return INVALID_OPERATION;
1038    }
1039
1040    // Passing down to mediaserver mainly for creating the crypto
1041    status_t status = mPlayer->prepareDrm(uuid, drmSessionId);
1042    ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
1043
1044    // TODO change to ALOGV
1045    ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
1046
1047    return status;
1048}
1049
1050status_t MediaPlayer::releaseDrm()
1051{
1052    Mutex::Autolock _l(mLock);
1053    if (mPlayer == NULL) {
1054        return NO_INIT;
1055    }
1056
1057    // Not allowing releaseDrm in an active/resumable state
1058    if (mCurrentState & (MEDIA_PLAYER_STARTED |
1059                         MEDIA_PLAYER_PAUSED |
1060                         MEDIA_PLAYER_PLAYBACK_COMPLETE |
1061                         MEDIA_PLAYER_STATE_ERROR)) {
1062        ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
1063        return INVALID_OPERATION;
1064    }
1065
1066    status_t status = mPlayer->releaseDrm();
1067    // TODO change to ALOGV
1068    ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
1069    if (status != OK) {
1070        ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
1071        // Overriding to OK so the client proceed with its own cleanup
1072        // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
1073        status = OK;
1074    }
1075
1076    return status;
1077}
1078
1079} // namespace android
1080