Direct api to the native media player.

MediaPlayer.java has 3 new methods:
* newRequest creates a Parcel that can be used to send data to the
  native player using invoke.
* invoke issues synchronous calls to the native player using opaque
  parcels for the request and reply.

IMediaPlayer.h has 1 new abstract method:
* invoke

The Midi and Vorbis players have a stub for these. So far only PV
makes use of that new feature.

To avoid any copy overhead, the JNI interface uses Parcel as a java
object (no serialization/copy happens at the JNI layer).

The remote interface token is inserted when the Parcel is constructed
in java. That way the parcel is already routable when it reaches
 IMediaPlayer.cpp (proxy). No extra copy is needed there.
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 @@
     RESET,
     SET_AUDIO_STREAM_TYPE,
     SET_LOOPING,
-    SET_VOLUME
+    SET_VOLUME,
+    INVOKE,
 };
 
 class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -170,6 +171,13 @@
         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 @@
             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 @@
     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 @@
 #undef __KERNEL__
 #endif
 
-
 namespace android {
 
 // TODO: Temp hack until we can register players
@@ -671,6 +673,14 @@
     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 @@
         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 @@
 }; // 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 @@
     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 @@
 }; // 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 @@
     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 @@
 }; // namespace android
 
 #endif // ANDROID_VORBISPLAYER_H
-