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 <string> 21 #include <sys/types.h> 22 23 #include <cutils/properties.h> 24 #include <utils/Errors.h> 25 #include <utils/KeyedVector.h> 26 #include <utils/RefBase.h> 27 #include <utils/StrongPointer.h> 28 #include <utils/Timers.h> 29 30 namespace android { 31 32 class IMediaAnalyticsService; 33 class Parcel; 34 35 // the class interface 36 // 37 38 class MediaAnalyticsItem { 39 40 friend class MediaAnalyticsService; 41 friend class IMediaAnalyticsService; 42 friend class MediaMetricsJNI; 43 friend class MetricsSummarizer; 44 friend class MediaMetricsDeathNotifier; 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 std::string 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 enum { 79 PROTO_V0 = 0, 80 PROTO_FIRST = PROTO_V0, 81 PROTO_V1 = 1, 82 PROTO_LAST = PROTO_V1, 83 }; 84 85 private: 86 // use the ::create() method instead 87 MediaAnalyticsItem(); 88 MediaAnalyticsItem(Key); 89 MediaAnalyticsItem(const MediaAnalyticsItem&); 90 MediaAnalyticsItem &operator=(const MediaAnalyticsItem&); 91 92 public: 93 94 static MediaAnalyticsItem* create(Key key); 95 static MediaAnalyticsItem* create(); 96 97 // access functions for the class 98 ~MediaAnalyticsItem(); 99 100 // SessionID ties multiple submissions for same key together 101 // so that if video "height" and "width" are known at one point 102 // and "framerate" is only known later, they can be be brought 103 // together. 104 MediaAnalyticsItem &setSessionID(SessionID_t); 105 MediaAnalyticsItem &clearSessionID(); 106 SessionID_t getSessionID() const; 107 // generates and stores a new ID iff mSessionID == SessionIDNone 108 SessionID_t generateSessionID(); 109 110 // reset all contents, discarding any extra data 111 void clear(); 112 MediaAnalyticsItem *dup(); 113 114 // set the key discriminator for the record. 115 // most often initialized as part of the constructor 116 MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key); 117 MediaAnalyticsItem::Key getKey(); 118 119 // # of attributes in the record 120 int32_t count() const; 121 122 // set values appropriately 123 void setInt32(Attr, int32_t value); 124 void setInt64(Attr, int64_t value); 125 void setDouble(Attr, double value); 126 void setRate(Attr, int64_t count, int64_t duration); 127 void setCString(Attr, const char *value); 128 129 // fused get/add/set; if attr wasn't there, it's a simple set. 130 // type-mismatch counts as "wasn't there". 131 void addInt32(Attr, int32_t value); 132 void addInt64(Attr, int64_t value); 133 void addDouble(Attr, double value); 134 void addRate(Attr, int64_t count, int64_t duration); 135 136 // find & extract values 137 // return indicates whether attr exists (and thus value filled in) 138 // NULL parameter value suppresses storage of value. 139 bool getInt32(Attr, int32_t *value); 140 bool getInt64(Attr, int64_t *value); 141 bool getDouble(Attr, double *value); 142 bool getRate(Attr, int64_t *count, int64_t *duration, double *rate); 143 // Caller owns the returned string 144 bool getCString(Attr, char **value); 145 bool getString(Attr, std::string *value); 146 147 // parameter indicates whether to close any existing open 148 // record with same key before establishing a new record 149 // caller retains ownership of 'this'. 150 bool selfrecord(bool); 151 bool selfrecord(); 152 153 // remove indicated attributes and their values 154 // filterNot() could also be called keepOnly() 155 // return value is # attributes removed 156 // XXX: perhaps 'remove' instead of 'filter' 157 // XXX: filterNot would become 'keep' 158 int32_t filter(int count, Attr attrs[]); 159 int32_t filterNot(int count, Attr attrs[]); 160 int32_t filter(Attr attr); 161 162 // below here are used on server side or to talk to server 163 // clients need not worry about these. 164 165 // timestamp, pid, and uid only used on server side 166 // timestamp is in 'nanoseconds, unix time' 167 MediaAnalyticsItem &setTimestamp(nsecs_t); 168 nsecs_t getTimestamp() const; 169 170 MediaAnalyticsItem &setPid(pid_t); 171 pid_t getPid() const; 172 173 MediaAnalyticsItem &setUid(uid_t); 174 uid_t getUid() const; 175 176 MediaAnalyticsItem &setPkgName(const std::string &pkgName); getPkgName()177 std::string getPkgName() const { return mPkgName; } 178 179 MediaAnalyticsItem &setPkgVersionCode(int64_t); 180 int64_t getPkgVersionCode() const; 181 182 // our serialization code for binder calls 183 int32_t writeToParcel(Parcel *); 184 int32_t readFromParcel(const Parcel&); 185 186 // supports the stable interface 187 bool dumpAttributes(char **pbuffer, size_t *plength); 188 189 std::string toString(); 190 std::string toString(int version); 191 const char *toCString(); 192 const char *toCString(int version); 193 194 // are we collecting analytics data 195 static bool isEnabled(); 196 197 private: 198 // handle Parcel version 0 199 int32_t writeToParcel0(Parcel *); 200 int32_t readFromParcel0(const Parcel&); 201 202 protected: 203 204 // merge fields from arg into this 205 // with rules for first/last/add, etc 206 // XXX: document semantics and how they are indicated 207 // caller continues to own 'incoming' 208 bool merge(MediaAnalyticsItem *incoming); 209 210 // enabled 1, disabled 0 211 static const char * const EnabledProperty; 212 static const char * const EnabledPropertyPersist; 213 static const int EnabledProperty_default; 214 215 private: 216 217 // to help validate that A doesn't mess with B's records 218 pid_t mPid; 219 uid_t mUid; 220 std::string mPkgName; 221 int64_t mPkgVersionCode; 222 223 // let's reuse a binder connection 224 static sp<IMediaAnalyticsService> sAnalyticsService; 225 static sp<IMediaAnalyticsService> getInstance(); 226 static void dropInstance(); 227 228 // tracking information 229 SessionID_t mSessionID; // grouping similar records 230 nsecs_t mTimestamp; // ns, system_time_monotonic 231 232 // will this record accept further updates 233 bool mFinalized; 234 235 Key mKey; 236 237 struct Prop { 238 239 Type mType; 240 const char *mName; 241 size_t mNameLen; // the strlen(), doesn't include the null 242 union { 243 int32_t int32Value; 244 int64_t int64Value; 245 double doubleValue; 246 char *CStringValue; 247 struct { int64_t count, duration; } rate; 248 } u; 249 void setName(const char *name, size_t len); 250 }; 251 252 void initProp(Prop *item); 253 void clearProp(Prop *item); 254 void clearPropValue(Prop *item); 255 void copyProp(Prop *dst, const Prop *src); 256 enum { 257 kGrowProps = 10 258 }; 259 bool growProps(int increment = kGrowProps); 260 size_t findPropIndex(const char *name, size_t len); 261 Prop *findProp(const char *name); 262 Prop *allocateProp(const char *name); 263 bool removeProp(const char *name); 264 265 size_t mPropCount; 266 size_t mPropSize; 267 Prop *mProps; 268 }; 269 270 } // namespace android 271 272 #endif 273