• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 namespace android {
30 
31 class IMediaAnalyticsService;
32 class Parcel;
33 
34 // the class interface
35 //
36 
37 class 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);
getPkgName()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