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