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

Commit 17dbaf28 authored by Andy Hung's avatar Andy Hung
Browse files

MediaMetrics: Update to use STL containers

Test: dumpsys media.metrics sanity
Change-Id: Ifcada098e755ef3d679715ed23fab9d793ebde3e
parent dbfd6388
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -234,10 +234,6 @@ MediaAnalyticsItem &MediaAnalyticsItem::setKey(MediaAnalyticsItem::Key key) {
    return *this;
}

MediaAnalyticsItem::Key MediaAnalyticsItem::getKey() {
    return mKey;
}

// number of attributes we have in this record
int32_t MediaAnalyticsItem::count() const {
    return mPropCount;
@@ -795,11 +791,11 @@ const char * MediaAnalyticsItem::toCString(int version) {
    return strdup(val.c_str());
}

std::string MediaAnalyticsItem::toString() {
std::string MediaAnalyticsItem::toString() const {
   return toString(PROTO_LAST);
}

std::string MediaAnalyticsItem::toString(int version) {
std::string MediaAnalyticsItem::toString(int version) const {

    // v0 : released with 'o'
    // v1 : bug fix (missing pid/finalized separator),
+3 −3
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ class MediaAnalyticsItem {
        // set the key discriminator for the record.
        // most often initialized as part of the constructor
        MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key);
        MediaAnalyticsItem::Key getKey();
        const MediaAnalyticsItem::Key& getKey() const { return mKey; }

        // # of attributes in the record
        int32_t count() const;
@@ -191,8 +191,8 @@ class MediaAnalyticsItem {
        // supports the stable interface
        bool dumpAttributes(char **pbuffer, size_t *plength);

        std::string toString();
        std::string toString(int version);
        std::string toString() const;
        std::string toString(int version) const;
        const char *toCString();
        const char *toCString(int version);

+6 −22
Original line number Diff line number Diff line
@@ -5,9 +5,9 @@ cc_binary {
    name: "mediametrics",

    srcs: [
        "iface_statsd.cpp",
        "main_mediametrics.cpp",
        "MediaAnalyticsService.cpp",
        "iface_statsd.cpp",
        "statsd_audiopolicy.cpp",
        "statsd_audiorecord.cpp",
        "statsd_audiothread.cpp",
@@ -24,44 +24,28 @@ cc_binary {
    },

    shared_libs: [
        "libcutils",
        "liblog",
        "libmedia",
        "libutils",
        "libbinder",
        "libdl",
        "libgui",
        "libmedia",
        "libmediautils",
        "liblog",
        "libmediametrics",
        "libstagefright_foundation",
        "libprotobuf-cpp-lite",
        "libstatslog",
        "libutils",
        "libprotobuf-cpp-lite",
    ],

    static_libs: [
        "libplatformprotos",
        "libregistermsext",
    ],

    include_dirs: [
        "frameworks/av/media/libstagefright/include",
        "frameworks/av/media/libstagefright/rtsp",
        "frameworks/av/media/libstagefright/webm",
        "frameworks/av/include/media",
        "frameworks/av/camera/include/camera",
        "frameworks/native/include/media/openmax",
        "frameworks/native/include/media/hardware",
        "external/tremolo/Tremolo",
        "system/media/audio_utils/include"
    ],

    init_rc: ["mediametrics.rc"],

    cflags: [
        "-Werror",
        "-Wall",
        "-Wno-error=deprecated-declarations",
        "-Werror",
        "-Wextra",
    ],
    clang: true,

+272 −445

File changed.

Preview size limit exceeded, changes collapsed.

+68 −78
Original line number Diff line number Diff line
@@ -14,109 +14,99 @@
 * limitations under the License.
 */

#pragma once

#ifndef ANDROID_MEDIAANALYTICSSERVICE_H
#define ANDROID_MEDIAANALYTICSSERVICE_H

#include <arpa/inet.h>

#include <utils/threads.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/List.h>

#include <atomic>
#include <deque>
#include <future>
#include <mutex>
#include <unordered_map>

// IMediaAnalyticsService must include Vector, String16, Errors
#include <media/IMediaAnalyticsService.h>
#include <utils/String8.h>

namespace android {

class MediaAnalyticsService : public BnMediaAnalyticsService
{

public:
    MediaAnalyticsService();
    ~MediaAnalyticsService() override;

    // on this side, caller surrenders ownership
    virtual int64_t submit(MediaAnalyticsItem *item, bool forcenew);
    // caller surrenders ownership of item, MediaAnalyticsService will delete.
    int64_t submit(MediaAnalyticsItem *item, bool forcenew) override;

    static  void            instantiate();
    virtual status_t        dump(int fd, const Vector<String16>& args);
    status_t dump(int fd, const Vector<String16>& args) override;

                            MediaAnalyticsService();
    virtual                 ~MediaAnalyticsService();

    bool processExpirations();
    static constexpr const char * const kServiceName = "media.metrics";

private:
    void processExpirations();
    MediaAnalyticsItem::SessionID_t generateUniqueSessionID();
    // input validation after arrival from client
    static bool isContentValid(const MediaAnalyticsItem *item, bool isTrusted);
    bool isRateLimited(MediaAnalyticsItem *) const;
    void saveItem(MediaAnalyticsItem *);

    // statistics about our analytics
    int64_t mItemsSubmitted;
    int64_t mItemsFinalized;
    int64_t mItemsDiscarded;
    int64_t mItemsDiscardedExpire;
    int64_t mItemsDiscardedCount;
    MediaAnalyticsItem::SessionID_t mLastSessionID;

    // partitioned a bit so we don't over serialize
    mutable Mutex           mLock;
    mutable Mutex           mLock_ids;
    mutable Mutex           mLock_mappings;
    // The following methods are GUARDED_BY(mLock)
    bool expirations_l(MediaAnalyticsItem *);

    // support for generating output
    void dumpQueue_l(String8 &result, int dumpProto);
    void dumpQueue_l(String8 &result, int dumpProto, nsecs_t, const char *only);
    void dumpHeaders_l(String8 &result, int dumpProto, nsecs_t ts_since);
    void dumpSummaries_l(String8 &result, int dumpProto, nsecs_t ts_since, const char * only);
    void dumpRecent_l(String8 &result, int dumpProto, nsecs_t ts_since, const char * only);

    // The following variables accessed without mLock

    // limit how many records we'll retain
    // by count (in each queue (open, finalized))
    int32_t mMaxRecords;
    // by time (none older than this long agan
    nsecs_t mMaxRecordAgeNs;
    const size_t mMaxRecords;
    // by time (none older than this)
    const nsecs_t mMaxRecordAgeNs;
    // max to expire per expirations_l() invocation
    int32_t mMaxRecordsExpiredAtOnce;
    //
    // # of sets of summaries
    int32_t mMaxRecordSets;
    // nsecs until we start a new record set
    nsecs_t mNewSetInterval;
    const size_t mMaxRecordsExpiredAtOnce;
    const int mDumpProtoDefault;

    // input validation after arrival from client
    bool contentValid(MediaAnalyticsItem *item, bool isTrusted);
    bool rateLimited(MediaAnalyticsItem *);
    std::atomic<MediaAnalyticsItem::SessionID_t> mLastSessionID{};

    // (oldest at front) so it prints nicely for dumpsys
    List<MediaAnalyticsItem *> mItems;
    void saveItem(MediaAnalyticsItem *);
    class UidInfo {
    public:
        void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);

    bool expirations_l(MediaAnalyticsItem *);
    std::future<bool> mExpireFuture;
    private:
        std::mutex mUidInfoLock;

    // support for generating output
    int mDumpProto;
    int mDumpProtoDefault;
    String8 dumpQueue();
    String8 dumpQueue(nsecs_t, const char *only);

    void dumpHeaders(String8 &result, nsecs_t ts_since);
    void dumpSummaries(String8 &result, nsecs_t ts_since, const char * only);
    void dumpRecent(String8 &result, nsecs_t ts_since, const char * only);

    // mapping uids to package names
    struct UidToPkgMap {
        uid_t uid;
        struct UidToPkgInfo {
            uid_t uid = -1;
            std::string pkg;
            std::string installer;
        int64_t versionCode;
        nsecs_t expiration;
            int64_t versionCode = 0;
            nsecs_t expiration = 0;  // TODO: remove expiration.
        };

    KeyedVector<uid_t,struct UidToPkgMap>  mPkgMappings;
    void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);

};
        // TODO: use concurrent hashmap with striped lock.
        std::unordered_map<uid_t, struct UidToPkgInfo> mPkgMappings; // GUARDED_BY(mUidInfoLock)
    } mUidInfo;  // mUidInfo can be accessed without lock (locked internally)

// hook to send things off to the statsd subsystem
extern bool dump2Statsd(MediaAnalyticsItem *item);
    std::atomic<int64_t> mItemsSubmitted{}; // accessed outside of lock.

// ----------------------------------------------------------------------------

}; // namespace android
    std::mutex mLock;
    // statistics about our analytics
    int64_t mItemsFinalized = 0;        // GUARDED_BY(mLock)
    int64_t mItemsDiscarded = 0;        // GUARDED_BY(mLock)
    int64_t mItemsDiscardedExpire = 0;  // GUARDED_BY(mLock)
    int64_t mItemsDiscardedCount = 0;   // GUARDED_BY(mLock)

    // If we have a worker thread to garbage collect
    std::future<void> mExpireFuture;    // GUARDED_BY(mLock)

    // Our item queue, generally (oldest at front)
    // TODO: Make separate class, use segmented queue, write lock only end.
    // Note: Another analytics module might have ownership of an item longer than the log.
    std::deque<std::shared_ptr<const MediaAnalyticsItem>> mItems; // GUARDED_BY(mLock)
};

#endif // ANDROID_MEDIAANALYTICSSERVICE_H
} // namespace android
Loading