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 Diff line number Diff line
@@ -59,6 +59,23 @@ public:
    // @param filter A set of allow and drop rules serialized in a Parcel.
    // @return OK if the invocation was made successfully.
    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 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);
            status_t        invoke(const Parcel& request, Parcel *reply);
            status_t        setMetadataFilter(const Parcel& filter);
            status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
private:
            void            clear_l();
            status_t        seekTo_l(int msec);
+34 −3
Original line number Diff line number Diff line
@@ -930,8 +930,21 @@ public class MediaPlayer
     */
    public Metadata getMetadata(final boolean update_only,
                                final boolean apply_filter) {
        // FIXME: Implement.
        return new Metadata();
        Parcel reply = Parcel.obtain();
        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
     *                Interface token must be set to the IMediaPlayer
     *                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.
     */
    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
     *                metadata types followed by the one to be
+13 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.media;

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

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


/**
   Class to hold the media's metadata.  Metadata are used
   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_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.
     */
@@ -119,6 +127,11 @@ public class Metadata

    /* package */ Metadata() {}

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

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

    Parcel *filter = parcelForJavaObject(env, request);

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

    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
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},
    {"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_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},
    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
};
Loading