Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_MEDIA_MEDIAANALYTICSITEM_H
     18 #define ANDROID_MEDIA_MEDIAANALYTICSITEM_H
     19 
     20 #include <cutils/properties.h>
     21 #include <string>
     22 #include <sys/types.h>
     23 #include <utils/Errors.h>
     24 #include <utils/KeyedVector.h>
     25 #include <utils/RefBase.h>
     26 #include <utils/StrongPointer.h>
     27 #include <utils/Timers.h>
     28 
     29 namespace android {
     30 
     31 class IMediaAnalyticsService;
     32 class Parcel;
     33 
     34 // the class interface
     35 //
     36 
     37 class MediaAnalyticsItem {
     38 
     39     friend class MediaAnalyticsService;
     40     friend class IMediaAnalyticsService;
     41     friend class MediaMetricsJNI;
     42     friend class MetricsSummarizer;
     43     friend class MediaMetricsDeathNotifier;
     44 
     45     public:
     46 
     47             enum Type {
     48                 kTypeNone = 0,
     49                 kTypeInt32 = 1,
     50                 kTypeInt64 = 2,
     51                 kTypeDouble = 3,
     52                 kTypeCString = 4,
     53                 kTypeRate = 5,
     54             };
     55 
     56         // sessionid
     57         // unique within device, within boot,
     58         typedef int64_t SessionID_t;
     59         static constexpr SessionID_t SessionIDInvalid = -1;
     60         static constexpr SessionID_t SessionIDNone = 0;
     61 
     62         // Key: the record descriminator
     63         // values for the record discriminator
     64         // values can be "component/component"
     65         // basic values: "video", "audio", "drm"
     66         // XXX: need to better define the format
     67         typedef std::string Key;
     68         static const Key kKeyNone;              // ""
     69         static const Key kKeyAny;               // "*"
     70 
     71         // Attr: names for attributes within a record
     72         // format "prop1" or "prop/subprop"
     73         // XXX: need to better define the format
     74         typedef const char *Attr;
     75 
     76 
     77         enum {
     78             PROTO_V0 = 0,
     79             PROTO_FIRST = PROTO_V0,
     80             PROTO_V1 = 1,
     81             PROTO_LAST = PROTO_V1,
     82         };
     83 
     84 
     85     public:
     86 
     87         // access functions for the class
     88         MediaAnalyticsItem();
     89         MediaAnalyticsItem(Key);
     90         ~MediaAnalyticsItem();
     91 
     92         // SessionID ties multiple submissions for same key together
     93         // so that if video "height" and "width" are known at one point
     94         // and "framerate" is only known later, they can be be brought
     95         // together.
     96         MediaAnalyticsItem &setSessionID(SessionID_t);
     97         MediaAnalyticsItem &clearSessionID();
     98         SessionID_t getSessionID() const;
     99         // generates and stores a new ID iff mSessionID == SessionIDNone
    100         SessionID_t generateSessionID();
    101 
    102         // reset all contents, discarding any extra data
    103         void clear();
    104         MediaAnalyticsItem *dup();
    105 
    106         // set the key discriminator for the record.
    107         // most often initialized as part of the constructor
    108         MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key);
    109         MediaAnalyticsItem::Key getKey();
    110 
    111         // # of attributes in the record
    112         int32_t count() const;
    113 
    114         // set values appropriately
    115         void setInt32(Attr, int32_t value);
    116         void setInt64(Attr, int64_t value);
    117         void setDouble(Attr, double value);
    118         void setRate(Attr, int64_t count, int64_t duration);
    119         void setCString(Attr, const char *value);
    120 
    121         // fused get/add/set; if attr wasn't there, it's a simple set.
    122         // type-mismatch counts as "wasn't there".
    123         void addInt32(Attr, int32_t value);
    124         void addInt64(Attr, int64_t value);
    125         void addDouble(Attr, double value);
    126         void addRate(Attr, int64_t count, int64_t duration);
    127 
    128         // find & extract values
    129         // return indicates whether attr exists (and thus value filled in)
    130         // NULL parameter value suppresses storage of value.
    131         bool getInt32(Attr, int32_t *value);
    132         bool getInt64(Attr, int64_t *value);
    133         bool getDouble(Attr, double *value);
    134         bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
    135         // Caller owns the returned string
    136         bool getCString(Attr, char **value);
    137 
    138         // parameter indicates whether to close any existing open
    139         // record with same key before establishing a new record
    140         // caller retains ownership of 'this'.
    141         bool selfrecord(bool);
    142         bool selfrecord();
    143 
    144         // remove indicated attributes and their values
    145         // filterNot() could also be called keepOnly()
    146         // return value is # attributes removed
    147         // XXX: perhaps 'remove' instead of 'filter'
    148         // XXX: filterNot would become 'keep'
    149         int32_t filter(int count, Attr attrs[]);
    150         int32_t filterNot(int count, Attr attrs[]);
    151         int32_t filter(Attr attr);
    152 
    153         // below here are used on server side or to talk to server
    154         // clients need not worry about these.
    155 
    156         // timestamp, pid, and uid only used on server side
    157         // timestamp is in 'nanoseconds, unix time'
    158         MediaAnalyticsItem &setTimestamp(nsecs_t);
    159         nsecs_t getTimestamp() const;
    160 
    161         MediaAnalyticsItem &setPid(pid_t);
    162         pid_t getPid() const;
    163 
    164         MediaAnalyticsItem &setUid(uid_t);
    165         uid_t getUid() const;
    166 
    167         MediaAnalyticsItem &setPkgName(const std::string &pkgName);
    168         std::string getPkgName() const { return mPkgName; }
    169 
    170         MediaAnalyticsItem &setPkgVersionCode(int64_t);
    171         int64_t getPkgVersionCode() const;
    172 
    173         // our serialization code for binder calls
    174         int32_t writeToParcel(Parcel *);
    175         int32_t readFromParcel(const Parcel&);
    176 
    177         std::string toString();
    178         std::string toString(int version);
    179 
    180         // are we collecting analytics data
    181         static bool isEnabled();
    182 
    183     protected:
    184 
    185         // merge fields from arg into this
    186         // with rules for first/last/add, etc
    187         // XXX: document semantics and how they are indicated
    188         // caller continues to own 'incoming'
    189         bool merge(MediaAnalyticsItem *incoming);
    190 
    191         // enabled 1, disabled 0
    192         static const char * const EnabledProperty;
    193         static const char * const EnabledPropertyPersist;
    194         static const int   EnabledProperty_default;
    195 
    196     private:
    197 
    198         // to help validate that A doesn't mess with B's records
    199         pid_t     mPid;
    200         uid_t     mUid;
    201         std::string   mPkgName;
    202         int64_t   mPkgVersionCode;
    203 
    204         // let's reuse a binder connection
    205         static sp<IMediaAnalyticsService> sAnalyticsService;
    206         static sp<IMediaAnalyticsService> getInstance();
    207         static void dropInstance();
    208 
    209         // tracking information
    210         SessionID_t mSessionID;         // grouping similar records
    211         nsecs_t mTimestamp;             // ns, system_time_monotonic
    212 
    213         // will this record accept further updates
    214         bool mFinalized;
    215 
    216         Key mKey;
    217 
    218         struct Prop {
    219 
    220             Type mType;
    221             const char *mName;
    222             size_t mNameLen;    // the strlen(), doesn't include the null
    223             union {
    224                     int32_t int32Value;
    225                     int64_t int64Value;
    226                     double doubleValue;
    227                     char *CStringValue;
    228                     struct { int64_t count, duration; } rate;
    229             } u;
    230             void setName(const char *name, size_t len);
    231         };
    232 
    233         void initProp(Prop *item);
    234         void clearProp(Prop *item);
    235         void clearPropValue(Prop *item);
    236         void copyProp(Prop *dst, const Prop *src);
    237         enum {
    238             kGrowProps = 10
    239         };
    240         bool growProps(int increment = kGrowProps);
    241         size_t findPropIndex(const char *name, size_t len);
    242         Prop *findProp(const char *name);
    243         Prop *allocateProp(const char *name);
    244         bool removeProp(const char *name);
    245 
    246         size_t mPropCount;
    247         size_t mPropSize;
    248         Prop *mProps;
    249 };
    250 
    251 } // namespace android
    252 
    253 #endif
    254