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#pragma once
18
19#include <gtest/gtest_prod.h>
20#include "config/ConfigListener.h"
21#include "logd/LogReader.h"
22#include "metrics/MetricsManager.h"
23#include "packages/UidMap.h"
24#include "external/StatsPullerManager.h"
25
26#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
27
28#include <stdio.h>
29#include <unordered_map>
30
31namespace android {
32namespace os {
33namespace statsd {
34
35// Keep this in sync with DumpReportReason enum in stats_log.proto
36enum DumpReportReason {
37    DEVICE_SHUTDOWN = 1,
38    CONFIG_UPDATED = 2,
39    CONFIG_REMOVED = 3,
40    GET_DATA_CALLED = 4,
41    ADB_DUMP = 5,
42    CONFIG_RESET = 6,
43    STATSCOMPANION_DIED = 7
44};
45
46class StatsLogProcessor : public ConfigListener {
47public:
48    StatsLogProcessor(const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
49                      const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor,
50                      const int64_t timeBaseNs,
51                      const std::function<bool(const ConfigKey&)>& sendBroadcast);
52    virtual ~StatsLogProcessor();
53
54    void OnLogEvent(LogEvent* event, bool reconnectionStarts);
55
56    // for testing only.
57    void OnLogEvent(LogEvent* event);
58
59    void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
60                         const StatsdConfig& config);
61    void OnConfigRemoved(const ConfigKey& key);
62
63    size_t GetMetricsSize(const ConfigKey& key) const;
64
65    void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
66                      const bool include_current_partial_bucket,
67                      const DumpReportReason dumpReportReason, vector<uint8_t>* outData);
68
69    /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
70    void onAnomalyAlarmFired(
71            const int64_t& timestampNs,
72            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
73
74    /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
75    void onPeriodicAlarmFired(
76            const int64_t& timestampNs,
77            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
78
79    /* Flushes data to disk. Data on memory will be gone after written to disk. */
80    void WriteDataToDisk(const DumpReportReason dumpReportReason);
81
82    // Reset all configs.
83    void resetConfigs();
84
85    inline sp<UidMap> getUidMap() {
86        return mUidMap;
87    }
88
89    void dumpStates(FILE* out, bool verbose);
90
91    void informPullAlarmFired(const int64_t timestampNs);
92
93    int64_t getLastReportTimeNs(const ConfigKey& key);
94
95    inline void setPrintLogs(bool enabled) {
96#ifdef VERY_VERBOSE_PRINTING
97        std::lock_guard<std::mutex> lock(mMetricsMutex);
98        mPrintAllLogs = enabled;
99#endif
100    }
101
102    // Add a specific config key to the possible configs to dump ASAP.
103    void noteOnDiskData(const ConfigKey& key);
104
105private:
106    // For testing only.
107    inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
108        return mAnomalyAlarmMonitor;
109    }
110
111    inline sp<AlarmMonitor> getPeriodicAlarmMonitor() const {
112        return mPeriodicAlarmMonitor;
113    }
114
115    mutable mutex mMetricsMutex;
116
117    std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
118
119    std::unordered_map<ConfigKey, long> mLastBroadcastTimes;
120
121    // Tracks when we last checked the bytes consumed for each config key.
122    std::unordered_map<ConfigKey, long> mLastByteSizeTimes;
123
124    // Tracks which config keys has metric reports on disk
125    std::set<ConfigKey> mOnDiskDataConfigs;
126
127    sp<UidMap> mUidMap;  // Reference to the UidMap to lookup app name and version for each uid.
128
129    StatsPullerManager mStatsPullerManager;
130
131    sp<AlarmMonitor> mAnomalyAlarmMonitor;
132
133    sp<AlarmMonitor> mPeriodicAlarmMonitor;
134
135    void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
136
137    void OnConfigUpdatedLocked(
138        const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
139
140    void WriteDataToDiskLocked(const DumpReportReason dumpReportReason);
141    void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
142                               const DumpReportReason dumpReportReason);
143
144    void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs,
145                                     const bool include_current_partial_bucket,
146                                     const DumpReportReason dumpReportReason,
147                                     util::ProtoOutputStream* proto);
148
149    /* Check if we should send a broadcast if approaching memory limits and if we're over, we
150     * actually delete the data. */
151    void flushIfNecessaryLocked(int64_t timestampNs, const ConfigKey& key,
152                                MetricsManager& metricsManager);
153
154    // Maps the isolated uid in the log event to host uid if the log event contains uid fields.
155    void mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const;
156
157    // Handler over the isolated uid change event.
158    void onIsolatedUidChangedEventLocked(const LogEvent& event);
159
160    // Reset all configs.
161    void resetConfigsLocked(const int64_t timestampNs);
162    // Reset the specified configs.
163    void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
164
165    // Function used to send a broadcast so that receiver for the config key can call getData
166    // to retrieve the stored data.
167    std::function<bool(const ConfigKey& key)> mSendBroadcast;
168
169    const int64_t mTimeBaseNs;
170
171    // Largest timestamp of the events that we have processed.
172    int64_t mLargestTimestampSeen = 0;
173
174    int64_t mLastTimestampSeen = 0;
175
176    bool mInReconnection = false;
177
178    // Processed log count
179    uint64_t mLogCount = 0;
180
181    // Log loss detected count
182    int mLogLossCount = 0;
183
184    long mLastPullerCacheClearTimeSec = 0;
185
186#ifdef VERY_VERBOSE_PRINTING
187    bool mPrintAllLogs = false;
188#endif
189
190    FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
191    FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
192    FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
193    FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
194    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
195    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
196    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
197    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1);
198    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2);
199    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3);
200    FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1);
201    FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2);
202    FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
203    FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
204    FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
205    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
206    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
207    FRIEND_TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents);
208    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
209    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
210
211    FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
212    FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition);
213    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition);
214    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition);
215
216    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition);
217    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
218    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);
219
220    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
221    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
222    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);
223
224    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
225    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
226    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
227    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
228    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
229
230    FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
231    FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
232};
233
234}  // namespace statsd
235}  // namespace os
236}  // namespace android
237