1/*
2 * Copyright (C) 2017 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
18#ifndef ANDROID_MEDIAANALYTICSSERVICE_H
19#define ANDROID_MEDIAANALYTICSSERVICE_H
20
21#include <arpa/inet.h>
22
23#include <utils/threads.h>
24#include <utils/Errors.h>
25#include <utils/KeyedVector.h>
26#include <utils/String8.h>
27#include <utils/List.h>
28
29#include <media/IMediaAnalyticsService.h>
30
31#include "MetricsSummarizer.h"
32
33
34namespace android {
35
36class MediaAnalyticsService : public BnMediaAnalyticsService
37{
38
39 public:
40
41    // on this side, caller surrenders ownership
42    virtual int64_t submit(MediaAnalyticsItem *item, bool forcenew);
43
44    static  void            instantiate();
45    virtual status_t        dump(int fd, const Vector<String16>& args);
46
47                            MediaAnalyticsService();
48    virtual                 ~MediaAnalyticsService();
49
50 private:
51    MediaAnalyticsItem::SessionID_t generateUniqueSessionID();
52
53    // statistics about our analytics
54    int64_t mItemsSubmitted;
55    int64_t mItemsFinalized;
56    int64_t mItemsDiscarded;
57    int64_t mItemsDiscardedExpire;
58    int64_t mItemsDiscardedCount;
59    int64_t mSetsDiscarded;
60    MediaAnalyticsItem::SessionID_t mLastSessionID;
61
62    // partitioned a bit so we don't over serialize
63    mutable Mutex           mLock;
64    mutable Mutex           mLock_ids;
65    mutable Mutex           mLock_mappings;
66
67    // limit how many records we'll retain
68    // by count (in each queue (open, finalized))
69    int32_t mMaxRecords;
70    // by time (none older than this long agan
71    nsecs_t mMaxRecordAgeNs;
72    //
73    // # of sets of summaries
74    int32_t mMaxRecordSets;
75    // nsecs until we start a new record set
76    nsecs_t mNewSetInterval;
77
78    // input validation after arrival from client
79    bool contentValid(MediaAnalyticsItem *item, bool isTrusted);
80    bool rateLimited(MediaAnalyticsItem *);
81
82    // the ones that are still open
83    // (newest at front) since we keep looking for them
84    List<MediaAnalyticsItem *> *mOpen;
85    // the ones we've finalized
86    // (oldest at front) so it prints nicely for dumpsys
87    List<MediaAnalyticsItem *> *mFinalized;
88    // searching within these queues: queue, key
89    MediaAnalyticsItem *findItem(List<MediaAnalyticsItem *> *,
90                                     MediaAnalyticsItem *, bool removeit);
91
92    // summarizers
93    void summarize(MediaAnalyticsItem *item);
94    class SummarizerSet {
95        nsecs_t mStarted;
96        List<MetricsSummarizer *> *mSummarizers;
97
98      public:
99        void appendSummarizer(MetricsSummarizer *s) {
100            if (s) {
101                mSummarizers->push_back(s);
102            }
103        };
104        nsecs_t getStarted() { return mStarted;}
105        void setStarted(nsecs_t started) {mStarted = started;}
106        List<MetricsSummarizer *> *getSummarizers() { return mSummarizers;}
107
108        SummarizerSet();
109        ~SummarizerSet();
110    };
111    void newSummarizerSet();
112    List<SummarizerSet *> *mSummarizerSets;
113    SummarizerSet *mCurrentSet;
114    List<MetricsSummarizer *> *getFirstSet() {
115        List<SummarizerSet *>::iterator first = mSummarizerSets->begin();
116        if (first != mSummarizerSets->end()) {
117            return (*first)->getSummarizers();
118        }
119        return NULL;
120    }
121
122    void saveItem(MediaAnalyticsItem);
123    void saveItem(List<MediaAnalyticsItem *> *, MediaAnalyticsItem *, int);
124    void deleteItem(List<MediaAnalyticsItem *> *, MediaAnalyticsItem *);
125
126    // support for generating output
127    int mDumpProto;
128    String8 dumpQueue(List<MediaAnalyticsItem*> *);
129    String8 dumpQueue(List<MediaAnalyticsItem*> *, nsecs_t, const char *only);
130
131    void dumpHeaders(String8 &result, nsecs_t ts_since);
132    void dumpSummaries(String8 &result, nsecs_t ts_since, const char * only);
133    void dumpRecent(String8 &result, nsecs_t ts_since, const char * only);
134
135    // mapping uids to package names
136    struct UidToPkgMap {
137        uid_t uid;
138        AString pkg;
139        AString installer;
140        int32_t versionCode;
141        nsecs_t expiration;
142    };
143
144    KeyedVector<uid_t,struct UidToPkgMap>  mPkgMappings;
145    void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);
146
147};
148
149// ----------------------------------------------------------------------------
150
151}; // namespace android
152
153#endif // ANDROID_MEDIAANALYTICSSERVICE_H
154