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 29namespace android { 30 31class IMediaAnalyticsService; 32class Parcel; 33 34// the class interface 35// 36 37class 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