blob: 290ed21306fb341d6de8b83d9762631395367273 [file] [log] [blame]
Andy Hung0f7ad8c2020-01-03 13:24:34 -08001/*
2 * Copyright (C) 2020 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#pragma once
18
19#include "TimeMachine.h"
20#include "TransactionLog.h"
21
22namespace android::mediametrics {
23
24/**
25 * AnalyticsState consists of a TimeMachine and TransactionLog for a set
26 * of MediaMetrics Items.
27 *
28 * One can add new Items with the submit() method.
29 *
30 * The AnalyticsState may be cleared or duplicated to preserve state after crashes
31 * in services are detected.
32 *
33 * As its members may not be moveable due to mutexes, we use this encapsulation
34 * with a shared pointer in order to save it or duplicate it.
35 */
36class AnalyticsState {
37public:
38 /**
39 * Returns success if AnalyticsState accepts the item.
40 *
41 * A trusted source can create a new key, an untrusted source
42 * can only modify the key if the uid will match that authorized
43 * on the existing key.
44 *
45 * \param item the item to be submitted.
46 * \param isTrusted whether the transaction comes from a trusted source.
47 * In this case, a trusted source is verified by binder
48 * UID to be a system service by MediaMetrics service.
49 * Do not use true if you haven't really checked!
50 *
51 * \return NO_ERROR on success or
52 * PERMISSION_DENIED if the item cannot be put into the AnalyticsState.
53 */
54 status_t submit(const std::shared_ptr<const mediametrics::Item>& item, bool isTrusted) {
55 return mTimeMachine.put(item, isTrusted) ?: mTransactionLog.put(item);
56 }
57
58 /**
Andy Hungea186fa2020-01-09 18:13:15 -080059 * Returns the TimeMachine.
60 *
61 * The TimeMachine object is internally locked, so access is safe and defined,
62 * but multiple threaded access may change results after calling.
63 */
64 TimeMachine& timeMachine() { return mTimeMachine; }
65 const TimeMachine& timeMachine() const { return mTimeMachine; }
66
67 /**
68 * Returns the TransactionLog.
69 *
70 * The TransactionLog object is internally locked, so access is safe and defined,
71 * but multiple threaded access may change results after calling.
72 */
73 TransactionLog& transactionLog() { return mTransactionLog; }
74 const TransactionLog& transactionLog() const { return mTransactionLog; }
75
76 /**
Andy Hung0f7ad8c2020-01-03 13:24:34 -080077 * Returns a pair consisting of the dump string, and the number of lines in the string.
78 *
79 * The number of lines in the returned pair is used as an optimization
80 * for subsequent line limiting.
81 *
82 * The TimeMachine and the TransactionLog are dumped separately under
83 * different locks, so may not be 100% consistent with the last data
84 * delivered.
85 *
86 * \param lines the maximum number of lines in the string returned.
87 */
88 std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const {
89 std::stringstream ss;
90 int32_t ll = lines;
91
92 if (ll > 0) {
93 ss << "TransactionLog:\n";
94 --ll;
95 }
96 if (ll > 0) {
97 auto [s, l] = mTransactionLog.dump(ll);
98 ss << s;
99 ll -= l;
100 }
101 if (ll > 0) {
102 ss << "TimeMachine:\n";
103 --ll;
104 }
105 if (ll > 0) {
106 auto [s, l] = mTimeMachine.dump(ll);
107 ss << s;
108 ll -= l;
109 }
110 return { ss.str(), lines - ll };
111 }
112
113 /**
114 * Clears the AnalyticsState.
115 */
116 void clear() {
117 mTimeMachine.clear();
118 mTransactionLog.clear();
119 }
120
121private:
122 // Note: TimeMachine and TransactionLog are individually locked.
123 // Access to these objects under multiple threads will be weakly synchronized,
124 // which is acceptable as modifications only increase the history (or with GC,
125 // eliminates very old history).
126
127 TimeMachine mTimeMachine;
128 TransactionLog mTransactionLog;
129};
130
131} // namespace android::mediametrics