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