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