Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d55c711 authored by Nicolas Catania's avatar Nicolas Catania
Browse files

Basic plumbing to retrieve metadata from the native player.

IMediaPlayer.h
Added a getMetadata method that mirrors the on in MediaPlayer.java.

MediaPlayer.java
Added a native method to get the metadata from the native player.
Parse the parcel into a Metadata object.

Metadata.java
Added a stub to parse the Parcel returned by the native player into
a set of metadata.

android_media_MediaPlayer.cpp
JNI call to forward the getMetadata call.

MediaPlayerService.cpp
MediaPlayerService::Client implements the new getMetadata method added in IMediaPlayer.h
parent 2eedb251
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,23 @@ public:
    // @param filter A set of allow and drop rules serialized in a Parcel.
    // @param filter A set of allow and drop rules serialized in a Parcel.
    // @return OK if the invocation was made successfully.
    // @return OK if the invocation was made successfully.
    virtual status_t        setMetadataFilter(const Parcel& filter) = 0;
    virtual status_t        setMetadataFilter(const Parcel& filter) = 0;

    // Retrieve a set of metadata.
    // @param update_only Include only the metadata that have changed
    //                    since the last invocation of getMetadata.
    //                    The set is built using the unfiltered
    //                    notifications the native player sent to the
    //                    MediaPlayerService during that period of
    //                    time. If false, all the metadatas are considered.
    // @param apply_filter If true, once the metadata set has been built based
    //                     on the value update_only, the current filter is
    //                     applied.
    // @param[out] metadata On exit contains a set (possibly empty) of metadata.
    //                      Valid only if the call returned OK.
    // @return OK if the invocation was made successfully.
    virtual status_t        getMetadata(bool update_only,
                                        bool apply_filter,
                                        Parcel *metadata) = 0;
};
};


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
+1 −0
Original line number Original line Diff line number Diff line
@@ -155,6 +155,7 @@ public:
    static  sp<IMemory>     decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
    static  sp<IMemory>     decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
            status_t        invoke(const Parcel& request, Parcel *reply);
            status_t        invoke(const Parcel& request, Parcel *reply);
            status_t        setMetadataFilter(const Parcel& filter);
            status_t        setMetadataFilter(const Parcel& filter);
            status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
private:
private:
            void            clear_l();
            void            clear_l();
            status_t        seekTo_l(int msec);
            status_t        seekTo_l(int msec);
+34 −3
Original line number Original line Diff line number Diff line
@@ -930,8 +930,21 @@ public class MediaPlayer
     */
     */
    public Metadata getMetadata(final boolean update_only,
    public Metadata getMetadata(final boolean update_only,
                                final boolean apply_filter) {
                                final boolean apply_filter) {
        // FIXME: Implement.
        Parcel reply = Parcel.obtain();
        return new Metadata();
        Metadata data = new Metadata();

        if (!native_getMetadata(update_only, apply_filter, reply)) {
            reply.recycle();
            return null;
        }

        // Metadata takes over the parcel, don't recycle it unless
        // there is an error.
        if (!data.parse(reply)) {
            reply.recycle();
            return null;
        }
        return data;
    }
    }


    /**
    /**
@@ -1064,11 +1077,29 @@ public class MediaPlayer
     * @param request Parcel destinated to the media player. The
     * @param request Parcel destinated to the media player. The
     *                Interface token must be set to the IMediaPlayer
     *                Interface token must be set to the IMediaPlayer
     *                one to be routed correctly through the system.
     *                one to be routed correctly through the system.
     * @param reply Parcel that will contain the reply.
     * @param reply[out] Parcel that will contain the reply.
     * @return The status code.
     * @return The status code.
     */
     */
    private native final int native_invoke(Parcel request, Parcel reply);
    private native final int native_invoke(Parcel request, Parcel reply);



    /**
     * @param update_only If true fetch only the set of metadata that have
     *                    changed since the last invocation of getMetadata.
     *                    The set is built using the unfiltered
     *                    notifications the native player sent to the
     *                    MediaPlayerService during that period of
     *                    time. If false, all the metadatas are considered.
     * @param apply_filter  If true, once the metadata set has been built based on
     *                     the value update_only, the current filter is applied.
     * @param reply[out] On return contains the serialized
     *                   metadata. Valid only if the call was successful.
     * @return The status code.
     */
    private native final boolean native_getMetadata(boolean update_only,
                                                    boolean apply_filter,
                                                    Parcel reply);

    /**
    /**
     * @param request Parcel with the 2 serialized lists of allowed
     * @param request Parcel with the 2 serialized lists of allowed
     *                metadata types followed by the one to be
     *                metadata types followed by the one to be
+13 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.media;
package android.media;


import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.util.Log;
import android.util.Log;


import java.util.Collections;
import java.util.Collections;
@@ -24,6 +25,7 @@ import java.util.Date;
import java.util.Iterator;
import java.util.Iterator;
import java.util.Set;
import java.util.Set;



/**
/**
   Class to hold the media's metadata.  Metadata are used
   Class to hold the media's metadata.  Metadata are used
   for human consumption and can be embedded in the media (e.g
   for human consumption and can be embedded in the media (e.g
@@ -100,6 +102,12 @@ public class Metadata
    public static final Set<Integer> MATCH_NONE = Collections.EMPTY_SET;
    public static final Set<Integer> MATCH_NONE = Collections.EMPTY_SET;
    public static final Set<Integer> MATCH_ALL = Collections.singleton(ANY);
    public static final Set<Integer> MATCH_ALL = Collections.singleton(ANY);


    private static final int STRING_VAL = 1;
    private static final int INTEGER_VAL = 2;
    private static final int LONG_VAL = 3;
    private static final int DOUBLE_VAL = 4;
    private static final int TIMED_TEXT_VAL = 2;

    /**
    /**
     * Helper class to hold a pair (time, text). Can be used to implement caption.
     * Helper class to hold a pair (time, text). Can be used to implement caption.
     */
     */
@@ -119,6 +127,11 @@ public class Metadata


    /* package */ Metadata() {}
    /* package */ Metadata() {}


    /* package */ boolean parse(Parcel data) {
        // FIXME: Implement.
        return true;
    }

    /**
    /**
     * @return the number of element in this metadata set.
     * @return the number of element in this metadata set.
     */
     */
+31 −0
Original line number Original line Diff line number Diff line
@@ -479,9 +479,39 @@ android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject r


    Parcel *filter = parcelForJavaObject(env, request);
    Parcel *filter = parcelForJavaObject(env, request);


    if (filter == NULL ) {
        jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
        return UNKNOWN_ERROR;
    }

    return media_player->setMetadataFilter(*filter);
    return media_player->setMetadataFilter(*filter);
}
}


static jboolean
android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
                                      jboolean apply_filter, jobject reply)
{
    sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
    if (media_player == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return false;
    }

    Parcel *metadata = parcelForJavaObject(env, reply);

    if (metadata == NULL ) {
        jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
        return false;
    }

    metadata->freeData();
    // On return metadata is positioned at the beginning of the
    // metadata. Note however that the parcel actually starts with the
    // return code so you should not rewind the parcel using
    // setDataPosition(0).
    return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
}



static void
static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
@@ -546,6 +576,7 @@ static JNINativeMethod gMethods[] = {
    {"getFrameAt",          "(I)Landroid/graphics/Bitmap;",     (void *)android_media_MediaPlayer_getFrameAt},
    {"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_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
    {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
    {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
    {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},
    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
    {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
};
};
Loading