blob: ed7b7b16b6dffee3447673aba49bf1bbc55346d2 [file] [log] [blame]
Ray Essick3938dc62016-11-01 08:56:56 -07001/*
Ray Essick2e9c63b2017-03-29 15:16:44 -07002 * Copyright (C) 2017 The Android Open Source Project
Ray Essick3938dc62016-11-01 08:56:56 -07003 *
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
Andy Hung17dbaf22019-10-11 14:06:31 -070017#pragma once
Ray Essick3938dc62016-11-01 08:56:56 -070018
Andy Hung17dbaf22019-10-11 14:06:31 -070019#include <atomic>
20#include <deque>
Ray Essick72a436b2018-06-14 15:08:13 -070021#include <future>
Andy Hung17dbaf22019-10-11 14:06:31 -070022#include <mutex>
23#include <unordered_map>
Ray Essick72a436b2018-06-14 15:08:13 -070024
Andy Hung17dbaf22019-10-11 14:06:31 -070025// IMediaAnalyticsService must include Vector, String16, Errors
Ray Essick3938dc62016-11-01 08:56:56 -070026#include <media/IMediaAnalyticsService.h>
Andy Hung17dbaf22019-10-11 14:06:31 -070027#include <utils/String8.h>
Ray Essick3938dc62016-11-01 08:56:56 -070028
Ray Essick3938dc62016-11-01 08:56:56 -070029namespace android {
30
31class MediaAnalyticsService : public BnMediaAnalyticsService
32{
Andy Hung17dbaf22019-10-11 14:06:31 -070033public:
34 MediaAnalyticsService();
35 ~MediaAnalyticsService() override;
Ray Essick3938dc62016-11-01 08:56:56 -070036
Andy Hungc89c8dc2019-10-16 17:48:21 -070037 /**
38 * Submits the indicated record to the mediaanalytics service, where
39 * it will be merged (if appropriate) with incomplete records that
40 * share the same key and sessionid.
41 *
42 * \param item the item to submit.
43 * \param forcenew marks any matching incomplete record as complete before
44 * inserting this new record.
45 *
46 * \return the sessionID associated with that item or
47 * MediaAnalyticsItem::SessionIDInvalid on failure.
48 *
49 * BEWARE: When called directly on the service (not from the binder interface),
50 * the caller surrenders ownership of item, MediaAnalyticsService will delete
51 * even on error. The binder interface does not take ownership.
52 * TODO: fix this inconsistency with the binder RPC interface.
53 */
54 MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) override;
Ray Essick3938dc62016-11-01 08:56:56 -070055
Andy Hung17dbaf22019-10-11 14:06:31 -070056 status_t dump(int fd, const Vector<String16>& args) override;
Ray Essick3938dc62016-11-01 08:56:56 -070057
Andy Hung17dbaf22019-10-11 14:06:31 -070058 static constexpr const char * const kServiceName = "media.metrics";
Ray Essick3938dc62016-11-01 08:56:56 -070059
Andy Hung17dbaf22019-10-11 14:06:31 -070060private:
61 void processExpirations();
Ray Essick3938dc62016-11-01 08:56:56 -070062 MediaAnalyticsItem::SessionID_t generateUniqueSessionID();
Andy Hung17dbaf22019-10-11 14:06:31 -070063 // input validation after arrival from client
64 static bool isContentValid(const MediaAnalyticsItem *item, bool isTrusted);
65 bool isRateLimited(MediaAnalyticsItem *) const;
66 void saveItem(MediaAnalyticsItem *);
Ray Essick3938dc62016-11-01 08:56:56 -070067
Andy Hung17dbaf22019-10-11 14:06:31 -070068 // The following methods are GUARDED_BY(mLock)
69 bool expirations_l(MediaAnalyticsItem *);
Ray Essick3938dc62016-11-01 08:56:56 -070070
Andy Hung17dbaf22019-10-11 14:06:31 -070071 // support for generating output
72 void dumpQueue_l(String8 &result, int dumpProto);
73 void dumpQueue_l(String8 &result, int dumpProto, nsecs_t, const char *only);
74 void dumpHeaders_l(String8 &result, int dumpProto, nsecs_t ts_since);
75 void dumpSummaries_l(String8 &result, int dumpProto, nsecs_t ts_since, const char * only);
76 void dumpRecent_l(String8 &result, int dumpProto, nsecs_t ts_since, const char * only);
77
78 // The following variables accessed without mLock
Ray Essick3938dc62016-11-01 08:56:56 -070079
Ray Essickf65f4212017-08-31 11:41:19 -070080 // limit how many records we'll retain
81 // by count (in each queue (open, finalized))
Andy Hung17dbaf22019-10-11 14:06:31 -070082 const size_t mMaxRecords;
83 // by time (none older than this)
84 const nsecs_t mMaxRecordAgeNs;
Ray Essick72a436b2018-06-14 15:08:13 -070085 // max to expire per expirations_l() invocation
Andy Hung17dbaf22019-10-11 14:06:31 -070086 const size_t mMaxRecordsExpiredAtOnce;
87 const int mDumpProtoDefault;
Ray Essick3938dc62016-11-01 08:56:56 -070088
Andy Hung17dbaf22019-10-11 14:06:31 -070089 std::atomic<MediaAnalyticsItem::SessionID_t> mLastSessionID{};
Ray Essick3938dc62016-11-01 08:56:56 -070090
Andy Hung17dbaf22019-10-11 14:06:31 -070091 class UidInfo {
92 public:
93 void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);
Ray Essick3938dc62016-11-01 08:56:56 -070094
Andy Hung17dbaf22019-10-11 14:06:31 -070095 private:
96 std::mutex mUidInfoLock;
Ray Essick72a436b2018-06-14 15:08:13 -070097
Andy Hung17dbaf22019-10-11 14:06:31 -070098 struct UidToPkgInfo {
99 uid_t uid = -1;
100 std::string pkg;
101 std::string installer;
102 int64_t versionCode = 0;
103 nsecs_t expiration = 0; // TODO: remove expiration.
104 };
Ray Essick2e9c63b2017-03-29 15:16:44 -0700105
Andy Hung17dbaf22019-10-11 14:06:31 -0700106 // TODO: use concurrent hashmap with striped lock.
107 std::unordered_map<uid_t, struct UidToPkgInfo> mPkgMappings; // GUARDED_BY(mUidInfoLock)
108 } mUidInfo; // mUidInfo can be accessed without lock (locked internally)
Ray Essick3938dc62016-11-01 08:56:56 -0700109
Andy Hung17dbaf22019-10-11 14:06:31 -0700110 std::atomic<int64_t> mItemsSubmitted{}; // accessed outside of lock.
Ray Essickf65f4212017-08-31 11:41:19 -0700111
Andy Hung17dbaf22019-10-11 14:06:31 -0700112 std::mutex mLock;
113 // statistics about our analytics
114 int64_t mItemsFinalized = 0; // GUARDED_BY(mLock)
115 int64_t mItemsDiscarded = 0; // GUARDED_BY(mLock)
116 int64_t mItemsDiscardedExpire = 0; // GUARDED_BY(mLock)
117 int64_t mItemsDiscardedCount = 0; // GUARDED_BY(mLock)
Ray Essickf65f4212017-08-31 11:41:19 -0700118
Andy Hung17dbaf22019-10-11 14:06:31 -0700119 // If we have a worker thread to garbage collect
120 std::future<void> mExpireFuture; // GUARDED_BY(mLock)
121
122 // Our item queue, generally (oldest at front)
123 // TODO: Make separate class, use segmented queue, write lock only end.
124 // Note: Another analytics module might have ownership of an item longer than the log.
125 std::deque<std::shared_ptr<const MediaAnalyticsItem>> mItems; // GUARDED_BY(mLock)
Ray Essick3938dc62016-11-01 08:56:56 -0700126};
127
Andy Hung17dbaf22019-10-11 14:06:31 -0700128} // namespace android