blob: 5bdc48f07da4ecce682399fd2d22a024ca375eeb [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
Andy Hung06f3aba2019-12-03 16:36:42 -080029#include "AudioAnalytics.h"
30
Ray Essick3938dc62016-11-01 08:56:56 -070031namespace android {
32
33class MediaAnalyticsService : public BnMediaAnalyticsService
34{
Andy Hung17dbaf22019-10-11 14:06:31 -070035public:
36 MediaAnalyticsService();
37 ~MediaAnalyticsService() override;
Ray Essick3938dc62016-11-01 08:56:56 -070038
Andy Hungc89c8dc2019-10-16 17:48:21 -070039 /**
Andy Hunga87e69c2019-10-18 10:07:40 -070040 * Submits the indicated record to the mediaanalytics service.
Andy Hungc89c8dc2019-10-16 17:48:21 -070041 *
42 * \param item the item to submit.
Andy Hunga87e69c2019-10-18 10:07:40 -070043 * \return status failure, which is negative on binder transaction failure.
44 * As the transaction is one-way, remote failures will not be reported.
Andy Hungc89c8dc2019-10-16 17:48:21 -070045 */
Andy Hunga87e69c2019-10-18 10:07:40 -070046 status_t submit(MediaAnalyticsItem *item) override {
47 return submitInternal(item, false /* release */);
48 }
Ray Essick3938dc62016-11-01 08:56:56 -070049
Andy Hung1efc9c62019-12-03 13:43:33 -080050 status_t submitBuffer(const char *buffer, size_t length) override {
51 MediaAnalyticsItem *item = new MediaAnalyticsItem();
52 return item->readFromByteString(buffer, length)
53 ?: submitInternal(item, true /* release */);
54 }
55
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 Hung55aaf522019-12-03 15:07:51 -080060 /**
61 * Rounds time to the nearest second.
62 */
63 static nsecs_t roundTime(nsecs_t timeNs);
64
Andy Hunga87e69c2019-10-18 10:07:40 -070065protected:
66
67 // Internal call where release is true if ownership of item is transferred
68 // to the service (that is, the service will eventually delete the item).
69 status_t submitInternal(MediaAnalyticsItem *item, bool release) override;
70
Andy Hung17dbaf22019-10-11 14:06:31 -070071private:
72 void processExpirations();
Andy Hung17dbaf22019-10-11 14:06:31 -070073 // input validation after arrival from client
74 static bool isContentValid(const MediaAnalyticsItem *item, bool isTrusted);
75 bool isRateLimited(MediaAnalyticsItem *) const;
Andy Hung82a074b2019-12-03 14:16:45 -080076 void saveItem(const std::shared_ptr<const MediaAnalyticsItem>& item);
Ray Essick3938dc62016-11-01 08:56:56 -070077
Andy Hung17dbaf22019-10-11 14:06:31 -070078 // The following methods are GUARDED_BY(mLock)
Andy Hung82a074b2019-12-03 14:16:45 -080079 bool expirations_l(const std::shared_ptr<const MediaAnalyticsItem>& item);
Ray Essick3938dc62016-11-01 08:56:56 -070080
Andy Hung17dbaf22019-10-11 14:06:31 -070081 // support for generating output
82 void dumpQueue_l(String8 &result, int dumpProto);
83 void dumpQueue_l(String8 &result, int dumpProto, nsecs_t, const char *only);
84 void dumpHeaders_l(String8 &result, int dumpProto, nsecs_t ts_since);
85 void dumpSummaries_l(String8 &result, int dumpProto, nsecs_t ts_since, const char * only);
86 void dumpRecent_l(String8 &result, int dumpProto, nsecs_t ts_since, const char * only);
87
88 // The following variables accessed without mLock
Ray Essick3938dc62016-11-01 08:56:56 -070089
Ray Essickf65f4212017-08-31 11:41:19 -070090 // limit how many records we'll retain
91 // by count (in each queue (open, finalized))
Andy Hung17dbaf22019-10-11 14:06:31 -070092 const size_t mMaxRecords;
93 // by time (none older than this)
94 const nsecs_t mMaxRecordAgeNs;
Ray Essick72a436b2018-06-14 15:08:13 -070095 // max to expire per expirations_l() invocation
Andy Hung17dbaf22019-10-11 14:06:31 -070096 const size_t mMaxRecordsExpiredAtOnce;
97 const int mDumpProtoDefault;
Ray Essick3938dc62016-11-01 08:56:56 -070098
Andy Hung17dbaf22019-10-11 14:06:31 -070099 class UidInfo {
100 public:
101 void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);
Ray Essick3938dc62016-11-01 08:56:56 -0700102
Andy Hung17dbaf22019-10-11 14:06:31 -0700103 private:
104 std::mutex mUidInfoLock;
Ray Essick72a436b2018-06-14 15:08:13 -0700105
Andy Hung17dbaf22019-10-11 14:06:31 -0700106 struct UidToPkgInfo {
107 uid_t uid = -1;
108 std::string pkg;
109 std::string installer;
110 int64_t versionCode = 0;
111 nsecs_t expiration = 0; // TODO: remove expiration.
112 };
Ray Essick2e9c63b2017-03-29 15:16:44 -0700113
Andy Hung17dbaf22019-10-11 14:06:31 -0700114 // TODO: use concurrent hashmap with striped lock.
115 std::unordered_map<uid_t, struct UidToPkgInfo> mPkgMappings; // GUARDED_BY(mUidInfoLock)
116 } mUidInfo; // mUidInfo can be accessed without lock (locked internally)
Ray Essick3938dc62016-11-01 08:56:56 -0700117
Andy Hung17dbaf22019-10-11 14:06:31 -0700118 std::atomic<int64_t> mItemsSubmitted{}; // accessed outside of lock.
Ray Essickf65f4212017-08-31 11:41:19 -0700119
Andy Hung06f3aba2019-12-03 16:36:42 -0800120 mediametrics::AudioAnalytics mAudioAnalytics;
121
Andy Hung17dbaf22019-10-11 14:06:31 -0700122 std::mutex mLock;
123 // statistics about our analytics
124 int64_t mItemsFinalized = 0; // GUARDED_BY(mLock)
125 int64_t mItemsDiscarded = 0; // GUARDED_BY(mLock)
126 int64_t mItemsDiscardedExpire = 0; // GUARDED_BY(mLock)
127 int64_t mItemsDiscardedCount = 0; // GUARDED_BY(mLock)
Ray Essickf65f4212017-08-31 11:41:19 -0700128
Andy Hung17dbaf22019-10-11 14:06:31 -0700129 // If we have a worker thread to garbage collect
130 std::future<void> mExpireFuture; // GUARDED_BY(mLock)
131
132 // Our item queue, generally (oldest at front)
133 // TODO: Make separate class, use segmented queue, write lock only end.
134 // Note: Another analytics module might have ownership of an item longer than the log.
135 std::deque<std::shared_ptr<const MediaAnalyticsItem>> mItems; // GUARDED_BY(mLock)
Ray Essick3938dc62016-11-01 08:56:56 -0700136};
137
Andy Hung17dbaf22019-10-11 14:06:31 -0700138} // namespace android