1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma once
16
17 #include <aidl/android/os/BnPullAtomCallback.h>
18 #include <aidl/android/os/IPullAtomCallback.h>
19 #include <aidl/android/os/IPullAtomResultReceiver.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
24 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
25 #include "src/StatsLogProcessor.h"
26 #include "src/hash.h"
27 #include "src/logd/LogEvent.h"
28 #include "src/packages/UidMap.h"
29 #include "src/stats_log_util.h"
30 #include "stats_event.h"
31 #include "statslog_statsdtest.h"
32
33 namespace android {
34 namespace os {
35 namespace statsd {
36
37 using namespace testing;
38 using ::aidl::android::os::BnPullAtomCallback;
39 using ::aidl::android::os::IPullAtomCallback;
40 using ::aidl::android::os::IPullAtomResultReceiver;
41 using android::util::ProtoReader;
42 using google::protobuf::RepeatedPtrField;
43 using Status = ::ndk::ScopedAStatus;
44
45 const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED;
46 const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED;
47
48 enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE };
49
50 class MockUidMap : public UidMap {
51 public:
52 MOCK_METHOD(int, getHostUidOrSelf, (int uid), (const));
53 MOCK_METHOD(std::set<int32_t>, getAppUid, (const string& package), (const));
54 };
55
56 // Converts a ProtoOutputStream to a StatsLogReport proto.
57 StatsLogReport outputStreamToProto(ProtoOutputStream* proto);
58
59 // Create AtomMatcher proto to simply match a specific atom type.
60 AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
61
62 // Create AtomMatcher proto for temperature atom.
63 AtomMatcher CreateTemperatureAtomMatcher();
64
65 // Create AtomMatcher proto for scheduled job state changed.
66 AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
67
68 // Create AtomMatcher proto for starting a scheduled job.
69 AtomMatcher CreateStartScheduledJobAtomMatcher();
70
71 // Create AtomMatcher proto for a scheduled job is done.
72 AtomMatcher CreateFinishScheduledJobAtomMatcher();
73
74 // Create AtomMatcher proto for screen brightness state changed.
75 AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
76
77 // Create AtomMatcher proto for starting battery save mode.
78 AtomMatcher CreateBatterySaverModeStartAtomMatcher();
79
80 // Create AtomMatcher proto for stopping battery save mode.
81 AtomMatcher CreateBatterySaverModeStopAtomMatcher();
82
83 // Create AtomMatcher proto for battery state none mode.
84 AtomMatcher CreateBatteryStateNoneMatcher();
85
86 // Create AtomMatcher proto for battery state usb mode.
87 AtomMatcher CreateBatteryStateUsbMatcher();
88
89 // Create AtomMatcher proto for process state changed.
90 AtomMatcher CreateUidProcessStateChangedAtomMatcher();
91
92 // Create AtomMatcher proto for acquiring wakelock.
93 AtomMatcher CreateAcquireWakelockAtomMatcher();
94
95 // Create AtomMatcher proto for releasing wakelock.
96 AtomMatcher CreateReleaseWakelockAtomMatcher() ;
97
98 // Create AtomMatcher proto for screen turned on.
99 AtomMatcher CreateScreenTurnedOnAtomMatcher();
100
101 // Create AtomMatcher proto for screen turned off.
102 AtomMatcher CreateScreenTurnedOffAtomMatcher();
103
104 // Create AtomMatcher proto for app sync turned on.
105 AtomMatcher CreateSyncStartAtomMatcher();
106
107 // Create AtomMatcher proto for app sync turned off.
108 AtomMatcher CreateSyncEndAtomMatcher();
109
110 // Create AtomMatcher proto for app sync moves to background.
111 AtomMatcher CreateMoveToBackgroundAtomMatcher();
112
113 // Create AtomMatcher proto for app sync moves to foreground.
114 AtomMatcher CreateMoveToForegroundAtomMatcher();
115
116 // Create AtomMatcher proto for process crashes
117 AtomMatcher CreateProcessCrashAtomMatcher() ;
118
119 // Create Predicate proto for screen is on.
120 Predicate CreateScreenIsOnPredicate();
121
122 // Create Predicate proto for screen is off.
123 Predicate CreateScreenIsOffPredicate();
124
125 // Create Predicate proto for a running scheduled job.
126 Predicate CreateScheduledJobPredicate();
127
128 // Create Predicate proto for battery saver mode.
129 Predicate CreateBatterySaverModePredicate();
130
131 // Create Predicate proto for device unplogged mode.
132 Predicate CreateDeviceUnpluggedPredicate();
133
134 // Create Predicate proto for holding wakelock.
135 Predicate CreateHoldingWakelockPredicate();
136
137 // Create a Predicate proto for app syncing.
138 Predicate CreateIsSyncingPredicate();
139
140 // Create a Predicate proto for app is in background.
141 Predicate CreateIsInBackgroundPredicate();
142
143 // Create State proto for screen state atom.
144 State CreateScreenState();
145
146 // Create State proto for uid process state atom.
147 State CreateUidProcessState();
148
149 // Create State proto for overlay state atom.
150 State CreateOverlayState();
151
152 // Create State proto for screen state atom with on/off map.
153 State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId);
154
155 // Create State proto for screen state atom with simple on/off map.
156 State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
157
158 // Create StateGroup proto for ScreenState ON group
159 StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId);
160
161 // Create StateGroup proto for ScreenState OFF group
162 StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId);
163
164 // Create StateGroup proto for simple ScreenState ON group
165 StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId);
166
167 // Create StateGroup proto for simple ScreenState OFF group
168 StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId);
169
170 // Create StateMap proto for ScreenState ON/OFF map
171 StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId);
172
173 // Create StateMap proto for simple ScreenState ON/OFF map
174 StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
175
176 // Add a predicate to the predicate combination.
177 void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
178
179 // Create dimensions from primitive fields.
180 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
181
182 // Create dimensions by attribution uid and tag.
183 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
184 const std::vector<Position>& positions);
185
186 // Create dimensions by attribution uid only.
187 FieldMatcher CreateAttributionUidDimensions(const int atomId,
188 const std::vector<Position>& positions);
189
190 FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
191 const std::vector<Position>& positions,
192 const std::vector<int>& fields);
193
194 // START: get primary key functions
195 // These functions take in atom field information and create FieldValues which are stored in the
196 // given HashableDimensionKey.
197 void getUidProcessKey(int uid, HashableDimensionKey* key);
198
199 void getOverlayKey(int uid, string packageName, HashableDimensionKey* key);
200
201 void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key);
202
203 void getPartialWakelockKey(int uid, HashableDimensionKey* key);
204 // END: get primary key functions
205
206 void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
207 const vector<string>& attributionTags);
208
209 // Builds statsEvent to get buffer that is parsed into logEvent then releases statsEvent.
210 void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
211
212 shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
213 int32_t value2);
214
215 void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
216 int32_t value2);
217
218 shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
219 int32_t value2, int32_t value3);
220
221 void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
222 int32_t value2, int32_t value3);
223
224 // The repeated value log event helpers create a log event with two int fields, both
225 // set to the same value. This is useful for testing metrics that are only interested
226 // in the value of the second field but still need the first field to be populated.
227 std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs,
228 int32_t value);
229
230 void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
231 int32_t value);
232
233 std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs);
234
235 void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs);
236
237 std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
238 int data2);
239
240 std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
241 const vector<int>& uids,
242 const vector<string>& tags, int data1, int data2);
243
244 sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids);
245
246 sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids);
247
248 // Create log event for screen state changed.
249 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
250 const android::view::DisplayStateEnum state,
251 int loggerUid = 0);
252
253 // Create log event for screen brightness state changed.
254 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);
255
256 // Create log event when scheduled job starts.
257 std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
258 const vector<int>& attributionUids,
259 const vector<string>& attributionTags,
260 const string& jobName);
261
262 // Create log event when scheduled job finishes.
263 std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
264 const vector<int>& attributionUids,
265 const vector<string>& attributionTags,
266 const string& jobName);
267
268 // Create log event when battery saver starts.
269 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
270 // Create log event when battery saver stops.
271 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs);
272
273 // Create log event when battery state changes.
274 std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state);
275
276 // Create log event for app moving to background.
277 std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid);
278
279 // Create log event for app moving to foreground.
280 std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid);
281
282 // Create log event when the app sync starts.
283 std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs, const vector<int>& uids,
284 const vector<string>& tags, const string& name);
285
286 // Create log event when the app sync ends.
287 std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs, const vector<int>& uids,
288 const vector<string>& tags, const string& name);
289
290 // Create log event when the app sync ends.
291 std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid);
292
293 // Create log event for an app crash.
294 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid);
295
296 // Create log event for acquiring wakelock.
297 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
298 const vector<string>& tags,
299 const string& wakelockName);
300
301 // Create log event for releasing wakelock.
302 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
303 const vector<string>& tags,
304 const string& wakelockName);
305
306 // Create log event for releasing wakelock.
307 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
308 int isolatedUid, bool is_create);
309
310 // Create log event for uid process state change.
311 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
312 uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state);
313
314 std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
315 const vector<int>& attributionUids,
316 const vector<string>& attributionTags,
317 const BleScanStateChanged::State state,
318 const bool filtered, const bool firstMatch,
319 const bool opportunistic);
320
321 std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
322 const string& packageName,
323 const bool usingAlertWindow,
324 const OverlayStateChanged::State state);
325
326 // Create a statsd log event processor upon the start time in seconds, config and key.
327 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
328 const StatsdConfig& config, const ConfigKey& key,
329 const shared_ptr<IPullAtomCallback>& puller = nullptr,
330 const int32_t atomTag = 0 /*for puller only*/,
331 const sp<UidMap> = new UidMap());
332
333 // Util function to sort the log events by timestamp.
334 void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
335
336 int64_t StringToId(const string& str);
337
338 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
339 const int uid, const string& tag);
340 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid);
341 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid);
342 void ValidateAttributionUidAndTagDimension(
343 const DimensionsValue& value, int atomId, int uid, const std::string& tag);
344 void ValidateAttributionUidAndTagDimension(
345 const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag);
346
347 struct DimensionsPair {
DimensionsPairDimensionsPair348 DimensionsPair(DimensionsValue m1, google::protobuf::RepeatedPtrField<StateValue> m2)
349 : dimInWhat(m1), stateValues(m2){};
350
351 DimensionsValue dimInWhat;
352 google::protobuf::RepeatedPtrField<StateValue> stateValues;
353 };
354
355 bool LessThan(const StateValue& s1, const StateValue& s2);
356 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
357 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
358
359
360 void backfillStartEndTimestamp(ConfigMetricsReport *config_report);
361 void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list);
362
363 void backfillStringInReport(ConfigMetricsReportList *config_report_list);
364 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
365 DimensionsValue* dimension);
366
367 template <typename T>
backfillStringInDimension(const std::map<uint64_t,string> & str_map,T * metrics)368 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
369 T* metrics) {
370 for (int i = 0; i < metrics->data_size(); ++i) {
371 auto data = metrics->mutable_data(i);
372 if (data->has_dimensions_in_what()) {
373 backfillStringInDimension(str_map, data->mutable_dimensions_in_what());
374 }
375 if (data->has_dimensions_in_condition()) {
376 backfillStringInDimension(str_map, data->mutable_dimensions_in_condition());
377 }
378 }
379 }
380
381 void backfillDimensionPath(ConfigMetricsReportList* config_report_list);
382
383 bool backfillDimensionPath(const DimensionsValue& path,
384 const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
385 DimensionsValue* dimension);
386
387 class FakeSubsystemSleepCallback : public BnPullAtomCallback {
388 public:
389 Status onPullAtom(int atomTag,
390 const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override;
391 };
392
393 template <typename T>
backfillDimensionPath(const DimensionsValue & whatPath,const DimensionsValue & conditionPath,T * metricData)394 void backfillDimensionPath(const DimensionsValue& whatPath,
395 const DimensionsValue& conditionPath,
396 T* metricData) {
397 for (int i = 0; i < metricData->data_size(); ++i) {
398 auto data = metricData->mutable_data(i);
399 if (data->dimension_leaf_values_in_what_size() > 0) {
400 backfillDimensionPath(whatPath, data->dimension_leaf_values_in_what(),
401 data->mutable_dimensions_in_what());
402 data->clear_dimension_leaf_values_in_what();
403 }
404 if (data->dimension_leaf_values_in_condition_size() > 0) {
405 backfillDimensionPath(conditionPath, data->dimension_leaf_values_in_condition(),
406 data->mutable_dimensions_in_condition());
407 data->clear_dimension_leaf_values_in_condition();
408 }
409 }
410 }
411
412 struct DimensionCompare {
operatorDimensionCompare413 bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
414 return LessThan(s1, s2);
415 }
416 };
417
418 template <typename T>
sortMetricDataByDimensionsValue(const T & metricData,T * sortedMetricData)419 void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) {
420 std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap;
421 for (int i = 0; i < metricData.data_size(); ++i) {
422 dimensionIndexMap.insert(
423 std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
424 metricData.data(i).slice_by_state()),
425 i));
426 }
427 for (const auto& itr : dimensionIndexMap) {
428 *sortedMetricData->add_data() = metricData.data(itr.second);
429 }
430 }
431
432 template <typename T>
backfillStartEndTimestampForFullBucket(const int64_t timeBaseNs,const int64_t bucketSizeNs,T * bucket)433 void backfillStartEndTimestampForFullBucket(
434 const int64_t timeBaseNs, const int64_t bucketSizeNs, T* bucket) {
435 bucket->set_start_bucket_elapsed_nanos(timeBaseNs + bucketSizeNs * bucket->bucket_num());
436 bucket->set_end_bucket_elapsed_nanos(
437 timeBaseNs + bucketSizeNs * bucket->bucket_num() + bucketSizeNs);
438 bucket->clear_bucket_num();
439 }
440
441 template <typename T>
backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs,T * bucket)442 void backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs, T* bucket) {
443 if (bucket->has_start_bucket_elapsed_millis()) {
444 bucket->set_start_bucket_elapsed_nanos(
445 MillisToNano(bucket->start_bucket_elapsed_millis()));
446 bucket->clear_start_bucket_elapsed_millis();
447 }
448 if (bucket->has_end_bucket_elapsed_millis()) {
449 bucket->set_end_bucket_elapsed_nanos(
450 MillisToNano(bucket->end_bucket_elapsed_millis()));
451 bucket->clear_end_bucket_elapsed_millis();
452 }
453 }
454
455 template <typename T>
backfillStartEndTimestampForMetrics(const int64_t timeBaseNs,const int64_t bucketSizeNs,T * metrics)456 void backfillStartEndTimestampForMetrics(const int64_t timeBaseNs, const int64_t bucketSizeNs,
457 T* metrics) {
458 for (int i = 0; i < metrics->data_size(); ++i) {
459 auto data = metrics->mutable_data(i);
460 for (int j = 0; j < data->bucket_info_size(); ++j) {
461 auto bucket = data->mutable_bucket_info(j);
462 if (bucket->has_bucket_num()) {
463 backfillStartEndTimestampForFullBucket(timeBaseNs, bucketSizeNs, bucket);
464 } else {
465 backfillStartEndTimestampForPartialBucket(timeBaseNs, bucket);
466 }
467 }
468 }
469 }
470
471 template <typename T>
backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs,T * metrics)472 void backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs, T* metrics) {
473 for (int i = 0; i < metrics->skipped_size(); ++i) {
474 backfillStartEndTimestampForPartialBucket(timeBaseNs, metrics->mutable_skipped(i));
475 }
476 }
477 } // namespace statsd
478 } // namespace os
479 } // namespace android
480