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

Commit e41cc497 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 6812

* changes:
  Implemented the tracking of the metadata updates.
parents e375fc5c 4df8b2c7
Loading
Loading
Loading
Loading
+68 −75
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@
#include <media/MediaMetadataRetrieverInterface.h>
#include <media/AudioTrack.h>

#include <utils/SortedVector.h>

#include "MediaRecorderClient.h"
#include "MediaPlayerService.h"
#include "MetadataRetrieverClient.h"
@@ -74,8 +76,9 @@ using android::status_t;
using android::OK;
using android::BAD_VALUE;
using android::NOT_ENOUGH_DATA;
using android::MetadataType;
using android::Parcel;
using android::Vector;
using android::SortedVector;

// Max number of entries in the filter.
const int kMaxFilterSize = 64;  // I pulled that out of thin air.
@@ -83,11 +86,6 @@ const int kMaxFilterSize = 64; // I pulled that out of thin air.
// Keep in sync with ANY in Metadata.java
const int32_t kAny = 0;

// To order the metadata types in the vector-filter.
int lessThan(const int32_t *lhs, const int32_t *rhs)
{
    return *lhs < *rhs ? 0 : 1;
}

// Unmarshall a filter from a Parcel.
// Filter format in a parcel:
@@ -111,39 +109,40 @@ int lessThan(const int32_t *lhs, const int32_t *rhs)
// @param[out] status On exit contains the status code to be returned.
// @return true if the parcel starts with a valid filter.
bool unmarshallFilter(const Parcel& p,
                      Vector<int32_t> *filter,
                      SortedVector<MetadataType> *filter,
                      status_t *status)
{
    int32_t s;
    if (p.readInt32(&s) != OK)
    int32_t val;
    if (p.readInt32(&val) != OK)
    {
        LOGE("Failed to read filter's length");
        *status = NOT_ENOUGH_DATA;
        return false;
    }

    if( s > kMaxFilterSize || s < 0)
    if( val > kMaxFilterSize || val < 0)
    {
        LOGE("Invalid filter len %d", s);
        LOGE("Invalid filter len %d", val);
        *status = BAD_VALUE;
        return false;
    }

    size_t size = s;
    const size_t num = val;

    filter->clear();
    filter->setCapacity(size);
    filter->setCapacity(num);

    size_t size = num * sizeof(MetadataType);

    s *= sizeof(int32_t);

    if (p.dataAvail() < static_cast<size_t>(s))
    if (p.dataAvail() < size)
    {
        LOGE("Filter too short expected %d but got %d", s, p.dataAvail());
        LOGE("Filter too short expected %d but got %d", size, p.dataAvail());
        *status = NOT_ENOUGH_DATA;
        return false;
    }

    const int32_t *data = static_cast<const int32_t*>(p.readInplace(s));
    const MetadataType *data = static_cast<const MetadataType*>(p.readInplace(size));

    if (NULL == data)
    {
@@ -155,59 +154,25 @@ bool unmarshallFilter(const Parcel& p,
    // TODO: The stl impl of vector would be more efficient here
    // because it degenerates into a memcpy on pod types. Try to
    // replace later or use stl::set.
    for (size_t i = 0; i < size; ++i)
    for (size_t i = 0; i < num; ++i)
    {
        filter->push(*data);
        filter->add(*data);
        ++data;
    }
    *status = OK;
    return true;
}

bool unmarshallBothFilters(const Parcel& p,
                           Vector<int32_t> *allow,
                           Vector<int32_t> *block,
                           status_t *status)
{
    if (!(unmarshallFilter(p, allow, status) && unmarshallFilter(p, block, status)))
    {
        return false;
    }
    allow->sort(lessThan);
    block->sort(lessThan);
    return true;
}

// @param filter Should be sorted in ascending order.
// @param filter Of metadata type.
// @param val To be searched.
// @return true if a match was found.
bool findMetadata(const Vector<int32_t> filter, const int32_t val)
bool findMetadata(const SortedVector<MetadataType>& filter, const int32_t val)
{
    // Deal with empty and ANY right away
    if (filter.isEmpty()) return false;
    if (filter[0] == kAny) return true;

    ssize_t min = 0;
    ssize_t max = filter.size() - 1;
    ssize_t mid;
    do
    {
        mid = (min + max) / 2;
        if (val > filter[mid])
        {
            min = mid + 1;
        }
        else
        {
            max = mid - 1;
        }
        if (filter[mid] == val)
        {
            return true;
        }
    }
    while(min <= max);
    return false;
    return filter.indexOf(val) >= 0;
}

}  // anonymous namespace
@@ -834,11 +799,11 @@ status_t MediaPlayerService::Client::invoke(const Parcel& request,
status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter)
{
    status_t status;
    Vector<int32_t> allow, drop;
    SortedVector<MetadataType> allow, drop;

    if (unmarshallBothFilters(filter, &allow, &drop, &status))
    {
        Mutex::Autolock l(mLock);
    if (unmarshallFilter(filter, &allow, &status) &&
        unmarshallFilter(filter, &drop, &status)) {
        Mutex::Autolock lock(mLock);

        mMetadataAllow = allow;
        mMetadataDrop = drop;
@@ -846,13 +811,28 @@ status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter)
    return status;
}

status_t MediaPlayerService::Client::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
status_t MediaPlayerService::Client::getMetadata(
        bool update_only, bool apply_filter, Parcel *reply)
{
    status_t status;
    metadata->writeInt32(-1);  // Placeholder for the return code
    reply->writeInt32(-1);  // Placeholder for the return code

    SortedVector<MetadataType> updates;

    // We don't block notifications while we fetch the data. We clear
    // mMetadataUpdated first so we don't lose notifications happening
    // during the rest of this call.
    {
        Mutex::Autolock lock(mLock);
        if (update_only) {
            updates = mMetadataUpdated;
        }
        mMetadataUpdated.clear();
    }

    // FIXME: Implement, query the native player and do the optional filtering, etc...
    status = OK;

    return status;
}

@@ -975,38 +955,51 @@ status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolu
    return NO_ERROR;
}


void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
{
    Client* client = static_cast<Client*>(cookie);

    if (MEDIA_INFO == msg &&
        MEDIA_INFO_METADATA_UPDATE == ext1 &&
        client->shouldDropMetadata(ext2 /* metadata type */)) {
        MEDIA_INFO_METADATA_UPDATE == ext1) {
        const MetadataType metadata_type = ext2;

        if(client->shouldDropMetadata(metadata_type)) {
            return;
        }

        // Update the list of metadata that have changed. getMetadata
        // also access mMetadataUpdated and clears it.
        client->addNewMetadataUpdate(metadata_type);
    }
    LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
    client->mClient->notify(msg, ext1, ext2);
}

bool MediaPlayerService::Client::shouldDropMetadata(int code) const
{
    Mutex::Autolock l(mLock);

    if (findMetadata(mMetadataDrop, code))
bool MediaPlayerService::Client::shouldDropMetadata(MetadataType code) const
{
    Mutex::Autolock lock(mLock);

    if (findMetadata(mMetadataDrop, code)) {
        return true;
    }

    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code))
    {
    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
        return false;
    }
    else
    {
    } else {
        return true;
    }
}


void MediaPlayerService::Client::addNewMetadataUpdate(MetadataType metadata_type) {
    Mutex::Autolock lock(mLock);
    if (mMetadataUpdated.indexOf(metadata_type) < 0) {
        mMetadataUpdated.add(metadata_type);
    }
}

#if CALLBACK_ANTAGONIZER
const int Antagonizer::interval = 10000; // 10 msecs

+25 −8
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <utils/List.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <utils/Vector.h>
#include <ui/SurfaceComposerClient.h>

@@ -30,6 +31,7 @@
#include <media/MediaPlayerInterface.h>

namespace android {
typedef int32_t MetadataType;

class IMediaRecorder;
class IMediaMetadataRetriever;
@@ -191,7 +193,9 @@ private:
        virtual status_t        setVolume(float leftVolume, float rightVolume);
        virtual status_t        invoke(const Parcel& request, Parcel *reply);
        virtual status_t        setMetadataFilter(const Parcel& filter);
        virtual status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
        virtual status_t        getMetadata(bool update_only,
                                            bool apply_filter,
                                            Parcel *reply);

        sp<MediaPlayerBase>     createPlayer(player_type playerType);
                status_t        setDataSource(const char *url);
@@ -215,10 +219,16 @@ private:
        sp<MediaPlayerBase>     getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; }


        /**
         * @return true if the metadata should be dropped.
         */
        bool shouldDropMetadata(int code) const;

        // @param type Of the metadata to be tested.
        // @return true if the metadata should be dropped according to
        //              the filters.
        bool shouldDropMetadata(MetadataType type) const;

        // Add a new element to the set of metadata updated. Noop if
        // the element exists already.
        // @param type Of the metadata to be recorded.
        void addNewMetadataUpdate(MetadataType type);

        mutable     Mutex                       mLock;
                    sp<MediaPlayerBase>         mPlayer;
@@ -229,10 +239,17 @@ private:
                    status_t                    mStatus;
                    bool                        mLoop;
                    int32_t                     mConnId;
        // FIXME: Replace Vector<> with std::set<> when available. std::set support find.

        // Metadata filters.
                    Vector<int32_t>             mMetadataAllow;  // protected by mLock
                    Vector<int32_t>             mMetadataDrop;  // protected by mLock
        SortedVector<int32_t>       mMetadataAllow;  // protected by mLock
        SortedVector<int32_t>       mMetadataDrop;  // protected by mLock

        // Metadata updated. For each MEDIA_INFO_METADATA_UPDATE
        // notification we try to update mMetadataUpdated which is a
        // set: no duplicate.
        // getMetadata clears this set.
        SortedVector<int32_t>       mMetadataUpdated;  // protected by mLock

#if CALLBACK_ANTAGONIZER
                    Antagonizer*                mAntagonizer;
#endif