blob: 4a36f6a0f17f4ba23b7e05ccded717fe6e73c8f7 [file] [log] [blame]
Ray Essick3938dc62016-11-01 08:56:56 -07001/*
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
Ray Essick783bd0d2018-01-11 11:10:35 -080020#include <string>
Ray Essick3938dc62016-11-01 08:56:56 -070021#include <sys/types.h>
Ray Essickba8c4842019-01-18 11:35:33 -080022
23#include <cutils/properties.h>
Ray Essick3938dc62016-11-01 08:56:56 -070024#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
Ray Essick3938dc62016-11-01 08:56:56 -070030namespace android {
31
Ray Essick3938dc62016-11-01 08:56:56 -070032class IMediaAnalyticsService;
Ray Essick783bd0d2018-01-11 11:10:35 -080033class Parcel;
Ray Essick3938dc62016-11-01 08:56:56 -070034
35// the class interface
36//
37
Ray Essickb5fac8e2016-12-12 11:33:56 -080038class MediaAnalyticsItem {
Ray Essick3938dc62016-11-01 08:56:56 -070039
40 friend class MediaAnalyticsService;
41 friend class IMediaAnalyticsService;
Ray Essicke08ab772017-01-25 17:47:51 -080042 friend class MediaMetricsJNI;
Ray Essick2e9c63b2017-03-29 15:16:44 -070043 friend class MetricsSummarizer;
Ray Essick2ab3c432017-10-02 09:29:49 -070044 friend class MediaMetricsDeathNotifier;
Ray Essick3938dc62016-11-01 08:56:56 -070045
46 public:
47
Ray Essickb5fac8e2016-12-12 11:33:56 -080048 enum Type {
49 kTypeNone = 0,
50 kTypeInt32 = 1,
51 kTypeInt64 = 2,
52 kTypeDouble = 3,
53 kTypeCString = 4,
54 kTypeRate = 5,
55 };
56
Ray Essick3938dc62016-11-01 08:56:56 -070057 // 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
Ray Essick783bd0d2018-01-11 11:10:35 -080068 typedef std::string Key;
Ray Essick3938dc62016-11-01 08:56:56 -070069 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
Ray Essickb5fac8e2016-12-12 11:33:56 -080075 typedef const char *Attr;
Ray Essick3938dc62016-11-01 08:56:56 -070076
77
Ray Essickf65f4212017-08-31 11:41:19 -070078 enum {
79 PROTO_V0 = 0,
80 PROTO_FIRST = PROTO_V0,
81 PROTO_V1 = 1,
82 PROTO_LAST = PROTO_V1,
83 };
84
Ray Essick6a305222019-01-28 20:33:18 -080085 private:
86 // use the ::create() method instead
87 MediaAnalyticsItem();
88 MediaAnalyticsItem(Key);
89 MediaAnalyticsItem(const MediaAnalyticsItem&);
90 MediaAnalyticsItem &operator=(const MediaAnalyticsItem&);
Ray Essickf65f4212017-08-31 11:41:19 -070091
Ray Essick3938dc62016-11-01 08:56:56 -070092 public:
93
Ray Essickba8c4842019-01-18 11:35:33 -080094 static MediaAnalyticsItem* create(Key key);
95 static MediaAnalyticsItem* create();
96
Ray Essick3938dc62016-11-01 08:56:56 -070097 // access functions for the class
Ray Essick3938dc62016-11-01 08:56:56 -070098 ~MediaAnalyticsItem();
99
Ray Essick3938dc62016-11-01 08:56:56 -0700100 // 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();
Ray Essickb5fac8e2016-12-12 11:33:56 -0800112 MediaAnalyticsItem *dup();
Ray Essick3938dc62016-11-01 08:56:56 -0700113
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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800123 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);
Ray Essick3938dc62016-11-01 08:56:56 -0700128
129 // fused get/add/set; if attr wasn't there, it's a simple set.
130 // type-mismatch counts as "wasn't there".
Ray Essickb5fac8e2016-12-12 11:33:56 -0800131 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);
Ray Essick3938dc62016-11-01 08:56:56 -0700135
136 // find & extract values
137 // return indicates whether attr exists (and thus value filled in)
Ray Essickb5fac8e2016-12-12 11:33:56 -0800138 // NULL parameter value suppresses storage of value.
Ray Essick3938dc62016-11-01 08:56:56 -0700139 bool getInt32(Attr, int32_t *value);
140 bool getInt64(Attr, int64_t *value);
141 bool getDouble(Attr, double *value);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800142 bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
143 // Caller owns the returned string
Ray Essick3938dc62016-11-01 08:56:56 -0700144 bool getCString(Attr, char **value);
Ray Essick20147322018-11-17 09:08:39 -0800145 bool getString(Attr, std::string *value);
Ray Essick3938dc62016-11-01 08:56:56 -0700146
147 // parameter indicates whether to close any existing open
148 // record with same key before establishing a new record
Ray Essickb5fac8e2016-12-12 11:33:56 -0800149 // caller retains ownership of 'this'.
Ray Essick3938dc62016-11-01 08:56:56 -0700150 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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800166 // timestamp is in 'nanoseconds, unix time'
Ray Essick3938dc62016-11-01 08:56:56 -0700167 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
Ray Essick783bd0d2018-01-11 11:10:35 -0800176 MediaAnalyticsItem &setPkgName(const std::string &pkgName);
177 std::string getPkgName() const { return mPkgName; }
Ray Essickf65f4212017-08-31 11:41:19 -0700178
Dianne Hackborn4e2eeff2017-11-27 14:01:29 -0800179 MediaAnalyticsItem &setPkgVersionCode(int64_t);
180 int64_t getPkgVersionCode() const;
Ray Essickf65f4212017-08-31 11:41:19 -0700181
Ray Essick3938dc62016-11-01 08:56:56 -0700182 // our serialization code for binder calls
183 int32_t writeToParcel(Parcel *);
184 int32_t readFromParcel(const Parcel&);
185
Ray Essickba8c4842019-01-18 11:35:33 -0800186 // supports the stable interface
187 bool dumpAttributes(char **pbuffer, size_t *plength);
188
Ray Essick783bd0d2018-01-11 11:10:35 -0800189 std::string toString();
190 std::string toString(int version);
Ray Essick20147322018-11-17 09:08:39 -0800191 const char *toCString();
192 const char *toCString(int version);
Ray Essick3938dc62016-11-01 08:56:56 -0700193
194 // are we collecting analytics data
195 static bool isEnabled();
196
Ray Essickba8c4842019-01-18 11:35:33 -0800197 private:
198 // handle Parcel version 0
199 int32_t writeToParcel0(Parcel *);
200 int32_t readFromParcel0(const Parcel&);
201
Ray Essick3938dc62016-11-01 08:56:56 -0700202 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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800207 // caller continues to own 'incoming'
208 bool merge(MediaAnalyticsItem *incoming);
Ray Essick3938dc62016-11-01 08:56:56 -0700209
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;
Ray Essick783bd0d2018-01-11 11:10:35 -0800220 std::string mPkgName;
Dianne Hackborn4e2eeff2017-11-27 14:01:29 -0800221 int64_t mPkgVersionCode;
Ray Essick3938dc62016-11-01 08:56:56 -0700222
223 // let's reuse a binder connection
224 static sp<IMediaAnalyticsService> sAnalyticsService;
225 static sp<IMediaAnalyticsService> getInstance();
Ray Essick2ab3c432017-10-02 09:29:49 -0700226 static void dropInstance();
Ray Essick3938dc62016-11-01 08:56:56 -0700227
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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800237 struct Prop {
Ray Essick3938dc62016-11-01 08:56:56 -0700238
239 Type mType;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800240 const char *mName;
241 size_t mNameLen; // the strlen(), doesn't include the null
Ray Essick3938dc62016-11-01 08:56:56 -0700242 union {
243 int32_t int32Value;
244 int64_t int64Value;
245 double doubleValue;
246 char *CStringValue;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800247 struct { int64_t count, duration; } rate;
Ray Essick3938dc62016-11-01 08:56:56 -0700248 } u;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800249 void setName(const char *name, size_t len);
Ray Essick3938dc62016-11-01 08:56:56 -0700250 };
Ray Essickb5fac8e2016-12-12 11:33:56 -0800251
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 };
Ray Essick9bb7e3b2017-10-23 13:01:48 -0700259 bool growProps(int increment = kGrowProps);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800260 size_t findPropIndex(const char *name, size_t len);
261 Prop *findProp(const char *name);
262 Prop *allocateProp(const char *name);
Ray Essickf65f4212017-08-31 11:41:19 -0700263 bool removeProp(const char *name);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800264
265 size_t mPropCount;
266 size_t mPropSize;
267 Prop *mProps;
Ray Essick3938dc62016-11-01 08:56:56 -0700268};
269
270} // namespace android
271
272#endif