summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/MediaPlayer.java52
-rw-r--r--media/jni/Android.mk1
-rw-r--r--media/jni/android_media_MediaPlayer.cpp26
-rw-r--r--media/libmedia/IMediaPlayer.cpp15
-rw-r--r--media/libmedia/IMediaPlayerService.cpp1
-rw-r--r--media/libmedia/mediaplayer.cpp14
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp12
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
-rw-r--r--media/libmediaplayerservice/MidiFile.h2
-rw-r--r--media/libmediaplayerservice/VorbisPlayer.h2
10 files changed, 122 insertions, 5 deletions
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 3b46d69..298cce9 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.util.Log;
@@ -435,6 +436,10 @@ public class MediaPlayer
}
private final static String TAG = "MediaPlayer";
+ // Name of the remote interface for the media player. Must be kept
+ // in sync with the 2nd parameter of the IMPLEMENT_META_INTERFACE
+ // macro invocation in IMediaPlayer.cpp
+ private final static String IMEDIA_PLAYER = "android.media.IMediaPlayer";
private int mNativeContext; // accessed by native methods
private int mListenerContext; // accessed by native methods
@@ -475,6 +480,43 @@ public class MediaPlayer
private native void _setVideoSurface();
/**
+ * Create a request parcel which can be routed to the native media
+ * player using {@link #invoke(Parcel, Parcel)}. The Parcel
+ * returned has the proper InterfaceToken set. The caller should
+ * not overwrite that token, i.e it can only append data to the
+ * Parcel.
+ *
+ * @return A parcel suitable to hold a request for the native
+ * player.
+ */
+ public Parcel newRequest() {
+ Parcel parcel = Parcel.obtain();
+ parcel.writeInterfaceToken(IMEDIA_PLAYER);
+ return parcel;
+ }
+
+ /**
+ * Invoke a generic method on the native player using opaque
+ * parcels for the request and reply. Both payloads' format is a
+ * convention between the java caller and the native player.
+ * Must be called after setDataSource to make sure a native player
+ * exists.
+ *
+ * @param request Parcel with the data for the extension. The
+ * caller must use {@link #newRequest()} to get one.
+ *
+ * @param[out] reply Parcel with the data returned by the
+ * native player.
+ *
+ * @return The status code see utils/Errors.h
+ */
+ public int invoke(Parcel request, Parcel reply) {
+ int retcode = native_invoke(request, reply);
+ reply.setDataPosition(0);
+ return retcode;
+ }
+
+ /**
* Sets the SurfaceHolder to use for displaying the video portion of the media.
* This call is optional. Not calling it when playing back a video will
* result in only the audio track being played.
@@ -915,8 +957,18 @@ public class MediaPlayer
*/
public native Bitmap getFrameAt(int msec) throws IllegalStateException;
+ /**
+ * @param request Parcel destinated to the media player. The
+ * Interface token must be set to the IMediaPlayer
+ * one to be routed correctly through the system.
+ * @param reply Parcel that will contain the reply.
+ * @return The status code.
+ */
+ private native final int native_invoke(Parcel request, Parcel reply);
+
private native final void native_setup(Object mediaplayer_this);
private native final void native_finalize();
+
@Override
protected void finalize() { native_finalize(); }
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 9552aa6..f19649b 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -27,6 +27,7 @@ LOCAL_STATIC_LIBRARIES :=
LOCAL_C_INCLUDES += \
external/tremor/Tremor \
+ frameworks/base/core/jni \
$(PV_INCLUDES) \
$(JNI_H_INCLUDE) \
$(call include-path-for, corecg graphics)
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 6317fe2..2c08c16 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -20,6 +20,7 @@
#include "utils/Log.h"
#include <media/mediaplayer.h>
+#include <media/MediaPlayerInterface.h>
#include <stdio.h>
#include <assert.h>
#include <limits.h>
@@ -30,6 +31,8 @@
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "utils/Errors.h" // for status_t
+#include "android_util_Binder.h"
+#include <binder/Parcel.h>
// ----------------------------------------------------------------------------
@@ -442,6 +445,28 @@ android_media_MediaPlayer_getFrameAt(JNIEnv *env, jobject thiz, jint msec)
return NULL;
}
+
+// Sends the request and reply parcels to the media player via the
+// binder interface.
+static jint
+android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
+ jobject java_request, jobject java_reply)
+{
+ sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
+ if (media_player == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ }
+
+
+ Parcel *request = parcelForJavaObject(env, java_request);
+ Parcel *reply = parcelForJavaObject(env, java_reply);
+
+ const status_t status = media_player->invoke(*request, reply);
+ // Don't use process_media_player_call which use the async loop to
+ // report errors, instead returns the status.
+ return status;
+}
+
static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
@@ -503,6 +528,7 @@ static JNINativeMethod gMethods[] = {
{"isLooping", "()Z", (void *)android_media_MediaPlayer_isLooping},
{"setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
{"getFrameAt", "(I)Landroid/graphics/Bitmap;", (void *)android_media_MediaPlayer_getFrameAt},
+ {"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
};
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index fa2d81d..3f278f4 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -39,7 +39,8 @@ enum {
RESET,
SET_AUDIO_STREAM_TYPE,
SET_LOOPING,
- SET_VOLUME
+ SET_VOLUME,
+ INVOKE,
};
class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -170,6 +171,13 @@ public:
remote()->transact(SET_VOLUME, data, &reply);
return reply.readInt32();
}
+
+ status_t invoke(const Parcel& request, Parcel *reply)
+ { // Avoid doing any extra copy. The interface descriptor should
+ // have been set by MediaPlayer.java.
+ status_t retcode = remote()->transact(INVOKE, request, reply);
+ return retcode;
+ }
};
IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -260,6 +268,11 @@ status_t BnMediaPlayer::onTransact(
reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
return NO_ERROR;
} break;
+ case INVOKE: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ invoke(data, reply);
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 33b3e22..0f64259 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -20,6 +20,7 @@
#include <binder/Parcel.h>
#include <binder/IMemory.h>
+#include <utils/Errors.h> // for status_t
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 220c998..4683166 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -196,6 +196,20 @@ status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
return err;
}
+status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
+{
+ Mutex::Autolock _l(mLock);
+ if ((mPlayer != NULL) && ( mCurrentState & MEDIA_PLAYER_INITIALIZED ))
+ {
+ LOGV("invoke %d", request.dataSize());
+ return mPlayer->invoke(request, reply);
+ }
+ LOGE("invoke failed: wrong state %X", mCurrentState);
+ return INVALID_OPERATION;
+}
+
+
+
status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
{
LOGV("setVideoSurface");
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index a17e651..e39495b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -34,6 +34,9 @@
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
+#include <utils/Errors.h> // for status_t
+#include <utils/String8.h>
+#include <utils/Vector.h>
#include <cutils/properties.h>
#include <media/MediaPlayerInterface.h>
@@ -61,7 +64,6 @@ pid_t gettid() { return syscall(__NR_gettid);}
#undef __KERNEL__
#endif
-
namespace android {
// TODO: Temp hack until we can register players
@@ -671,6 +673,14 @@ status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface
return p->setVideoSurface(surface);
}
+status_t MediaPlayerService::Client::invoke(const Parcel& request,
+ Parcel *reply)
+{
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == NULL) return UNKNOWN_ERROR;
+ return p->invoke(request, reply);
+}
+
status_t MediaPlayerService::Client::prepareAsync()
{
LOGV("[%d] prepareAsync", mConnId);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 5a296bf..12f2231 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -187,6 +187,7 @@ private:
virtual status_t setAudioStreamType(int type);
virtual status_t setLooping(int loop);
virtual status_t setVolume(float leftVolume, float rightVolume);
+ virtual status_t invoke(const Parcel& request, Parcel *reply);
sp<MediaPlayerBase> createPlayer(player_type playerType);
status_t setDataSource(const char *url);
@@ -238,4 +239,3 @@ private:
}; // namespace android
#endif // ANDROID_MEDIAPLAYERSERVICE_H
-
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index 302f1cf..83d97fe 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -46,6 +46,7 @@ public:
virtual status_t reset();
virtual status_t setLooping(int loop);
virtual player_type playerType() { return SONIVOX_PLAYER; }
+ virtual status_t invoke(const Parcel& request, Parcel *reply) {return INVALID_OPERATION;}
private:
status_t createOutputTrack();
@@ -74,4 +75,3 @@ private:
}; // namespace android
#endif // ANDROID_MIDIFILE_H
-
diff --git a/media/libmediaplayerservice/VorbisPlayer.h b/media/libmediaplayerservice/VorbisPlayer.h
index c30dc1b..4024654 100644
--- a/media/libmediaplayerservice/VorbisPlayer.h
+++ b/media/libmediaplayerservice/VorbisPlayer.h
@@ -53,6 +53,7 @@ public:
virtual status_t reset();
virtual status_t setLooping(int loop);
virtual player_type playerType() { return VORBIS_PLAYER; }
+ virtual status_t invoke(const Parcel& request, Parcel *reply) {return INVALID_OPERATION;}
private:
status_t setdatasource(const char *path, int fd, int64_t offset, int64_t length);
@@ -88,4 +89,3 @@ private:
}; // namespace android
#endif // ANDROID_VORBISPLAYER_H
-