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

Commit b2c69391 authored by Nicolas Catania's avatar Nicolas Catania
Browse files

Implemented the metadata changed notification filters.

IMediaPlayer:
new setMetadataFilter method so set a filter (2 lists of allowed and blocked metadata type)
serialized in a Parcel.

MediaPlayer.java/android_media_MediaPlayer.cpp/mediaplayer.cpp
new setMetadataFilter that passes the filter down to the MediaPlayerService's binder interface.

MediaPlayerService.cpp
The Client inner class holds the allowed and blocked metadata types.
These are in 2 vectors that get populated in the setMetadataFilter.

A new shourldDropMetadata method returns true if a type of metadata should be dropped according
to the filters.

The notify method in run the metadata update notifications thru the filter and possibly drop them.
parent 3ff23c46
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -52,8 +52,13 @@ public:
    // @param request Parcel that must start with the media player
    // interface token.
    // @param[out] reply Parcel to hold the reply data. Cannot be null.
    // @return OK if the invocation was made. PERMISSION_DENIED otherwise.
    // @return OK if the invocation was made successfully.
    virtual status_t        invoke(const Parcel& request, Parcel *reply) = 0;

    // Set a new metadata filter.
    // @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;
};

// ----------------------------------------------------------------------------
+3 −0
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ enum media_info_type {
    MEDIA_INFO_BAD_INTERLEAVING = 800,
    // The media is not seekable (e.g live stream).
    MEDIA_INFO_NOT_SEEKABLE = 801,
    // New media metadata is available.
    MEDIA_INFO_METADATA_UPDATE = 802,
};


@@ -152,6 +154,7 @@ public:
    static  sp<IMemory>     decode(const char* url, 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        setMetadataFilter(const Parcel& filter);
private:
            void            clear_l();
            status_t        seekTo_l(int msec);
+42 −9
Original line number Diff line number Diff line
@@ -937,25 +937,49 @@ public class MediaPlayer
    /**
     * Set a filter for the metadata update notification and update
     * retrieval. The caller provides 2 set of metadata keys, allowed
     * and disallowed. The disallow set always takes the precedence
     * over the allowed one.
     * and blocked. The blocked set always takes precedence over the
     * allowed one.
     * Metadata.MATCH_ALL and Metadata.MATCH_NONE are 2 sets available as
     * shorthands to allow/disallow all or no metadata.
     * shorthands to allow/block all or no metadata.
     *
     * By default, there is no filter set.
     *
     * @param allow Is the set of metadata the client is interested
     *              receiving new notifications for.
     * @param disallow Is the set of metadata the client is not interested
     *                 receiving new notifications for.
     *              in receiving new notifications for.
     * @param block Is the set of metadata the client is not interested
     *              in receiving new notifications for.
     * @return The call status code.
     *
     // FIXME: unhide.
     * {@hide}
     */
    public int setMetadataFilter(Set<Integer> allow, Set<Integer> disallow) {
        // FIXME: Implement.
        return 0;
    public int setMetadataFilter(Set<Integer> allow, Set<Integer> block) {
        // Do our serialization manually instead of calling
        // Parcel.writeArray since the sets are made of the same type
        // we avoid paying the price of calling writeValue (used by
        // writeArray) which burns an extra int per element to encode
        // the type.
        Parcel request =  newRequest();

        // The parcel starts already with an interface token. There
        // are 2 filters. Each one starts with a 4bytes number to
        // store the len followed by a number of int (4 bytes as well)
        // representing the metadata type.
        int capacity = request.dataSize() + 4 * (1 + allow.size() + 1 + block.size());

        if (request.dataCapacity() < capacity) {
            request.setDataCapacity(capacity);
        }

        request.writeInt(allow.size());
        for(Integer t: allow) {
            request.writeInt(t);
        }
        request.writeInt(block.size());
        for(Integer t: block) {
            request.writeInt(t);
        }
        return native_setMetadataFilter(request);
    }

    /**
@@ -1045,6 +1069,15 @@ public class MediaPlayer
     */
    private native final int native_invoke(Parcel request, Parcel reply);

    /**
     * @param request Parcel with the 2 serialized lists of allowed
     *                metadata types followed by the one to be
     *                dropped. Each list starts with an integer
     *                indicating the number of metadata type elements.
     * @return The status code.
     */
    private native final int native_setMetadataFilter(Parcel request);

    private native final void native_setup(Object mediaplayer_this);
    private native final void native_finalize();

+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ public class Metadata
    //

    public static final int ANY = 0;  // Never used for metadata returned, only for filtering.
                                      // Keep in sync with kAny in MediaPlayerService.cpp

    // TODO: Should we use numbers compatible with the metadata retriever?
    public static final int TITLE = 1;           // String
+19 −2
Original line number Diff line number Diff line
@@ -455,18 +455,34 @@ android_media_MediaPlayer_invoke(JNIEnv *env, jobject thiz,
    sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
    if (media_player == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return UNKNOWN_ERROR;
    }


    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;
    return media_player->invoke(*request, reply);
}

// Sends the new filter to the client.
static jint
android_media_MediaPlayer_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
{
    sp<MediaPlayer> media_player = getMediaPlayer(env, thiz);
    if (media_player == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return UNKNOWN_ERROR;
    }

    Parcel *filter = parcelForJavaObject(env, request);

    return media_player->setMetadataFilter(*filter);
}


static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
@@ -529,6 +545,7 @@ static JNINativeMethod gMethods[] = {
    {"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_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
};
Loading