10f0c9b5007ff694d05a91c28359db0553e4dd061Ray Essick/*
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
39class MediaAnalyticsItem {
40
41    friend class MediaAnalyticsService;
42    friend class IMediaAnalyticsService;
43    friend class MediaMetricsJNI;
44    friend class MetricsSummarizer;
45
46    public:
47
48            enum Type {
49                kTypeNone = 0,
50                kTypeInt32 = 1,
51                kTypeInt64 = 2,
52                kTypeDouble = 3,
53                kTypeCString = 4,
54                kTypeRate = 5,
55            };
56
57        // 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
68        typedef AString Key;
69        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
75        typedef const char *Attr;
76
77
78    public:
79
80        // access functions for the class
81        MediaAnalyticsItem();
82        MediaAnalyticsItem(Key);
83        ~MediaAnalyticsItem();
84
85        // so clients can send intermediate values to be overlaid later
86        MediaAnalyticsItem &setFinalized(bool);
87        bool getFinalized() const;
88
89        // SessionID ties multiple submissions for same key together
90        // so that if video "height" and "width" are known at one point
91        // and "framerate" is only known later, they can be be brought
92        // together.
93        MediaAnalyticsItem &setSessionID(SessionID_t);
94        MediaAnalyticsItem &clearSessionID();
95        SessionID_t getSessionID() const;
96        // generates and stores a new ID iff mSessionID == SessionIDNone
97        SessionID_t generateSessionID();
98
99        // reset all contents, discarding any extra data
100        void clear();
101        MediaAnalyticsItem *dup();
102
103        // set the key discriminator for the record.
104        // most often initialized as part of the constructor
105        MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key);
106        MediaAnalyticsItem::Key getKey();
107
108        // # of attributes in the record
109        int32_t count() const;
110
111        // set values appropriately
112        void setInt32(Attr, int32_t value);
113        void setInt64(Attr, int64_t value);
114        void setDouble(Attr, double value);
115        void setRate(Attr, int64_t count, int64_t duration);
116        void setCString(Attr, const char *value);
117
118        // fused get/add/set; if attr wasn't there, it's a simple set.
119        // type-mismatch counts as "wasn't there".
120        void addInt32(Attr, int32_t value);
121        void addInt64(Attr, int64_t value);
122        void addDouble(Attr, double value);
123        void addRate(Attr, int64_t count, int64_t duration);
124
125        // find & extract values
126        // return indicates whether attr exists (and thus value filled in)
127        // NULL parameter value suppresses storage of value.
128        bool getInt32(Attr, int32_t *value);
129        bool getInt64(Attr, int64_t *value);
130        bool getDouble(Attr, double *value);
131        bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
132        // Caller owns the returned string
133        bool getCString(Attr, char **value);
134
135        // parameter indicates whether to close any existing open
136        // record with same key before establishing a new record
137        // caller retains ownership of 'this'.
138        bool selfrecord(bool);
139        bool selfrecord();
140
141        // remove indicated attributes and their values
142        // filterNot() could also be called keepOnly()
143        // return value is # attributes removed
144        // XXX: perhaps 'remove' instead of 'filter'
145        // XXX: filterNot would become 'keep'
146        int32_t filter(int count, Attr attrs[]);
147        int32_t filterNot(int count, Attr attrs[]);
148        int32_t filter(Attr attr);
149
150        // below here are used on server side or to talk to server
151        // clients need not worry about these.
152
153        // timestamp, pid, and uid only used on server side
154        // timestamp is in 'nanoseconds, unix time'
155        MediaAnalyticsItem &setTimestamp(nsecs_t);
156        nsecs_t getTimestamp() const;
157
158        MediaAnalyticsItem &setPid(pid_t);
159        pid_t getPid() const;
160
161        MediaAnalyticsItem &setUid(uid_t);
162        uid_t getUid() const;
163
164        // our serialization code for binder calls
165        int32_t writeToParcel(Parcel *);
166        int32_t readFromParcel(const Parcel&);
167
168        AString toString();
169
170        // are we collecting analytics data
171        static bool isEnabled();
172
173    protected:
174
175        // merge fields from arg into this
176        // with rules for first/last/add, etc
177        // XXX: document semantics and how they are indicated
178        // caller continues to own 'incoming'
179        bool merge(MediaAnalyticsItem *incoming);
180
181        // enabled 1, disabled 0
182        static const char * const EnabledProperty;
183        static const char * const EnabledPropertyPersist;
184        static const int   EnabledProperty_default;
185
186    private:
187
188        // to help validate that A doesn't mess with B's records
189        pid_t     mPid;
190        uid_t     mUid;
191
192        // let's reuse a binder connection
193        static sp<IMediaAnalyticsService> sAnalyticsService;
194        static sp<IMediaAnalyticsService> getInstance();
195
196        // tracking information
197        SessionID_t mSessionID;         // grouping similar records
198        nsecs_t mTimestamp;             // ns, system_time_monotonic
199
200        // will this record accept further updates
201        bool mFinalized;
202
203        Key mKey;
204
205        struct Prop {
206
207            Type mType;
208            const char *mName;
209            size_t mNameLen;    // the strlen(), doesn't include the null
210            union {
211                    int32_t int32Value;
212                    int64_t int64Value;
213                    double doubleValue;
214                    char *CStringValue;
215                    struct { int64_t count, duration; } rate;
216            } u;
217            void setName(const char *name, size_t len);
218        };
219
220        void initProp(Prop *item);
221        void clearProp(Prop *item);
222        void clearPropValue(Prop *item);
223        void copyProp(Prop *dst, const Prop *src);
224        enum {
225            kGrowProps = 10
226        };
227        void growProps(int increment = kGrowProps);
228        size_t findPropIndex(const char *name, size_t len);
229        Prop *findProp(const char *name);
230        Prop *allocateProp(const char *name);
231
232        size_t mPropCount;
233        size_t mPropSize;
234        Prop *mProps;
235};
236
237} // namespace android
238
239#endif
240