blob: 42a2f5bc436dd5093002e3d5d052c135c7011355 [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 Essickbf536ac2019-08-26 11:04:28 -070020#include "MediaMetrics.h"
21
Ray Essick783bd0d2018-01-11 11:10:35 -080022#include <string>
Ray Essick3938dc62016-11-01 08:56:56 -070023#include <sys/types.h>
Ray Essickba8c4842019-01-18 11:35:33 -080024
25#include <cutils/properties.h>
Ray Essick3938dc62016-11-01 08:56:56 -070026#include <utils/Errors.h>
27#include <utils/KeyedVector.h>
28#include <utils/RefBase.h>
29#include <utils/StrongPointer.h>
30#include <utils/Timers.h>
31
Ray Essick3938dc62016-11-01 08:56:56 -070032namespace android {
33
Ray Essick3938dc62016-11-01 08:56:56 -070034class IMediaAnalyticsService;
Ray Essick783bd0d2018-01-11 11:10:35 -080035class Parcel;
Ray Essick3938dc62016-11-01 08:56:56 -070036
37// the class interface
38//
39
Ray Essickb5fac8e2016-12-12 11:33:56 -080040class MediaAnalyticsItem {
Ray Essick3938dc62016-11-01 08:56:56 -070041
42 friend class MediaAnalyticsService;
43 friend class IMediaAnalyticsService;
Ray Essicke08ab772017-01-25 17:47:51 -080044 friend class MediaMetricsJNI;
Ray Essick2e9c63b2017-03-29 15:16:44 -070045 friend class MetricsSummarizer;
Ray Essick2ab3c432017-10-02 09:29:49 -070046 friend class MediaMetricsDeathNotifier;
Ray Essick3938dc62016-11-01 08:56:56 -070047
48 public:
49
Ray Essickb5fac8e2016-12-12 11:33:56 -080050 enum Type {
51 kTypeNone = 0,
52 kTypeInt32 = 1,
53 kTypeInt64 = 2,
54 kTypeDouble = 3,
55 kTypeCString = 4,
56 kTypeRate = 5,
57 };
58
Ray Essick3938dc62016-11-01 08:56:56 -070059 // sessionid
60 // unique within device, within boot,
61 typedef int64_t SessionID_t;
62 static constexpr SessionID_t SessionIDInvalid = -1;
63 static constexpr SessionID_t SessionIDNone = 0;
64
65 // Key: the record descriminator
66 // values for the record discriminator
67 // values can be "component/component"
68 // basic values: "video", "audio", "drm"
69 // XXX: need to better define the format
Ray Essick783bd0d2018-01-11 11:10:35 -080070 typedef std::string Key;
Ray Essick3938dc62016-11-01 08:56:56 -070071 static const Key kKeyNone; // ""
72 static const Key kKeyAny; // "*"
73
74 // Attr: names for attributes within a record
75 // format "prop1" or "prop/subprop"
76 // XXX: need to better define the format
Ray Essickb5fac8e2016-12-12 11:33:56 -080077 typedef const char *Attr;
Ray Essick3938dc62016-11-01 08:56:56 -070078
79
Ray Essickf65f4212017-08-31 11:41:19 -070080 enum {
81 PROTO_V0 = 0,
82 PROTO_FIRST = PROTO_V0,
83 PROTO_V1 = 1,
84 PROTO_LAST = PROTO_V1,
85 };
86
Ray Essick6a305222019-01-28 20:33:18 -080087 private:
88 // use the ::create() method instead
89 MediaAnalyticsItem();
90 MediaAnalyticsItem(Key);
91 MediaAnalyticsItem(const MediaAnalyticsItem&);
92 MediaAnalyticsItem &operator=(const MediaAnalyticsItem&);
Ray Essickf65f4212017-08-31 11:41:19 -070093
Ray Essick3938dc62016-11-01 08:56:56 -070094 public:
95
Ray Essickba8c4842019-01-18 11:35:33 -080096 static MediaAnalyticsItem* create(Key key);
97 static MediaAnalyticsItem* create();
98
Ray Essickbf536ac2019-08-26 11:04:28 -070099 static MediaAnalyticsItem* convert(mediametrics_handle_t);
100 static mediametrics_handle_t convert(MediaAnalyticsItem *);
101
Ray Essick3938dc62016-11-01 08:56:56 -0700102 // access functions for the class
Ray Essick3938dc62016-11-01 08:56:56 -0700103 ~MediaAnalyticsItem();
104
Ray Essick3938dc62016-11-01 08:56:56 -0700105 // SessionID ties multiple submissions for same key together
106 // so that if video "height" and "width" are known at one point
107 // and "framerate" is only known later, they can be be brought
108 // together.
109 MediaAnalyticsItem &setSessionID(SessionID_t);
110 MediaAnalyticsItem &clearSessionID();
111 SessionID_t getSessionID() const;
112 // generates and stores a new ID iff mSessionID == SessionIDNone
113 SessionID_t generateSessionID();
114
115 // reset all contents, discarding any extra data
116 void clear();
Ray Essickb5fac8e2016-12-12 11:33:56 -0800117 MediaAnalyticsItem *dup();
Ray Essick3938dc62016-11-01 08:56:56 -0700118
119 // set the key discriminator for the record.
120 // most often initialized as part of the constructor
121 MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key);
122 MediaAnalyticsItem::Key getKey();
123
124 // # of attributes in the record
125 int32_t count() const;
126
127 // set values appropriately
Ray Essickb5fac8e2016-12-12 11:33:56 -0800128 void setInt32(Attr, int32_t value);
129 void setInt64(Attr, int64_t value);
130 void setDouble(Attr, double value);
131 void setRate(Attr, int64_t count, int64_t duration);
132 void setCString(Attr, const char *value);
Ray Essick3938dc62016-11-01 08:56:56 -0700133
134 // fused get/add/set; if attr wasn't there, it's a simple set.
135 // type-mismatch counts as "wasn't there".
Ray Essickb5fac8e2016-12-12 11:33:56 -0800136 void addInt32(Attr, int32_t value);
137 void addInt64(Attr, int64_t value);
138 void addDouble(Attr, double value);
139 void addRate(Attr, int64_t count, int64_t duration);
Ray Essick3938dc62016-11-01 08:56:56 -0700140
141 // find & extract values
142 // return indicates whether attr exists (and thus value filled in)
Ray Essickb5fac8e2016-12-12 11:33:56 -0800143 // NULL parameter value suppresses storage of value.
Ray Essick3938dc62016-11-01 08:56:56 -0700144 bool getInt32(Attr, int32_t *value);
145 bool getInt64(Attr, int64_t *value);
146 bool getDouble(Attr, double *value);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800147 bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
148 // Caller owns the returned string
Ray Essick3938dc62016-11-01 08:56:56 -0700149 bool getCString(Attr, char **value);
Ray Essick20147322018-11-17 09:08:39 -0800150 bool getString(Attr, std::string *value);
Ray Essick3938dc62016-11-01 08:56:56 -0700151
152 // parameter indicates whether to close any existing open
153 // record with same key before establishing a new record
Ray Essickb5fac8e2016-12-12 11:33:56 -0800154 // caller retains ownership of 'this'.
Ray Essick3938dc62016-11-01 08:56:56 -0700155 bool selfrecord(bool);
156 bool selfrecord();
157
158 // remove indicated attributes and their values
159 // filterNot() could also be called keepOnly()
160 // return value is # attributes removed
161 // XXX: perhaps 'remove' instead of 'filter'
162 // XXX: filterNot would become 'keep'
163 int32_t filter(int count, Attr attrs[]);
164 int32_t filterNot(int count, Attr attrs[]);
165 int32_t filter(Attr attr);
166
167 // below here are used on server side or to talk to server
168 // clients need not worry about these.
169
170 // timestamp, pid, and uid only used on server side
Ray Essickb5fac8e2016-12-12 11:33:56 -0800171 // timestamp is in 'nanoseconds, unix time'
Ray Essick3938dc62016-11-01 08:56:56 -0700172 MediaAnalyticsItem &setTimestamp(nsecs_t);
173 nsecs_t getTimestamp() const;
174
175 MediaAnalyticsItem &setPid(pid_t);
176 pid_t getPid() const;
177
178 MediaAnalyticsItem &setUid(uid_t);
179 uid_t getUid() const;
180
Ray Essick783bd0d2018-01-11 11:10:35 -0800181 MediaAnalyticsItem &setPkgName(const std::string &pkgName);
182 std::string getPkgName() const { return mPkgName; }
Ray Essickf65f4212017-08-31 11:41:19 -0700183
Dianne Hackborn4e2eeff2017-11-27 14:01:29 -0800184 MediaAnalyticsItem &setPkgVersionCode(int64_t);
185 int64_t getPkgVersionCode() const;
Ray Essickf65f4212017-08-31 11:41:19 -0700186
Ray Essick3938dc62016-11-01 08:56:56 -0700187 // our serialization code for binder calls
188 int32_t writeToParcel(Parcel *);
189 int32_t readFromParcel(const Parcel&);
190
Ray Essickba8c4842019-01-18 11:35:33 -0800191 // supports the stable interface
192 bool dumpAttributes(char **pbuffer, size_t *plength);
193
Ray Essick783bd0d2018-01-11 11:10:35 -0800194 std::string toString();
195 std::string toString(int version);
Ray Essick20147322018-11-17 09:08:39 -0800196 const char *toCString();
197 const char *toCString(int version);
Ray Essick3938dc62016-11-01 08:56:56 -0700198
199 // are we collecting analytics data
200 static bool isEnabled();
201
Ray Essickba8c4842019-01-18 11:35:33 -0800202 private:
203 // handle Parcel version 0
204 int32_t writeToParcel0(Parcel *);
205 int32_t readFromParcel0(const Parcel&);
206
Ray Essick3938dc62016-11-01 08:56:56 -0700207 protected:
208
209 // merge fields from arg into this
210 // with rules for first/last/add, etc
211 // XXX: document semantics and how they are indicated
Ray Essickb5fac8e2016-12-12 11:33:56 -0800212 // caller continues to own 'incoming'
213 bool merge(MediaAnalyticsItem *incoming);
Ray Essick3938dc62016-11-01 08:56:56 -0700214
215 // enabled 1, disabled 0
216 static const char * const EnabledProperty;
217 static const char * const EnabledPropertyPersist;
218 static const int EnabledProperty_default;
219
220 private:
221
222 // to help validate that A doesn't mess with B's records
223 pid_t mPid;
224 uid_t mUid;
Ray Essick783bd0d2018-01-11 11:10:35 -0800225 std::string mPkgName;
Dianne Hackborn4e2eeff2017-11-27 14:01:29 -0800226 int64_t mPkgVersionCode;
Ray Essick3938dc62016-11-01 08:56:56 -0700227
228 // let's reuse a binder connection
229 static sp<IMediaAnalyticsService> sAnalyticsService;
230 static sp<IMediaAnalyticsService> getInstance();
Ray Essick2ab3c432017-10-02 09:29:49 -0700231 static void dropInstance();
Ray Essick3938dc62016-11-01 08:56:56 -0700232
233 // tracking information
234 SessionID_t mSessionID; // grouping similar records
235 nsecs_t mTimestamp; // ns, system_time_monotonic
236
237 // will this record accept further updates
238 bool mFinalized;
239
240 Key mKey;
241
Ray Essickb5fac8e2016-12-12 11:33:56 -0800242 struct Prop {
Ray Essick3938dc62016-11-01 08:56:56 -0700243
244 Type mType;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800245 const char *mName;
246 size_t mNameLen; // the strlen(), doesn't include the null
Ray Essick3938dc62016-11-01 08:56:56 -0700247 union {
248 int32_t int32Value;
249 int64_t int64Value;
250 double doubleValue;
251 char *CStringValue;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800252 struct { int64_t count, duration; } rate;
Ray Essick3938dc62016-11-01 08:56:56 -0700253 } u;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800254 void setName(const char *name, size_t len);
Ray Essick3938dc62016-11-01 08:56:56 -0700255 };
Ray Essickb5fac8e2016-12-12 11:33:56 -0800256
257 void initProp(Prop *item);
258 void clearProp(Prop *item);
259 void clearPropValue(Prop *item);
260 void copyProp(Prop *dst, const Prop *src);
261 enum {
262 kGrowProps = 10
263 };
Ray Essick9bb7e3b2017-10-23 13:01:48 -0700264 bool growProps(int increment = kGrowProps);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800265 size_t findPropIndex(const char *name, size_t len);
266 Prop *findProp(const char *name);
267 Prop *allocateProp(const char *name);
Ray Essickf65f4212017-08-31 11:41:19 -0700268 bool removeProp(const char *name);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800269
270 size_t mPropCount;
271 size_t mPropSize;
272 Prop *mProps;
Ray Essick3938dc62016-11-01 08:56:56 -0700273};
274
275} // namespace android
276
277#endif