diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/MediaPlayer.java | 47 | ||||
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 14 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 32 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 10 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 14 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 2 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightPlayer.cpp | 10 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightPlayer.h | 2 |
8 files changed, 131 insertions, 0 deletions
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 89ee7d3..e8b89e0 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1064,6 +1064,53 @@ public class MediaPlayer private native void _reset(); /** + * Suspends the MediaPlayer. The only methods that may be called while + * suspended are {@link #reset()}, {@link #release()} and {@link #resume()}. + * MediaPlayer will release its hardware resources as far as + * possible and reasonable. A successfully suspended MediaPlayer will + * cease sending events. + * If suspension is successful, this method returns true, otherwise + * false is returned and the player's state is not affected. + * @hide + */ + public boolean suspend() { + if (native_suspend_resume(true) < 0) { + return false; + } + + stayAwake(false); + + // make sure none of the listeners get called anymore + mEventHandler.removeCallbacksAndMessages(null); + + return true; + } + + /** + * Resumes the MediaPlayer. Only to be called after a previous (successful) + * call to {@link #suspend()}. + * MediaPlayer will return to a state close to what it was in before + * suspension. + * @hide + */ + public boolean resume() { + if (native_suspend_resume(false) < 0) { + return false; + } + + if (isPlaying()) { + stayAwake(true); + } + + return true; + } + + /** + * @hide + */ + private native int native_suspend_resume(boolean isSuspend); + + /** * Sets the audio stream type for this MediaPlayer. See {@link AudioManager} * for a list of stream types. * diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 2773e5c..8ed3730 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -692,6 +692,19 @@ android_media_MediaPlayer_snoop(JNIEnv* env, jobject thiz, jobject data, jint ki return ret; } +static jint +android_media_MediaPlayer_native_suspend_resume( + JNIEnv *env, jobject thiz, jboolean isSuspend) { + LOGV("suspend_resume(%d)", isSuspend); + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return UNKNOWN_ERROR; + } + + return isSuspend ? mp->suspend() : mp->resume(); +} + // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { @@ -724,6 +737,7 @@ static JNINativeMethod gMethods[] = { {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup}, {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize}, {"snoop", "([SI)I", (void *)android_media_MediaPlayer_snoop}, + {"native_suspend_resume", "(Z)I", (void *)android_media_MediaPlayer_native_suspend_resume}, }; static const char* const kClassPathName = "android/media/MediaPlayer"; diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 9c127d4..ed792b3 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -43,6 +43,8 @@ enum { INVOKE, SET_METADATA_FILTER, GET_METADATA, + SUSPEND, + RESUME, }; class BpMediaPlayer: public BpInterface<IMediaPlayer> @@ -199,6 +201,26 @@ public: remote()->transact(GET_METADATA, request, reply); return reply->readInt32(); } + + status_t suspend() { + Parcel request; + request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + + Parcel reply; + remote()->transact(SUSPEND, request, &reply); + + return reply.readInt32(); + } + + status_t resume() { + Parcel request; + request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + + Parcel reply; + remote()->transact(RESUME, request, &reply); + + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); @@ -299,6 +321,16 @@ status_t BnMediaPlayer::onTransact( reply->writeInt32(setMetadataFilter(data)); return NO_ERROR; } break; + case SUSPEND: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + reply->writeInt32(suspend()); + return NO_ERROR; + } break; + case RESUME: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + reply->writeInt32(resume()); + return NO_ERROR; + } break; case GET_METADATA: { CHECK_INTERFACE(IMediaPlayer, data, reply); const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply); diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 01cd8ce..2157814 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -167,6 +167,16 @@ status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply) return INVALID_OPERATION; } +status_t MediaPlayer::suspend() { + Mutex::Autolock _l(mLock); + return mPlayer->suspend(); +} + +status_t MediaPlayer::resume() { + Mutex::Autolock _l(mLock); + return mPlayer->resume(); +} + status_t MediaPlayer::setMetadataFilter(const Parcel& filter) { LOGD("setMetadataFilter"); diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 55b06f4..b4fc035 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -970,6 +970,20 @@ status_t MediaPlayerService::Client::getMetadata( return OK; } +status_t MediaPlayerService::Client::suspend() { + sp<MediaPlayerBase> p = getPlayer(); + if (p == 0) return UNKNOWN_ERROR; + + return p->suspend(); +} + +status_t MediaPlayerService::Client::resume() { + sp<MediaPlayerBase> p = getPlayer(); + if (p == 0) return UNKNOWN_ERROR; + + return p->resume(); +} + status_t MediaPlayerService::Client::prepareAsync() { LOGV("[%d] prepareAsync", mConnId); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index c9cae35..2408c62 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -222,6 +222,8 @@ private: virtual status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply); + virtual status_t suspend(); + virtual status_t resume(); sp<MediaPlayerBase> createPlayer(player_type playerType); diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp index 1bfcf65..7776b4e 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -136,6 +136,16 @@ player_type StagefrightPlayer::playerType() { return STAGEFRIGHT_PLAYER; } +status_t StagefrightPlayer::suspend() { + LOGV("suspend"); + return mPlayer->suspend(); +} + +status_t StagefrightPlayer::resume() { + LOGV("resume"); + return mPlayer->resume(); +} + status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) { return INVALID_OPERATION; } diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h index 9e6674a..4446582 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.h +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -50,6 +50,8 @@ public: virtual player_type playerType(); virtual status_t invoke(const Parcel &request, Parcel *reply); virtual void setAudioSink(const sp<AudioSink> &audioSink); + virtual status_t suspend(); + virtual status_t resume(); private: AwesomePlayer *mPlayer; |