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