blob: ec9b660f68bb5cd203aeced585e8104e786c17d7 [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
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
30namespace android {
31
32
33
34class IMediaAnalyticsService;
35
36// the class interface
37//
38
Ray Essickb5fac8e2016-12-12 11:33:56 -080039class MediaAnalyticsItem {
Ray Essick3938dc62016-11-01 08:56:56 -070040
41 friend class MediaAnalyticsService;
42 friend class IMediaAnalyticsService;
Ray Essicke08ab772017-01-25 17:47:51 -080043 friend class MediaMetricsJNI;
Ray Essick2e9c63b2017-03-29 15:16:44 -070044 friend class MetricsSummarizer;
Ray Essick2ab3c432017-10-02 09:29:49 -070045 friend class MediaMetricsDeathNotifier;
Ray Essick3938dc62016-11-01 08:56:56 -070046
47 public:
48
Ray Essickb5fac8e2016-12-12 11:33:56 -080049 enum Type {
50 kTypeNone = 0,
51 kTypeInt32 = 1,
52 kTypeInt64 = 2,
53 kTypeDouble = 3,
54 kTypeCString = 4,
55 kTypeRate = 5,
56 };
57
Ray Essick3938dc62016-11-01 08:56:56 -070058 // 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
Ray Essickb5fac8e2016-12-12 11:33:56 -080076 typedef const char *Attr;
Ray Essick3938dc62016-11-01 08:56:56 -070077
78
Ray Essickf65f4212017-08-31 11:41:19 -070079 enum {
80 PROTO_V0 = 0,
81 PROTO_FIRST = PROTO_V0,
82 PROTO_V1 = 1,
83 PROTO_LAST = PROTO_V1,
84 };
85
86
Ray Essick3938dc62016-11-01 08:56:56 -070087 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();
Ray Essickb5fac8e2016-12-12 11:33:56 -0800110 MediaAnalyticsItem *dup();
Ray Essick3938dc62016-11-01 08:56:56 -0700111
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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800121 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);
Ray Essick3938dc62016-11-01 08:56:56 -0700126
127 // fused get/add/set; if attr wasn't there, it's a simple set.
128 // type-mismatch counts as "wasn't there".
Ray Essickb5fac8e2016-12-12 11:33:56 -0800129 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);
Ray Essick3938dc62016-11-01 08:56:56 -0700133
134 // find & extract values
135 // return indicates whether attr exists (and thus value filled in)
Ray Essickb5fac8e2016-12-12 11:33:56 -0800136 // NULL parameter value suppresses storage of value.
Ray Essick3938dc62016-11-01 08:56:56 -0700137 bool getInt32(Attr, int32_t *value);
138 bool getInt64(Attr, int64_t *value);
139 bool getDouble(Attr, double *value);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800140 bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
141 // Caller owns the returned string
Ray Essick3938dc62016-11-01 08:56:56 -0700142 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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800146 // caller retains ownership of 'this'.
Ray Essick3938dc62016-11-01 08:56:56 -0700147 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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800163 // timestamp is in 'nanoseconds, unix time'
Ray Essick3938dc62016-11-01 08:56:56 -0700164 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
Ray Essickf65f4212017-08-31 11:41:19 -0700173 MediaAnalyticsItem &setPkgName(AString);
174 AString getPkgName() const;
175
Dianne Hackborn4e2eeff2017-11-27 14:01:29 -0800176 MediaAnalyticsItem &setPkgVersionCode(int64_t);
177 int64_t getPkgVersionCode() const;
Ray Essickf65f4212017-08-31 11:41:19 -0700178
Ray Essick3938dc62016-11-01 08:56:56 -0700179 // our serialization code for binder calls
180 int32_t writeToParcel(Parcel *);
181 int32_t readFromParcel(const Parcel&);
182
183 AString toString();
Ray Essickf65f4212017-08-31 11:41:19 -0700184 AString toString(int version);
Ray Essick3938dc62016-11-01 08:56:56 -0700185
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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800194 // caller continues to own 'incoming'
195 bool merge(MediaAnalyticsItem *incoming);
Ray Essick3938dc62016-11-01 08:56:56 -0700196
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;
Ray Essickf65f4212017-08-31 11:41:19 -0700207 AString mPkgName;
Dianne Hackborn4e2eeff2017-11-27 14:01:29 -0800208 int64_t mPkgVersionCode;
Ray Essick3938dc62016-11-01 08:56:56 -0700209
210 // let's reuse a binder connection
211 static sp<IMediaAnalyticsService> sAnalyticsService;
212 static sp<IMediaAnalyticsService> getInstance();
Ray Essick2ab3c432017-10-02 09:29:49 -0700213 static void dropInstance();
Ray Essick3938dc62016-11-01 08:56:56 -0700214
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
Ray Essickb5fac8e2016-12-12 11:33:56 -0800224 struct Prop {
Ray Essick3938dc62016-11-01 08:56:56 -0700225
226 Type mType;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800227 const char *mName;
228 size_t mNameLen; // the strlen(), doesn't include the null
Ray Essick3938dc62016-11-01 08:56:56 -0700229 union {
230 int32_t int32Value;
231 int64_t int64Value;
232 double doubleValue;
233 char *CStringValue;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800234 struct { int64_t count, duration; } rate;
Ray Essick3938dc62016-11-01 08:56:56 -0700235 } u;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800236 void setName(const char *name, size_t len);
Ray Essick3938dc62016-11-01 08:56:56 -0700237 };
Ray Essickb5fac8e2016-12-12 11:33:56 -0800238
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 };
Ray Essick9bb7e3b2017-10-23 13:01:48 -0700246 bool growProps(int increment = kGrowProps);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800247 size_t findPropIndex(const char *name, size_t len);
248 Prop *findProp(const char *name);
249 Prop *allocateProp(const char *name);
Ray Essickf65f4212017-08-31 11:41:19 -0700250 bool removeProp(const char *name);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800251
252 size_t mPropCount;
253 size_t mPropSize;
254 Prop *mProps;
Ray Essick3938dc62016-11-01 08:56:56 -0700255};
256
257} // namespace android
258
259#endif