| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ANDROID_MEDIA_MEDIAANALYTICSITEM_H |
| #define ANDROID_MEDIA_MEDIAANALYTICSITEM_H |
| |
| #include <cutils/properties.h> |
| #include <sys/types.h> |
| #include <utils/Errors.h> |
| #include <utils/KeyedVector.h> |
| #include <utils/RefBase.h> |
| #include <utils/StrongPointer.h> |
| #include <utils/Timers.h> |
| |
| #include <media/stagefright/foundation/AString.h> |
| |
| namespace android { |
| |
| |
| |
| class IMediaAnalyticsService; |
| |
| // the class interface |
| // |
| |
| class MediaAnalyticsItem { |
| |
| friend class MediaAnalyticsService; |
| friend class IMediaAnalyticsService; |
| friend class MediaMetricsJNI; |
| friend class MetricsSummarizer; |
| friend class MediaMetricsDeathNotifier; |
| |
| public: |
| |
| enum Type { |
| kTypeNone = 0, |
| kTypeInt32 = 1, |
| kTypeInt64 = 2, |
| kTypeDouble = 3, |
| kTypeCString = 4, |
| kTypeRate = 5, |
| }; |
| |
| // sessionid |
| // unique within device, within boot, |
| typedef int64_t SessionID_t; |
| static constexpr SessionID_t SessionIDInvalid = -1; |
| static constexpr SessionID_t SessionIDNone = 0; |
| |
| // Key: the record descriminator |
| // values for the record discriminator |
| // values can be "component/component" |
| // basic values: "video", "audio", "drm" |
| // XXX: need to better define the format |
| typedef AString Key; |
| static const Key kKeyNone; // "" |
| static const Key kKeyAny; // "*" |
| |
| // Attr: names for attributes within a record |
| // format "prop1" or "prop/subprop" |
| // XXX: need to better define the format |
| typedef const char *Attr; |
| |
| |
| enum { |
| PROTO_V0 = 0, |
| PROTO_FIRST = PROTO_V0, |
| PROTO_V1 = 1, |
| PROTO_LAST = PROTO_V1, |
| }; |
| |
| |
| public: |
| |
| // access functions for the class |
| MediaAnalyticsItem(); |
| MediaAnalyticsItem(Key); |
| ~MediaAnalyticsItem(); |
| |
| // so clients can send intermediate values to be overlaid later |
| MediaAnalyticsItem &setFinalized(bool); |
| bool getFinalized() const; |
| |
| // SessionID ties multiple submissions for same key together |
| // so that if video "height" and "width" are known at one point |
| // and "framerate" is only known later, they can be be brought |
| // together. |
| MediaAnalyticsItem &setSessionID(SessionID_t); |
| MediaAnalyticsItem &clearSessionID(); |
| SessionID_t getSessionID() const; |
| // generates and stores a new ID iff mSessionID == SessionIDNone |
| SessionID_t generateSessionID(); |
| |
| // reset all contents, discarding any extra data |
| void clear(); |
| MediaAnalyticsItem *dup(); |
| |
| // set the key discriminator for the record. |
| // most often initialized as part of the constructor |
| MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key); |
| MediaAnalyticsItem::Key getKey(); |
| |
| // # of attributes in the record |
| int32_t count() const; |
| |
| // set values appropriately |
| void setInt32(Attr, int32_t value); |
| void setInt64(Attr, int64_t value); |
| void setDouble(Attr, double value); |
| void setRate(Attr, int64_t count, int64_t duration); |
| void setCString(Attr, const char *value); |
| |
| // fused get/add/set; if attr wasn't there, it's a simple set. |
| // type-mismatch counts as "wasn't there". |
| void addInt32(Attr, int32_t value); |
| void addInt64(Attr, int64_t value); |
| void addDouble(Attr, double value); |
| void addRate(Attr, int64_t count, int64_t duration); |
| |
| // find & extract values |
| // return indicates whether attr exists (and thus value filled in) |
| // NULL parameter value suppresses storage of value. |
| bool getInt32(Attr, int32_t *value); |
| bool getInt64(Attr, int64_t *value); |
| bool getDouble(Attr, double *value); |
| bool getRate(Attr, int64_t *count, int64_t *duration, double *rate); |
| // Caller owns the returned string |
| bool getCString(Attr, char **value); |
| |
| // parameter indicates whether to close any existing open |
| // record with same key before establishing a new record |
| // caller retains ownership of 'this'. |
| bool selfrecord(bool); |
| bool selfrecord(); |
| |
| // remove indicated attributes and their values |
| // filterNot() could also be called keepOnly() |
| // return value is # attributes removed |
| // XXX: perhaps 'remove' instead of 'filter' |
| // XXX: filterNot would become 'keep' |
| int32_t filter(int count, Attr attrs[]); |
| int32_t filterNot(int count, Attr attrs[]); |
| int32_t filter(Attr attr); |
| |
| // below here are used on server side or to talk to server |
| // clients need not worry about these. |
| |
| // timestamp, pid, and uid only used on server side |
| // timestamp is in 'nanoseconds, unix time' |
| MediaAnalyticsItem &setTimestamp(nsecs_t); |
| nsecs_t getTimestamp() const; |
| |
| MediaAnalyticsItem &setPid(pid_t); |
| pid_t getPid() const; |
| |
| MediaAnalyticsItem &setUid(uid_t); |
| uid_t getUid() const; |
| |
| MediaAnalyticsItem &setPkgName(AString); |
| AString getPkgName() const; |
| |
| MediaAnalyticsItem &setPkgVersionCode(int32_t); |
| int32_t getPkgVersionCode() const; |
| |
| // our serialization code for binder calls |
| int32_t writeToParcel(Parcel *); |
| int32_t readFromParcel(const Parcel&); |
| |
| AString toString(); |
| AString toString(int version); |
| |
| // are we collecting analytics data |
| static bool isEnabled(); |
| |
| protected: |
| |
| // merge fields from arg into this |
| // with rules for first/last/add, etc |
| // XXX: document semantics and how they are indicated |
| // caller continues to own 'incoming' |
| bool merge(MediaAnalyticsItem *incoming); |
| |
| // enabled 1, disabled 0 |
| static const char * const EnabledProperty; |
| static const char * const EnabledPropertyPersist; |
| static const int EnabledProperty_default; |
| |
| private: |
| |
| // to help validate that A doesn't mess with B's records |
| pid_t mPid; |
| uid_t mUid; |
| AString mPkgName; |
| int32_t mPkgVersionCode; |
| |
| // let's reuse a binder connection |
| static sp<IMediaAnalyticsService> sAnalyticsService; |
| static sp<IMediaAnalyticsService> getInstance(); |
| static void dropInstance(); |
| |
| // tracking information |
| SessionID_t mSessionID; // grouping similar records |
| nsecs_t mTimestamp; // ns, system_time_monotonic |
| |
| // will this record accept further updates |
| bool mFinalized; |
| |
| Key mKey; |
| |
| struct Prop { |
| |
| Type mType; |
| const char *mName; |
| size_t mNameLen; // the strlen(), doesn't include the null |
| union { |
| int32_t int32Value; |
| int64_t int64Value; |
| double doubleValue; |
| char *CStringValue; |
| struct { int64_t count, duration; } rate; |
| } u; |
| void setName(const char *name, size_t len); |
| }; |
| |
| void initProp(Prop *item); |
| void clearProp(Prop *item); |
| void clearPropValue(Prop *item); |
| void copyProp(Prop *dst, const Prop *src); |
| enum { |
| kGrowProps = 10 |
| }; |
| bool growProps(int increment = kGrowProps); |
| size_t findPropIndex(const char *name, size_t len); |
| Prop *findProp(const char *name); |
| Prop *allocateProp(const char *name); |
| bool removeProp(const char *name); |
| |
| size_t mPropCount; |
| size_t mPropSize; |
| Prop *mProps; |
| }; |
| |
| } // namespace android |
| |
| #endif |