summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-12-15 22:28:56 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-12-15 22:35:40 +0000
commit9d00fd0e5deece8676c67584a45ce2b7e8ba437e (patch)
tree04f60398fa0384189cf1aff436b02847449ab7a8
parent7b616d6ec2a4bfaca6d8d6f94bf76cb4729d14b5 (diff)
parent350c3e0c7a31db268e9025f15cf99359fb916dbc (diff)
downloadbase-android-mainline-11.0.0_r5.tar.gz
Make change and version bump to r_aml_301600000 for mainline module file: apex/permission/apex_manifest.jsonandroid-mainline-11.0.0_r5
Change-Id: Ib24417cef4afb230a8efaebd103937bc0f663ee0
-rw-r--r--Android.bp17
-rw-r--r--apex/permission/apex_manifest.json2
-rw-r--r--apex/statsd/.clang-format17
-rw-r--r--apex/statsd/Android.bp81
-rw-r--r--apex/statsd/OWNERS9
-rw-r--r--apex/statsd/TEST_MAPPING10
-rw-r--r--apex/statsd/aidl/Android.bp51
-rw-r--r--apex/statsd/aidl/android/os/IPendingIntentRef.aidl46
-rw-r--r--apex/statsd/aidl/android/os/IPullAtomCallback.aidl31
-rw-r--r--apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl32
-rw-r--r--apex/statsd/aidl/android/os/IStatsCompanionService.aidl57
-rw-r--r--apex/statsd/aidl/android/os/IStatsManagerService.aidl136
-rw-r--r--apex/statsd/aidl/android/os/IStatsd.aidl230
-rw-r--r--apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl21
-rw-r--r--apex/statsd/aidl/android/util/StatsEventParcel.aidl8
-rw-r--r--apex/statsd/apex_manifest.json5
-rw-r--r--apex/statsd/com.android.os.statsd.avbpubkeybin1032 -> 0 bytes
-rw-r--r--apex/statsd/com.android.os.statsd.pem51
-rw-r--r--apex/statsd/com.android.os.statsd.pk8bin2375 -> 0 bytes
-rw-r--r--apex/statsd/com.android.os.statsd.x509.pem30
-rw-r--r--apex/statsd/framework/Android.bp80
-rw-r--r--apex/statsd/framework/api/current.txt12
-rw-r--r--apex/statsd/framework/api/module-lib-current.txt10
-rw-r--r--apex/statsd/framework/api/module-lib-removed.txt1
-rw-r--r--apex/statsd/framework/api/removed.txt1
-rw-r--r--apex/statsd/framework/api/system-current.txt111
-rw-r--r--apex/statsd/framework/api/system-removed.txt1
-rw-r--r--apex/statsd/framework/java/android/app/StatsManager.java725
-rw-r--r--apex/statsd/framework/java/android/os/StatsDimensionsValue.java317
-rw-r--r--apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java77
-rw-r--r--apex/statsd/framework/java/android/util/StatsEvent.java879
-rw-r--r--apex/statsd/framework/java/android/util/StatsLog.java185
-rw-r--r--apex/statsd/framework/test/Android.bp36
-rw-r--r--apex/statsd/framework/test/AndroidManifest.xml26
-rw-r--r--apex/statsd/framework/test/AndroidTest.xml34
-rw-r--r--apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java85
-rw-r--r--apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java115
-rw-r--r--apex/statsd/framework/test/src/android/util/StatsEventTest.java818
-rw-r--r--apex/statsd/jni/android_util_StatsLog.cpp90
-rw-r--r--apex/statsd/service/Android.bp35
-rw-r--r--apex/statsd/service/java/com/android/server/stats/StatsCompanion.java188
-rw-r--r--apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java751
-rw-r--r--apex/statsd/service/java/com/android/server/stats/StatsManagerService.java668
-rw-r--r--apex/statsd/statsd.rc20
-rw-r--r--apex/statsd/testing/Android.bp25
-rw-r--r--apex/statsd/testing/test_manifest.json4
-rw-r--r--apex/statsd/tests/libstatspull/Android.bp61
-rw-r--r--apex/statsd/tests/libstatspull/AndroidManifest.xml31
-rw-r--r--apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp70
-rw-r--r--apex/statsd/tests/libstatspull/protos/test_atoms.proto32
-rw-r--r--apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java287
-rw-r--r--apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java124
-rw-r--r--cmds/statsd/.clang-format17
-rw-r--r--cmds/statsd/Android.bp429
-rw-r--r--cmds/statsd/OWNERS9
-rw-r--r--cmds/statsd/TEST_MAPPING7
-rw-r--r--cmds/statsd/benchmark/duration_metric_benchmark.cpp314
-rw-r--r--cmds/statsd/benchmark/filter_value_benchmark.cpp72
-rw-r--r--cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp77
-rw-r--r--cmds/statsd/benchmark/hello_world_benchmark.cpp29
-rw-r--r--cmds/statsd/benchmark/log_event_benchmark.cpp50
-rw-r--r--cmds/statsd/benchmark/main.cpp19
-rw-r--r--cmds/statsd/benchmark/metric_util.cpp379
-rw-r--r--cmds/statsd/benchmark/metric_util.h140
-rw-r--r--cmds/statsd/benchmark/stats_write_benchmark.cpp40
-rw-r--r--cmds/statsd/src/FieldValue.cpp474
-rw-r--r--cmds/statsd/src/FieldValue.h462
-rw-r--r--cmds/statsd/src/HashableDimensionKey.cpp381
-rw-r--r--cmds/statsd/src/HashableDimensionKey.h238
-rw-r--r--cmds/statsd/src/Log.h33
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp1130
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h370
-rw-r--r--cmds/statsd/src/StatsService.cpp1322
-rw-r--r--cmds/statsd/src/StatsService.h416
-rw-r--r--cmds/statsd/src/active_config_list.proto57
-rw-r--r--cmds/statsd/src/annotations.h33
-rw-r--r--cmds/statsd/src/anomaly/AlarmMonitor.cpp139
-rw-r--r--cmds/statsd/src/anomaly/AlarmMonitor.h162
-rw-r--r--cmds/statsd/src/anomaly/AlarmTracker.cpp94
-rw-r--r--cmds/statsd/src/anomaly/AlarmTracker.h80
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.cpp321
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.h204
-rw-r--r--cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp115
-rw-r--r--cmds/statsd/src/anomaly/DurationAnomalyTracker.h79
-rw-r--r--cmds/statsd/src/anomaly/indexed_priority_queue.h224
-rw-r--r--cmds/statsd/src/anomaly/subscriber_util.cpp70
-rw-r--r--cmds/statsd/src/anomaly/subscriber_util.h33
-rw-r--r--cmds/statsd/src/atom_field_options.proto116
-rw-r--r--cmds/statsd/src/atoms.proto11275
-rw-r--r--cmds/statsd/src/condition/CombinationConditionTracker.cpp187
-rw-r--r--cmds/statsd/src/condition/CombinationConditionTracker.h111
-rw-r--r--cmds/statsd/src/condition/ConditionTimer.h83
-rw-r--r--cmds/statsd/src/condition/ConditionTracker.h156
-rw-r--r--cmds/statsd/src/condition/ConditionWizard.cpp70
-rw-r--r--cmds/statsd/src/condition/ConditionWizard.h68
-rw-r--r--cmds/statsd/src/condition/SimpleConditionTracker.cpp386
-rw-r--r--cmds/statsd/src/condition/SimpleConditionTracker.h138
-rw-r--r--cmds/statsd/src/condition/condition_util.cpp93
-rw-r--r--cmds/statsd/src/condition/condition_util.h43
-rw-r--r--cmds/statsd/src/config/ConfigKey.cpp54
-rw-r--r--cmds/statsd/src/config/ConfigKey.h89
-rw-r--r--cmds/statsd/src/config/ConfigListener.cpp31
-rw-r--r--cmds/statsd/src/config/ConfigListener.h52
-rw-r--r--cmds/statsd/src/config/ConfigManager.cpp375
-rw-r--r--cmds/statsd/src/config/ConfigManager.h181
-rw-r--r--cmds/statsd/src/experiment_ids.proto29
-rw-r--r--cmds/statsd/src/external/Perfetto.cpp139
-rw-r--r--cmds/statsd/src/external/Perfetto.h37
-rw-r--r--cmds/statsd/src/external/PullDataReceiver.h41
-rw-r--r--cmds/statsd/src/external/PullResultReceiver.cpp39
-rw-r--r--cmds/statsd/src/external/PullResultReceiver.h48
-rw-r--r--cmds/statsd/src/external/PullUidProvider.h39
-rw-r--r--cmds/statsd/src/external/StatsCallbackPuller.cpp116
-rw-r--r--cmds/statsd/src/external/StatsCallbackPuller.h46
-rw-r--r--cmds/statsd/src/external/StatsPuller.cpp126
-rw-r--r--cmds/statsd/src/external/StatsPuller.h119
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp371
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.h189
-rw-r--r--cmds/statsd/src/external/TrainInfoPuller.cpp55
-rw-r--r--cmds/statsd/src/external/TrainInfoPuller.h38
-rw-r--r--cmds/statsd/src/external/puller_util.cpp153
-rw-r--r--cmds/statsd/src/external/puller_util.h34
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp1101
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h678
-rw-r--r--cmds/statsd/src/hash.cpp142
-rw-r--r--cmds/statsd/src/hash.h46
-rw-r--r--cmds/statsd/src/logd/LogEvent.cpp599
-rw-r--r--cmds/statsd/src/logd/LogEvent.h331
-rw-r--r--cmds/statsd/src/logd/LogEventQueue.cpp62
-rw-r--r--cmds/statsd/src/logd/LogEventQueue.h57
-rw-r--r--cmds/statsd/src/main.cpp113
-rw-r--r--cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp120
-rw-r--r--cmds/statsd/src/matchers/CombinationLogMatchingTracker.h53
-rw-r--r--cmds/statsd/src/matchers/EventMatcherWizard.cpp35
-rw-r--r--cmds/statsd/src/matchers/EventMatcherWizard.h41
-rw-r--r--cmds/statsd/src/matchers/LogMatchingTracker.h96
-rw-r--r--cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp73
-rw-r--r--cmds/statsd/src/matchers/SimpleLogMatchingTracker.h55
-rw-r--r--cmds/statsd/src/matchers/matcher_util.cpp372
-rw-r--r--cmds/statsd/src/matchers/matcher_util.h44
-rw-r--r--cmds/statsd/src/metadata_util.cpp122
-rw-r--r--cmds/statsd/src/metadata_util.h32
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.cpp397
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.h123
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp653
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.h169
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.cpp170
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.h83
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.cpp620
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.h211
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.cpp321
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h508
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp695
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h351
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.cpp1160
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.h342
-rw-r--r--cmds/statsd/src/metrics/duration_helper/DurationTracker.h226
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp331
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h94
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp463
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h93
-rw-r--r--cmds/statsd/src/metrics/metrics_manager_util.cpp983
-rw-r--r--cmds/statsd/src/metrics/metrics_manager_util.h140
-rw-r--r--cmds/statsd/src/packages/PackageInfoListener.h45
-rw-r--r--cmds/statsd/src/packages/UidMap.cpp563
-rw-r--r--cmds/statsd/src/packages/UidMap.h227
-rw-r--r--cmds/statsd/src/shell/ShellSubscriber.cpp245
-rw-r--r--cmds/statsd/src/shell/ShellSubscriber.h146
-rw-r--r--cmds/statsd/src/shell/shell_config.proto39
-rw-r--r--cmds/statsd/src/shell/shell_data.proto29
-rwxr-xr-xcmds/statsd/src/socket/StatsSocketListener.cpp156
-rw-r--r--cmds/statsd/src/socket/StatsSocketListener.h54
-rw-r--r--cmds/statsd/src/state/StateListener.h54
-rw-r--r--cmds/statsd/src/state/StateManager.cpp112
-rw-r--r--cmds/statsd/src/state/StateManager.h103
-rw-r--r--cmds/statsd/src/state/StateTracker.cpp190
-rw-r--r--cmds/statsd/src/state/StateTracker.h94
-rw-r--r--cmds/statsd/src/stats_log.proto553
-rw-r--r--cmds/statsd/src/stats_log_util.cpp609
-rw-r--r--cmds/statsd/src/stats_log_util.h117
-rw-r--r--cmds/statsd/src/stats_util.h36
-rw-r--r--cmds/statsd/src/statscompanion_util.cpp35
-rw-r--r--cmds/statsd/src/statscompanion_util.h33
-rw-r--r--cmds/statsd/src/statsd_config.proto511
-rw-r--r--cmds/statsd/src/statsd_metadata.proto67
-rw-r--r--cmds/statsd/src/storage/StorageManager.cpp781
-rw-r--r--cmds/statsd/src/storage/StorageManager.h168
-rw-r--r--cmds/statsd/src/subscriber/IncidentdReporter.cpp169
-rw-r--r--cmds/statsd/src/subscriber/IncidentdReporter.h36
-rw-r--r--cmds/statsd/src/subscriber/SubscriberReporter.cpp171
-rw-r--r--cmds/statsd/src/subscriber/SubscriberReporter.h109
-rw-r--r--cmds/statsd/src/uid_data.proto36
-rw-r--r--cmds/statsd/src/utils/MultiConditionTrigger.cpp57
-rw-r--r--cmds/statsd/src/utils/MultiConditionTrigger.h55
-rw-r--r--cmds/statsd/statsd_test.xml37
-rw-r--r--cmds/statsd/tests/AlarmMonitor_test.cpp69
-rw-r--r--cmds/statsd/tests/ConfigManager_test.cpp159
-rw-r--r--cmds/statsd/tests/FieldValue_test.cpp659
-rw-r--r--cmds/statsd/tests/HashableDimensionKey_test.cpp137
-rw-r--r--cmds/statsd/tests/LogEntryMatcher_test.cpp809
-rw-r--r--cmds/statsd/tests/LogEvent_test.cpp371
-rw-r--r--cmds/statsd/tests/LogReader_test.cpp21
-rw-r--r--cmds/statsd/tests/MetricsManager_test.cpp799
-rw-r--r--cmds/statsd/tests/StatsLogProcessor_test.cpp1886
-rw-r--r--cmds/statsd/tests/StatsService_test.cpp104
-rw-r--r--cmds/statsd/tests/UidMap_test.cpp426
-rw-r--r--cmds/statsd/tests/anomaly/AlarmTracker_test.cpp94
-rw-r--r--cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp408
-rw-r--r--cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp167
-rw-r--r--cmds/statsd/tests/condition/ConditionTimer_test.cpp68
-rw-r--r--cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp739
-rw-r--r--cmds/statsd/tests/e2e/Alarm_e2e_test.cpp92
-rw-r--r--cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp390
-rw-r--r--cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp527
-rw-r--r--cmds/statsd/tests/e2e/Attribution_e2e_test.cpp375
-rw-r--r--cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp114
-rw-r--r--cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp901
-rw-r--r--cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp1473
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp624
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp295
-rw-r--r--cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp1833
-rw-r--r--cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp348
-rw-r--r--cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp433
-rw-r--r--cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp679
-rw-r--r--cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp355
-rw-r--r--cmds/statsd/tests/external/StatsCallbackPuller_test.cpp219
-rw-r--r--cmds/statsd/tests/external/StatsPullerManager_test.cpp150
-rw-r--r--cmds/statsd/tests/external/StatsPuller_test.cpp316
-rw-r--r--cmds/statsd/tests/external/puller_util_test.cpp408
-rw-r--r--cmds/statsd/tests/guardrail/StatsdStats_test.cpp544
-rw-r--r--cmds/statsd/tests/indexed_priority_queue_test.cpp235
-rw-r--r--cmds/statsd/tests/log_event/LogEventQueue_test.cpp115
-rw-r--r--cmds/statsd/tests/metadata_util_test.cpp69
-rw-r--r--cmds/statsd/tests/metrics/CountMetricProducer_test.cpp476
-rw-r--r--cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp515
-rw-r--r--cmds/statsd/tests/metrics/EventMetricProducer_test.cpp182
-rw-r--r--cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp865
-rw-r--r--cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp424
-rw-r--r--cmds/statsd/tests/metrics/OringDurationTracker_test.cpp576
-rw-r--r--cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp5104
-rw-r--r--cmds/statsd/tests/metrics/metrics_test_helper.cpp57
-rw-r--r--cmds/statsd/tests/metrics/metrics_test_helper.h63
-rw-r--r--cmds/statsd/tests/shell/ShellSubscriber_test.cpp207
-rw-r--r--cmds/statsd/tests/state/StateTracker_test.cpp571
-rw-r--r--cmds/statsd/tests/statsd_test_util.cpp1393
-rw-r--r--cmds/statsd/tests/statsd_test_util.h479
-rw-r--r--cmds/statsd/tests/storage/StorageManager_test.cpp204
-rw-r--r--cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp174
-rw-r--r--cmds/statsd/tools/localtools/Android.bp46
-rw-r--r--cmds/statsd/tools/localtools/TEST_MAPPING8
-rw-r--r--cmds/statsd/tools/localtools/localdrive_manifest.txt1
-rw-r--r--cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java284
-rw-r--r--cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java379
-rw-r--r--cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java419
-rw-r--r--cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java326
-rw-r--r--cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java195
-rw-r--r--cmds/statsd/tools/localtools/testdrive_manifest.txt1
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/bluetooth/BluetoothCodecConfig.java32
-rw-r--r--core/java/android/bluetooth/BluetoothCodecStatus.java5
-rw-r--r--core/java/android/content/pm/PackageManager.java5
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java12
-rw-r--r--core/java/android/net/LinkProperties.java3
-rw-r--r--core/java/android/net/MacAddress.java2
-rw-r--r--core/java/android/net/RouteInfo.java3
-rwxr-xr-xcore/java/android/os/Build.java4
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java19
-rw-r--r--core/java/com/android/internal/content/FileSystemProvider.java11
-rw-r--r--core/proto/Android.bp30
-rw-r--r--core/proto/android/app/enums.proto210
-rw-r--r--core/proto/android/app/job/enums.proto38
-rw-r--r--core/proto/android/app/media_output_enum.proto65
-rw-r--r--core/proto/android/app/settings_enums.proto2686
-rw-r--r--core/proto/android/app/tvsettings_enums.proto941
-rw-r--r--core/proto/android/bluetooth/a2dp/enums.proto35
-rw-r--r--core/proto/android/bluetooth/enums.proto141
-rw-r--r--core/proto/android/bluetooth/hci/enums.proto559
-rw-r--r--core/proto/android/bluetooth/hfp/enums.proto28
-rw-r--r--core/proto/android/bluetooth/smp/enums.proto58
-rw-r--r--core/proto/android/debug/enums.proto67
-rw-r--r--core/proto/android/hardware/biometrics/enums.proto60
-rw-r--r--core/proto/android/hardware/sensor/assist/enums.proto34
-rw-r--r--core/proto/android/net/networkcapabilities.proto133
-rw-r--r--core/proto/android/net/networkrequest.proto2
-rw-r--r--core/proto/android/os/batterystats.proto4
-rw-r--r--core/proto/android/os/enums.proto169
-rw-r--r--core/proto/android/os/incident.proto2
-rw-r--r--core/proto/android/server/activitymanagerservice.proto2
-rw-r--r--core/proto/android/server/bluetooth_manager_service.proto2
-rw-r--r--core/proto/android/server/connectivity/Android.bp24
-rw-r--r--core/proto/android/server/connectivity/data_stall_event.proto91
-rw-r--r--core/proto/android/server/enums.proto40
-rw-r--r--core/proto/android/server/job/enums.proto43
-rw-r--r--core/proto/android/server/jobscheduler.proto4
-rw-r--r--core/proto/android/server/location/enums.proto132
-rw-r--r--core/proto/android/server/powermanagerservice.proto6
-rw-r--r--core/proto/android/server/windowmanagerservice.proto3
-rw-r--r--core/proto/android/service/battery.proto2
-rw-r--r--core/proto/android/service/procstats.proto2
-rw-r--r--core/proto/android/service/procstats_enum.proto102
-rw-r--r--core/proto/android/service/usb.proto440
-rw-r--r--core/proto/android/stats/accessibility/accessibility_enums.proto35
-rw-r--r--core/proto/android/stats/connectivity/Android.bp38
-rw-r--r--core/proto/android/stats/connectivity/network_stack.proto180
-rw-r--r--core/proto/android/stats/connectivity/tethering.proto97
-rw-r--r--core/proto/android/stats/devicepolicy/Android.bp33
-rw-r--r--core/proto/android/stats/devicepolicy/device_policy.proto24
-rw-r--r--core/proto/android/stats/devicepolicy/device_policy_enums.proto204
-rw-r--r--core/proto/android/stats/devicepolicy/jarjar-rules.txt1
-rw-r--r--core/proto/android/stats/dnsresolver/Android.bp24
-rw-r--r--core/proto/android/stats/dnsresolver/dns_resolver.proto375
-rw-r--r--core/proto/android/stats/docsui/docsui_enums.proto197
-rw-r--r--core/proto/android/stats/enums.proto29
-rw-r--r--core/proto/android/stats/intelligence/enums.proto40
-rw-r--r--core/proto/android/stats/launcher/Android.bp40
-rw-r--r--core/proto/android/stats/launcher/launcher.proto88
-rw-r--r--core/proto/android/stats/location/location_enums.proto122
-rw-r--r--core/proto/android/stats/mediametrics/mediametrics.proto239
-rw-r--r--core/proto/android/stats/mediaprovider/mediaprovider_enums.proto30
-rw-r--r--core/proto/android/stats/otaupdate/updateengine_enums.proto82
-rw-r--r--core/proto/android/stats/storage/storage_enums.proto26
-rw-r--r--core/proto/android/stats/style/Android.bp27
-rw-r--r--core/proto/android/stats/style/style_enums.proto48
-rw-r--r--core/proto/android/stats/sysui/notification_enums.proto30
-rw-r--r--core/proto/android/stats/textclassifier/Android.bp23
-rw-r--r--core/proto/android/stats/textclassifier/textclassifier_enums.proto87
-rw-r--r--core/proto/android/telecomm/enums.proto203
-rw-r--r--core/proto/android/telephony/enums.proto161
-rw-r--r--core/proto/android/view/enums.proto71
-rw-r--r--core/proto/android/wifi/enums.proto50
-rw-r--r--core/res/res/values-am/strings.xml4
-rw-r--r--core/res/res/values-ar/strings.xml32
-rw-r--r--core/res/res/values-as/strings.xml8
-rw-r--r--core/res/res/values-az/strings.xml16
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml52
-rw-r--r--core/res/res/values-be/strings.xml42
-rw-r--r--core/res/res/values-bn/strings.xml10
-rw-r--r--core/res/res/values-bs/strings.xml6
-rw-r--r--core/res/res/values-ca/strings.xml28
-rw-r--r--core/res/res/values-cs/strings.xml6
-rw-r--r--core/res/res/values-da/strings.xml2
-rw-r--r--core/res/res/values-de/strings.xml2
-rw-r--r--core/res/res/values-en-rCA/strings.xml6
-rw-r--r--core/res/res/values-es-rUS/strings.xml6
-rw-r--r--core/res/res/values-es/strings.xml6
-rw-r--r--core/res/res/values-et/strings.xml4
-rw-r--r--core/res/res/values-eu/strings.xml4
-rw-r--r--core/res/res/values-fa/strings.xml40
-rw-r--r--core/res/res/values-fi/strings.xml8
-rw-r--r--core/res/res/values-fr-rCA/strings.xml56
-rw-r--r--core/res/res/values-fr/strings.xml38
-rw-r--r--core/res/res/values-gl/strings.xml4
-rw-r--r--core/res/res/values-gu/strings.xml32
-rw-r--r--core/res/res/values-hu/strings.xml6
-rw-r--r--core/res/res/values-hy/strings.xml26
-rw-r--r--core/res/res/values-in/strings.xml28
-rw-r--r--core/res/res/values-it/strings.xml4
-rw-r--r--core/res/res/values-iw/strings.xml2
-rw-r--r--core/res/res/values-kk/strings.xml24
-rw-r--r--core/res/res/values-km/strings.xml14
-rw-r--r--core/res/res/values-kn/strings.xml10
-rw-r--r--core/res/res/values-ky/strings.xml18
-rw-r--r--core/res/res/values-mk/strings.xml42
-rw-r--r--core/res/res/values-ml/strings.xml10
-rw-r--r--core/res/res/values-mn/strings.xml32
-rw-r--r--core/res/res/values-mr/strings.xml70
-rw-r--r--core/res/res/values-my/strings.xml2
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne/strings.xml102
-rw-r--r--core/res/res/values-nl/strings.xml38
-rw-r--r--core/res/res/values-or/strings.xml8
-rw-r--r--core/res/res/values-pa/strings.xml8
-rw-r--r--core/res/res/values-pl/strings.xml30
-rw-r--r--core/res/res/values-pt-rPT/strings.xml2
-rw-r--r--core/res/res/values-ru/strings.xml8
-rw-r--r--core/res/res/values-sl/strings.xml2
-rw-r--r--core/res/res/values-sq/strings.xml2
-rw-r--r--core/res/res/values-sr/strings.xml52
-rw-r--r--core/res/res/values-sv/strings.xml2
-rw-r--r--core/res/res/values-sw/strings.xml4
-rw-r--r--core/res/res/values-ta/strings.xml2
-rw-r--r--core/res/res/values-te/strings.xml16
-rw-r--r--core/res/res/values-th/strings.xml2
-rw-r--r--core/res/res/values-tl/strings.xml10
-rw-r--r--core/res/res/values-uk/strings.xml10
-rw-r--r--core/res/res/values-ur/strings.xml32
-rw-r--r--core/res/res/values-uz/strings.xml8
-rw-r--r--core/res/res/values-vi/strings.xml8
-rw-r--r--packages/CarSystemUI/res/values-ca/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-es-rUS/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-fi/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-in/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-kk/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-ky/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-ne/strings.xml2
-rw-r--r--packages/CarSystemUI/res/values-sk/strings.xml2
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java7
-rw-r--r--packages/SettingsLib/HelpUtils/res/values-es/strings.xml2
-rw-r--r--packages/SettingsLib/HelpUtils/res/values-te/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-bs/arrays.xml6
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-hy/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-in/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ja/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-mn/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-te/arrays.xml16
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-th/arrays.xml8
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java10
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java4
-rw-r--r--services/core/java/com/android/server/NsdService.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java117
-rw-r--r--services/core/java/com/android/server/connectivity/VpnIkev2Utils.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java4
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java44
-rw-r--r--tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt9
-rw-r--r--tests/net/java/android/net/MacAddressTest.java4
-rw-r--r--tools/stats_log_api_gen/.clang-format17
-rw-r--r--tools/stats_log_api_gen/Android.bp131
-rw-r--r--tools/stats_log_api_gen/Collation.cpp576
-rw-r--r--tools/stats_log_api_gen/Collation.h201
-rw-r--r--tools/stats_log_api_gen/java_writer.cpp336
-rw-r--r--tools/stats_log_api_gen/java_writer.h38
-rw-r--r--tools/stats_log_api_gen/java_writer_q.cpp601
-rw-r--r--tools/stats_log_api_gen/java_writer_q.h46
-rw-r--r--tools/stats_log_api_gen/main.cpp264
-rw-r--r--tools/stats_log_api_gen/native_writer.cpp355
-rw-r--r--tools/stats_log_api_gen/native_writer.h37
-rw-r--r--tools/stats_log_api_gen/test.proto215
-rw-r--r--tools/stats_log_api_gen/test_collation.cpp369
-rw-r--r--tools/stats_log_api_gen/utils.cpp434
-rw-r--r--tools/stats_log_api_gen/utils.h83
-rw-r--r--wifi/jarjar-rules.txt2
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java2
-rw-r--r--wifi/java/android/net/wifi/WifiEnterpriseConfig.java20
-rw-r--r--wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java3
-rw-r--r--wifi/tests/Android.bp1
-rw-r--r--wifi/tests/src/android/net/wifi/WifiConfigurationTest.java3
478 files changed, 967 insertions, 91414 deletions
diff --git a/Android.bp b/Android.bp
index 4c03c3f417fc..c7d69cd9a19f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -607,6 +607,7 @@ gensrcs {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -633,6 +634,7 @@ gensrcs {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -749,13 +751,19 @@ java_library_host {
name: "platformprotos",
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ ":libstats_internal_protos",
+ ":statsd_internal_protos",
"cmds/am/proto/instrumentation_data.proto",
"cmds/statsd/src/**/*.proto",
"core/proto/**/*.proto",
"libs/incident/proto/**/*.proto",
],
proto: {
- include_dirs: ["external/protobuf/src"],
+ include_dirs: [
+ "external/protobuf/src",
+ "frameworks/proto_logging/stats",
+ ],
type: "full",
},
errorprone: {
@@ -778,6 +786,7 @@ java_library {
sdk_version: "9",
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -793,6 +802,7 @@ java_library {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -813,7 +823,9 @@ cc_defaults {
proto: {
export_proto_headers: true,
- include_dirs: ["external/protobuf/src"],
+ include_dirs: [
+ "external/protobuf/src",
+ ],
},
cflags: [
@@ -824,6 +836,7 @@ cc_defaults {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
],
}
diff --git a/apex/permission/apex_manifest.json b/apex/permission/apex_manifest.json
index dc0ee2bffa9b..39a993642787 100644
--- a/apex/permission/apex_manifest.json
+++ b/apex/permission/apex_manifest.json
@@ -1,4 +1,4 @@
{
"name": "com.android.permission",
- "version": 301501400
+ "version": 301600000
}
diff --git a/apex/statsd/.clang-format b/apex/statsd/.clang-format
deleted file mode 100644
index cead3a079435..000000000000
--- a/apex/statsd/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
- - Regex: '^"Log\.h"'
- Priority: -1
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
deleted file mode 100644
index d1148f8107c0..000000000000
--- a/apex/statsd/Android.bp
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-apex {
- name: "com.android.os.statsd",
- defaults: ["com.android.os.statsd-defaults"],
- manifest: "apex_manifest.json",
-}
-
-apex_defaults {
- native_shared_libs: [
- "libstats_jni",
- "libstatspull",
- "libstatssocket",
- ],
- binaries: ["statsd"],
- java_libs: [
- "framework-statsd",
- "service-statsd",
- ],
- compile_multilib: "both",
- prebuilts: ["com.android.os.statsd.init.rc"],
- name: "com.android.os.statsd-defaults",
- updatable: true,
- min_sdk_version: "30",
- key: "com.android.os.statsd.key",
- certificate: ":com.android.os.statsd.certificate",
-}
-
-apex_key {
- name: "com.android.os.statsd.key",
- public_key: "com.android.os.statsd.avbpubkey",
- private_key: "com.android.os.statsd.pem",
-}
-
-android_app_certificate {
- name: "com.android.os.statsd.certificate",
- // This will use com.android.os.statsd.x509.pem (the cert) and
- // com.android.os.statsd.pk8 (the private key)
- certificate: "com.android.os.statsd",
-}
-
-prebuilt_etc {
- name: "com.android.os.statsd.init.rc",
- src: "statsd.rc",
- filename: "init.rc",
- installable: false,
-}
-
-// JNI library for StatsLog.write
-cc_library_shared {
- name: "libstats_jni",
- srcs: ["jni/**/*.cpp"],
- header_libs: ["libnativehelper_header_only"],
- shared_libs: [
- "liblog", // Has a stable abi - should not be copied into apex.
- "libstatssocket",
- ],
- stl: "libc++_static",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wextra",
- "-Wno-unused-parameter",
- ],
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
diff --git a/apex/statsd/OWNERS b/apex/statsd/OWNERS
deleted file mode 100644
index bed9600bc955..000000000000
--- a/apex/statsd/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-jeffreyhuang@google.com
-joeo@google.com
-jtnguyen@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com \ No newline at end of file
diff --git a/apex/statsd/TEST_MAPPING b/apex/statsd/TEST_MAPPING
deleted file mode 100644
index 93f108707d9e..000000000000
--- a/apex/statsd/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "presubmit" : [
- {
- "name" : "FrameworkStatsdTest"
- },
- {
- "name" : "LibStatsPullTests"
- }
- ]
-}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
deleted file mode 100644
index 04339e67d799..000000000000
--- a/apex/statsd/aidl/Android.bp
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-filegroup {
- name: "framework-statsd-aidl-sources",
- srcs: ["**/*.aidl"],
-}
-
-aidl_interface {
- name: "statsd-aidl",
- unstable: true,
- srcs: [
- "android/os/IPendingIntentRef.aidl",
- "android/os/IPullAtomCallback.aidl",
- "android/os/IPullAtomResultReceiver.aidl",
- "android/os/IStatsCompanionService.aidl",
- "android/os/IStatsd.aidl",
- "android/os/StatsDimensionsValueParcel.aidl",
- "android/util/StatsEventParcel.aidl",
- ],
- backend: {
- java: {
- enabled: false, // framework-statsd and service-statsd use framework-statsd-aidl-sources
- },
- cpp: {
- enabled: false,
- },
- ndk: {
- enabled: true,
- apex_available: [
- // TODO(b/145923087): Remove this once statsd binary is in apex
- "//apex_available:platform",
-
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
- },
- }
-}
diff --git a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl b/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
deleted file mode 100644
index 000a69992a49..000000000000
--- a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.StatsDimensionsValueParcel;
-
-/**
- * Binder interface to hold a PendingIntent for StatsCompanionService.
- * {@hide}
- */
-interface IPendingIntentRef {
-
- /**
- * Sends a broadcast to the specified PendingIntent that it should getData now.
- * This should be only called from StatsCompanionService.
- */
- oneway void sendDataBroadcast(long lastReportTimeNs);
-
- /**
- * Send a broadcast to the specified PendingIntent notifying it that the list of active configs
- * has changed. This should be only called from StatsCompanionService.
- */
- oneway void sendActiveConfigsChangedBroadcast(in long[] configIds);
-
- /**
- * Send a broadcast to the specified PendingIntent, along with the other information
- * specified. This should only be called from StatsCompanionService.
- */
- oneway void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
- long subscriptionRuleId, in String[] cookies,
- in StatsDimensionsValueParcel dimensionsValueParcel);
-}
diff --git a/apex/statsd/aidl/android/os/IPullAtomCallback.aidl b/apex/statsd/aidl/android/os/IPullAtomCallback.aidl
deleted file mode 100644
index ff0b97bb5b84..000000000000
--- a/apex/statsd/aidl/android/os/IPullAtomCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.IPullAtomResultReceiver;
-
-/**
- * Binder interface to pull atoms for the stats service.
- * {@hide}
- */
-interface IPullAtomCallback {
- /**
- * Initiate a request for a pull for an atom.
- */
- oneway void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver);
-
-}
diff --git a/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl b/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl
deleted file mode 100644
index 00d026e25df3..000000000000
--- a/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.util.StatsEventParcel;
-
-/**
- * Binder interface to pull atoms for the stats service.
- * {@hide}
- */
-interface IPullAtomResultReceiver {
-
- /**
- * Indicate that a pull request for an atom is complete.
- */
- oneway void pullFinished(int atomTag, boolean success, in StatsEventParcel[] output);
-
-}
diff --git a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
deleted file mode 100644
index d56a4bd0a8e5..000000000000
--- a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/**
- * Binder interface to communicate with the Java-based statistics service helper.
- * {@hide}
- */
-interface IStatsCompanionService {
- /**
- * Tell statscompanion that stastd is up and running.
- */
- oneway void statsdReady();
-
- /**
- * Register a repeating alarm for pulling to fire at the given timestamp and every
- * intervalMs thereafter (in ms since epoch).
- * If polling alarm had already been registered, it will be replaced by new one.
- * Uses AlarmManager.setRepeating API, so if the timestamp is in past, alarm fires immediately,
- * and alarm is inexact.
- */
- oneway void setPullingAlarm(long nextPullTimeMs);
-
- /** Cancel any repeating pulling alarm. */
- oneway void cancelPullingAlarm();
-
- /**
- * Register an alarm when we want to trigger subscribers at the given
- * timestamp (in ms since epoch).
- * If an alarm had already been registered, it will be replaced by new one.
- */
- oneway void setAlarmForSubscriberTriggering(long timestampMs);
-
- /** Cancel any alarm for the purpose of subscriber triggering. */
- oneway void cancelAlarmForSubscriberTriggering();
-
- /**
- * Ask StatsCompanionService if the given permission is allowed for a particular process
- * and user ID. statsd is incapable of doing this check itself because checkCallingPermission
- * is not currently supported by libbinder_ndk.
- */
- boolean checkPermission(String permission, int pid, int uid);
-}
diff --git a/apex/statsd/aidl/android/os/IStatsManagerService.aidl b/apex/statsd/aidl/android/os/IStatsManagerService.aidl
deleted file mode 100644
index b59a97e25bd0..000000000000
--- a/apex/statsd/aidl/android/os/IStatsManagerService.aidl
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.app.PendingIntent;
-import android.os.IPullAtomCallback;
-
-/**
- * Binder interface to communicate with the Java-based statistics service helper.
- * Contains parcelable objects available only in Java.
- * {@hide}
- */
-interface IStatsManagerService {
-
- /**
- * Registers the given pending intent for this config key. This intent is invoked when the
- * memory consumed by the metrics for this configuration approach the pre-defined limits. There
- * can be at most one listener per config key.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void setDataFetchOperation(long configId, in PendingIntent pendingIntent,
- in String packageName);
-
- /**
- * Removes the data fetch operation for the specified configuration.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeDataFetchOperation(long configId, in String packageName);
-
- /**
- * Registers the given pending intent for this packagename. This intent is invoked when the
- * active status of any of the configs sent by this package changes and will contain a list of
- * config ids that are currently active. It also returns the list of configs that are currently
- * active. There can be at most one active configs changed listener per package.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- long[] setActiveConfigsChangedOperation(in PendingIntent pendingIntent, in String packageName);
-
- /**
- * Removes the active configs changed operation for the specified package name.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeActiveConfigsChangedOperation(in String packageName);
-
- /**
- * Set the PendingIntent to be used when broadcasting subscriber
- * information to the given subscriberId within the given config.
- *
- * Suppose that the calling uid has added a config with key configKey, and that in this config
- * it is specified that when a particular anomaly is detected, a broadcast should be sent to
- * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
- * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
- * when the anomaly is detected.
- *
- * This function can only be called by the owner (uid) of the config. It must be called each
- * time statsd starts. Later calls overwrite previous calls; only one PendingIntent is stored.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void setBroadcastSubscriber(long configKey, long subscriberId, in PendingIntent pendingIntent,
- in String packageName);
-
- /**
- * Undoes setBroadcastSubscriber() for the (configKey, subscriberId) pair.
- * Any broadcasts associated with subscriberId will henceforth not be sent.
- * No-op if this (configKey, subscriberId) pair was not associated with an PendingIntent.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void unsetBroadcastSubscriber(long configKey, long subscriberId, in String packageName);
-
- /**
- * Returns the most recently registered experiment IDs.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- long[] getRegisteredExperimentIds();
-
- /**
- * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- byte[] getMetadata(in String packageName);
-
- /**
- * Fetches data for the specified configuration key. Returns a byte array representing proto
- * wire-encoded of ConfigMetricsReportList.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- byte[] getData(in long key, in String packageName);
-
- /**
- * Sets a configuration with the specified config id and subscribes to updates for this
- * configuration id. Broadcasts will be sent if this configuration needs to be collected.
- * The configuration must be a wire-encoded StatsdConfig. The receiver for this data is
- * registered in a separate function.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void addConfiguration(in long configId, in byte[] config, in String packageName);
-
- /**
- * Removes the configuration with the matching config id. No-op if this config id does not
- * exist.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeConfiguration(in long configId, in String packageName);
-
- /** Tell StatsManagerService to register a puller for the given atom tag with statsd. */
- oneway void registerPullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
- in int[] additiveFields, IPullAtomCallback pullerCallback);
-
- /** Tell StatsManagerService to unregister the pulller for the given atom tag from statsd. */
- oneway void unregisterPullAtomCallback(int atomTag);
-}
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
deleted file mode 100644
index 066412a9f157..000000000000
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.IPendingIntentRef;
-import android.os.IPullAtomCallback;
-import android.os.ParcelFileDescriptor;
-
-/**
- * Binder interface to communicate with the statistics management service.
- * {@hide}
- */
-interface IStatsd {
- /**
- * Tell the stats daemon that the android system server is up and running.
- */
- oneway void systemRunning();
-
- /**
- * Tell the stats daemon that the android system has finished booting.
- */
- oneway void bootCompleted();
-
- /**
- * Tell the stats daemon that the StatsCompanionService is up and running.
- * Two-way binder call so that caller knows message received.
- */
- void statsCompanionReady();
-
- /**
- * Tells statsd that it is time to poll some stats. Statsd will be responsible for determing
- * what stats to poll and initiating the polling.
- * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
- */
- void informPollAlarmFired();
-
- /**
- * Tells statsd that it is time to handle periodic alarms. Statsd will be responsible for
- * determing what alarm subscriber to trigger.
- * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
- */
- void informAlarmForSubscriberTriggeringFired();
-
- /**
- * Tells statsd that the device is about to shutdown.
- */
- void informDeviceShutdown();
-
- /**
- * Inform statsd about a file descriptor for a pipe through which we will pipe version
- * and package information for each uid.
- * Versions and package information are supplied via UidData proto where info for each app
- * is captured in its own element of a repeated ApplicationInfo message.
- */
- oneway void informAllUidData(in ParcelFileDescriptor fd);
-
- /**
- * Inform statsd what the uid, version, version_string, and installer are for one app that was
- * updated.
- */
- oneway void informOnePackage(in String app, in int uid, in long version,
- in String version_string, in String installer);
-
- /**
- * Inform stats that an app was removed.
- */
- oneway void informOnePackageRemoved(in String app, in int uid);
-
- /**
- * Fetches data for the specified configuration key. Returns a byte array representing proto
- * wire-encoded of ConfigMetricsReportList.
- *
- * Requires Manifest.permission.DUMP.
- */
- byte[] getData(in long key, int callingUid);
-
- /**
- * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
- *
- * Requires Manifest.permission.DUMP.
- */
- byte[] getMetadata();
-
- /**
- * Sets a configuration with the specified config id and subscribes to updates for this
- * configuration key. Broadcasts will be sent if this configuration needs to be collected.
- * The configuration must be a wire-encoded StatsdConfig. The receiver for this data is
- * registered in a separate function.
- *
- * Requires Manifest.permission.DUMP.
- */
- void addConfiguration(in long configId, in byte[] config, in int callingUid);
-
- /**
- * Registers the given pending intent for this config key. This intent is invoked when the
- * memory consumed by the metrics for this configuration approach the pre-defined limits. There
- * can be at most one listener per config key.
- *
- * Requires Manifest.permission.DUMP.
- */
- void setDataFetchOperation(long configId, in IPendingIntentRef pendingIntentRef,
- int callingUid);
-
- /**
- * Removes the data fetch operation for the specified configuration.
- *
- * Requires Manifest.permission.DUMP.
- */
- void removeDataFetchOperation(long configId, int callingUid);
-
- /**
- * Registers the given pending intent for this packagename. This intent is invoked when the
- * active status of any of the configs sent by this package changes and will contain a list of
- * config ids that are currently active. It also returns the list of configs that are currently
- * active. There can be at most one active configs changed listener per package.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- long[] setActiveConfigsChangedOperation(in IPendingIntentRef pendingIntentRef, int callingUid);
-
- /**
- * Removes the active configs changed operation for the specified package name.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
- */
- void removeActiveConfigsChangedOperation(int callingUid);
-
- /**
- * Removes the configuration with the matching config id. No-op if this config id does not
- * exist.
- *
- * Requires Manifest.permission.DUMP.
- */
- void removeConfiguration(in long configId, in int callingUid);
-
- /**
- * Set the PendingIntentRef to be used when broadcasting subscriber
- * information to the given subscriberId within the given config.
- *
- * Suppose that the calling uid has added a config with key configId, and that in this config
- * it is specified that when a particular anomaly is detected, a broadcast should be sent to
- * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
- * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
- * when the anomaly is detected.
- *
- * This function can only be called by the owner (uid) of the config. It must be called each
- * time statsd starts. Later calls overwrite previous calls; only one pendingIntent is stored.
- *
- * Requires Manifest.permission.DUMP.
- */
- void setBroadcastSubscriber(long configId, long subscriberId, in IPendingIntentRef pir,
- int callingUid);
-
- /**
- * Undoes setBroadcastSubscriber() for the (configId, subscriberId) pair.
- * Any broadcasts associated with subscriberId will henceforth not be sent.
- * No-op if this (configKey, subscriberId) pair was not associated with an PendingIntentRef.
- *
- * Requires Manifest.permission.DUMP.
- */
- void unsetBroadcastSubscriber(long configId, long subscriberId, int callingUid);
-
- /**
- * Tell the stats daemon that all the pullers registered during boot have been sent.
- */
- oneway void allPullersFromBootRegistered();
-
- /**
- * Registers a puller callback function that, when invoked, pulls the data
- * for the specified atom tag.
- */
- oneway void registerPullAtomCallback(int uid, int atomTag, long coolDownMillis,
- long timeoutMillis,in int[] additiveFields,
- IPullAtomCallback pullerCallback);
-
- /**
- * Registers a puller callback function that, when invoked, pulls the data
- * for the specified atom tag.
- *
- * Enforces the REGISTER_STATS_PULL_ATOM permission.
- */
- oneway void registerNativePullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
- in int[] additiveFields, IPullAtomCallback pullerCallback);
-
- /**
- * Unregisters any pullAtomCallback for the given uid/atom.
- */
- oneway void unregisterPullAtomCallback(int uid, int atomTag);
-
- /**
- * Unregisters any pullAtomCallback for the given atom + caller.
- *
- * Enforces the REGISTER_STATS_PULL_ATOM permission.
- */
- oneway void unregisterNativePullAtomCallback(int atomTag);
-
- /**
- * The install requires staging.
- */
- const int FLAG_REQUIRE_STAGING = 0x01;
-
- /**
- * Rollback is enabled with this install.
- */
- const int FLAG_ROLLBACK_ENABLED = 0x02;
-
- /**
- * Requires low latency monitoring.
- */
- const int FLAG_REQUIRE_LOW_LATENCY_MONITOR = 0x04;
-
- /**
- * Returns the most recently registered experiment IDs.
- */
- long[] getRegisteredExperimentIds();
-}
diff --git a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl b/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
deleted file mode 100644
index 05f78d00348e..000000000000
--- a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-package android.os;
-
-/**
- * @hide
- */
-parcelable StatsDimensionsValueParcel {
- // Field equals atomTag for top level StatsDimensionsValueParcels or
- // positions in depth (1-indexed) for lower level parcels.
- int field;
-
- // Indicator for which type of value is stored. Should be set to one
- // of the constants in StatsDimensionsValue.java.
- int valueType;
-
- String stringValue;
- int intValue;
- long longValue;
- boolean boolValue;
- float floatValue;
- StatsDimensionsValueParcel[] tupleValue;
-}
diff --git a/apex/statsd/aidl/android/util/StatsEventParcel.aidl b/apex/statsd/aidl/android/util/StatsEventParcel.aidl
deleted file mode 100644
index add8bfb47b1a..000000000000
--- a/apex/statsd/aidl/android/util/StatsEventParcel.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.util;
-
-/**
- * @hide
- */
-parcelable StatsEventParcel {
- byte[] buffer;
-}
diff --git a/apex/statsd/apex_manifest.json b/apex/statsd/apex_manifest.json
deleted file mode 100644
index b0d50f321839..000000000000
--- a/apex/statsd/apex_manifest.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "com.android.os.statsd",
- "version": 301501000
-}
-
diff --git a/apex/statsd/com.android.os.statsd.avbpubkey b/apex/statsd/com.android.os.statsd.avbpubkey
deleted file mode 100644
index d78af8b8bef2..000000000000
--- a/apex/statsd/com.android.os.statsd.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.pem b/apex/statsd/com.android.os.statsd.pem
deleted file mode 100644
index 558e17fd6864..000000000000
--- a/apex/statsd/com.android.os.statsd.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKgIBAAKCAgEA893bbpkivKEiNgfknYBSlzC0csaKU/ddBm5Pb4ZFuab+LQSR
-9DDc5JrsmxyrsrvuwL/zAtMbkyYWzEiUxJtx/w0bw8rC90GoPRSCmxyI0ZK8FuPy
-IAQ7UeNfTWZ485mAUaTSasGIfQ3DY4F0P+aUSijeG3NUY02nALHDMqJX7lXR+mL1
-DUYDg05KB0jxQwlYqBeujTPPiAzEqm3PlBoHuan8/qgK2wdQMTVg/fieUD3lupmV
-Wj2dRZgqfBPA16ZbV4Uo0j0bZSf+fQLiXlU2VJGb5i/FQfjLqMKGABDI0MgK7Sc2
-m4ySpV4g4XKDv/vw6Dw4kwWC7mATEVAkH+q6V7uiZeN6a7w30UMtPI8fPaUvAP3L
-VBjCBIv/3m+CKkWcNxOZ3sQBQl5bS05dxcfiVsBvBLYbvQgC+Wy0Sc3b+1pXFT/E
-uAsbZ4CyVsi1+PAdx3h5e2QAyNCXgZDOcvTUyxY6JLTE0LOVHmI4fJEujBex//Oz
-PCRHvC8K+KiljyQWf/NYrLSD3QGYAjVMtQh7yu2yhzWzgBUxyhuv3rY4ATXsN3bJ
-wW4w7/L/RSLSW5+lp/NoJOD9utbsKTyGMHOY6K8JLOmhv3ORoAEmLYlFTI+FqBi9
-AH1HQEKCyh8Z/bYHLUzGWl6FqAMtcnuintv40BbKyt0/D1ItdbSNKmOZ5rkCAwEA
-AQKCAgAY7ll8mRNADYkd1Pi+UVwgMM6B3WJO6z8LZUOhtyxxqmzZ1VnGiShMBrqh
-sPCsuSHTeswxQbvT81TpVZI/91RUKtbn0VbVSFUWyX4AtY4XPtUT0gHy2/vkh0Y6
-93ruDIdd0Wfhmh+GCV4sUhO8ZKpMWpk6XTQHYuzr2UCHcKlkqElrO6qpzLqXNe3D
-iOWBYPc7WBB0RxO0aPnCIq/SCEc55/MBZdSWR80e+sILtNsagPl3djQaoanub3wI
-a0yPv2YfMHHX7H9cfBY8WYsi8bs4MhqqEcAs2m6XtitU3mJpVcooLJYcmOZ1GYZr
-BfYKLouWcnGmNi4IiLHqVzMaQDkEhAZsRaAXCkoVVrFBedLlmLPpiUIQlINF4vxe
-3IcekTKWyMzkU6h+K8T15MU5mLSqeL2Gji1JIwKJno51FZ9uc++pUJVtfYQmNny8
-8RKvQ1hv/S5yLQKgN+VkNbaWlUoMP73dtUe3m/At71/2Dj7xB0KtcgT1lEMrM1GR
-oynJAJLz/d0n5RUUREwkZZMcA4fQVC7Db6vpK69jPiQMShpZ3JKCEjfYLUuN0slt
-FPhjiR175E0vTRuLoIj4kXNwLLswH0c9zqrKM2S92SCxAV3E4JJGKhUZalvT9s1g
-LrPhMCl6CsOES98T87d3RyAIK0iVRCnRUG3bc+8rzyRd4fzkAQKCAQEA/UjmCSm3
-H46t/1w7YBZPew7SFQOAJe81iDzbonc3fNPD2R8lxtD3MwdvrQ5f9fhT4+uveWNr
-dyBX7ppnissyM3LZRN+7BdeIVVeIPVen6Ou9W2i7q18ZoQx9IpRcZEw5tGJFZaGx
-EmyPN4i1K0ccUkGbBvbXXQ/tcG3wElRpBAc5/TQ8vrpUgHll2/MbYhowx6P9uHv5
-thoyG98X+7Fbg8ikzw5GtyuedXfyX1CpJ7yUQVS2PEaOMXOkZdx2bbWRAYYCpsqB
-dMmjs2PsFhZHu6CpLhlocHbfUiRztCUCaMZJPQXFSVmy8QDMvZEdVLvad9Poi8ny
-lmHVRgxaNbAtIQKCAQEA9nscqRaaO7hIX9bOUxcDbI0486Ws4H0hAFApIN+6/LP4
-hkxey3xWArTYWrvSG1d5GkJAdn99ayWzo2PevmJlrhIJiO1QqYBAk+87cnhwSCmB
-kb0sGkNWcc/xNRy7eqdhyCmVhaUnIbORee+cD6qiu/l2BAclTf2ZARFOGXjhQkvt
-cDbc/9ZR467ceXbiTIU34Be4xnNAY1mo59jvwl9eqxgpefYTqPhcZ7OmlDli77Hd
-XuRfuxLZCscv7A9M5Enc2zwOEP5VwRNwYzYtMm2Yh9CQZxNWC7JVh1Gw5MPFzsGl
-sgEdb4WGneN6PPLQHK7NF0f7wYSNnF0i3XSME9MumQKCAQEA0qMbWydr+TyJC0LC
-xigHtUkgAQXGPsXuePxTk4sdhBwAVcKHgg4qZi+a+gpoV4BLE9LfPU4nAwzM08to
-rI5Lk2nBsnt1Z2hVItQGoy0QoK3b7fbti5ktETf3oRhMtcSGgLLxD5ImVjId8Isq
-T3F15hpVOLdzZxtl1Qg4jKXSJ91yplYY5mzC9Yz/3qkQbsdlJcIFsLS5eG3UmkUw
-Bsr6VmA4X1F6Eb6eqwYzdHz6D+fOS36NhxcODaYkY+myO46xptixv8/NVTiTgQ5q
-OfwRb8Iur/3FUzIoioFyD7Bvjn7ITY1NArEsFS0bF9Nk1yDakKiUThyGN/Xojbac
-FuYKwQKCAQEAxOWJ+qU8phJLdowBHC0ZJiEWasRhep9auoZOpJ01IWOfV6EwZLs5
-dkYDQ1Agwoi5DDn6hu7HQM3IV/CS4mF2OnzcMw7ozc7PR53nTkVZ5LuLbuHAlmZO
-avKjDDucpJmLqjtV34IT5X8t6kt3zqgQAbuBBCy1Jz07ebfaPMzsnWpMDcU1/AW4
-OvrX0wweMOSGwzQP/i/ZMsRQAo2w0gQfeuv9Thk+kU99ebXwjx3co//hCEnFE4s1
-6L8/0AJU+VTr4hJyZi7WUDt4HzkLF+qm22/Hux+eMA/Q9R1UAxtFLCpTdAQiAJGY
-/Q3X+1I434DgAwYU3f1Gpq9cB65vq/KamQKCAQEAjIub5wde/ttHlLALvnOXrbqe
-nUIfWHExMzhul/rkr8fFEJwij2nZUuN2EWUGzBWQQoNXw5QKHLZyPsyFUOa/P2BS
-osnffAa+sumL4k36E71xFdTVV5ExyTXZVB49sPmUpivP9gEucFFqDHKjGsF45dBF
-+DZdykLUIv+/jQUzXGkZ5Wv/r52YUNho4EZdwnlJ2so7cxnsYnjW+c1nlp17tkq5
-DfwktkeD9iFzlaZ66vLoO44luaBm+lC3xM2sHinOTwbk0gvhJAIoLfkOYhpmGc8A
-4W/E1OHfVz6xqVDsMBFhRbQpHNkf8XZNqkIoqHVMTaMOJJlM+lb0+A9B8Bm/XA==
------END RSA PRIVATE KEY-----
diff --git a/apex/statsd/com.android.os.statsd.pk8 b/apex/statsd/com.android.os.statsd.pk8
deleted file mode 100644
index 49910f80a05c..000000000000
--- a/apex/statsd/com.android.os.statsd.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.x509.pem b/apex/statsd/com.android.os.statsd.x509.pem
deleted file mode 100644
index e7b16b2048cb..000000000000
--- a/apex/statsd/com.android.os.statsd.x509.pem
+++ /dev/null
@@ -1,30 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFDTCCAvWgAwIBAgIUCnta1LAl5fMMLLQx//4zWz9A2A8wDQYJKoZIhvcNAQEL
-BQAwFTETMBEGA1UECgwKR29vZ2xlIExMQzAgFw0xOTA4MTIyMjM5MzBaGA80NzU3
-MDcwODIyMzkzMFowFTETMBEGA1UECgwKR29vZ2xlIExMQzCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBAOranWZ19jkXCF9WIlXv01tUUvLKMHWKV7X9Earw
-cL7/aax0pFbNJutgyBUiOszbR+0T7quZxz6jACu+6y7iaMJnvMluZsfTi+p2UvQt
-y6Ql7ZUOQ7bVluCFIW5hZ+8d9RrLmZdvX1r4YfF6HufDBkAbj+os+y6407OezJAV
-8EATpemc9gsCC4RJZpwzTs1RUXMD4UoNrLZAE8+7iaJZeBxmz0MAPj92pYc9M7/d
-xInzYvOR08/uEpHt8jlMdVgSQS/FaRlIOIqcGBk3cjkjDlpVATQ4Hyjy+IPQPjTD
-bJUmDJiYeBCyY/pYZQvTQjl8s+fvykTsF9Lfb+E+PhZ0+N8pRi7sUSpisZHSiqaN
-W3oxYWc0YQSuzygHHog8HH/azHX5L805g/+Rwfb/cUF9eJgjq0vrkFnsz4UKgKNV
-hHL90mfqpbc2UvJ8VY8BvIjbsHQ77LrBKlqI9VMPorttpTOuwHHJPKsyN972F0Ul
-lRB6CwFE8csVGWXoNaDZWBv7xTDdbdirmlKDNueg9pw6ksYV2Is9Dv8PxmsZvb+4
-oftC/hb4X1Pudn01PPs9Tx44CwHuVLENUwlDEVzG5zNetsv9kAuCYt3VRVF+NYqj
-NAfLbxCKLe25wGzJrZUEJ1YrYIjpUbfwnttEad/9Pu13DAS7HZwn5vwqEKB/1LlT
-NSUXAgMBAAGjUzBRMB0GA1UdDgQWBBSKElkhJSbzgh8+iysye8SrkmJ62DAfBgNV
-HSMEGDAWgBSKElkhJSbzgh8+iysye8SrkmJ62DAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBCwUAA4ICAQANFGnc2wJBrFbh2nzhl06g4TjPKGRCw365vZ1A3T9O
-jXP0lToHDxB33TpKk6d7zszR1uPphQQxgzhSVZB/jx8q4kWSSoKoF9Dlx7h8rAt+
-2TM5DaBvxrwu5mqOALwQuF81wap1Pl2L2fFHvygCm8b+Ci4iS5vcr0axNnp1rK1b
-vUtRWY4mfxTjJYcgeCVUGskqTb+cCxQZ6Icno6VTKajT1FybRmD3KZJaUuLbNEN+
-IE4nGTMG2WZ5Hl2vR8JJp1sYYn8T3ElMAb0MSNFkqsfI+tToEwGsuJDgYEdtEnzf
-lTycQvn5NhrIZRRN3pqSyWpAU7p9mmyTK0PHMz2D/Rtfb7lE692vXzxCmZND51mc
-YXCCoanV6eZZ7Sbqzh60+5QV38hgFBst5l8CcFaWWSFK9nBWdzS5lhs9lmQ4aiYd
-IE0qsNZgMob+TTP1VW39hu4EDjNmOrKfimM9J2tcPZ5QP01DgETPvAsB7vn2Xz9J
-HGt5ntiSV4W2izDP8viQ1M5NvfdBaUhcnNsE6/sxfU0USRs2hrEp1oiqrv4p6V0P
-qOt7C2/YtJzkrxfsHZAxBUSRHa7LwtzgeiJDUivHn94VnAzSAH8MLx6CzDPQ8HWN
-NiZFxTKfMVyjEmbQ2PalHWB8pWtpdEh7X4rzaqhnLBTis3pGssASgo3ArLIYleAU
-+g==
------END CERTIFICATE-----
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
deleted file mode 100644
index 09ab56384761..000000000000
--- a/apex/statsd/framework/Android.bp
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_visibility: [ ":__pkg__" ]
-}
-
-genrule {
- name: "statslog-statsd-java-gen",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --module statsd" +
- " --javaPackage com.android.internal.statsd --javaClass StatsdStatsLog",
- out: ["com/android/internal/statsd/StatsdStatsLog.java"],
-}
-
-java_library_static {
- name: "statslog-statsd",
- srcs: [
- ":statslog-statsd-java-gen",
- ],
- visibility: [
- "//cts/hostsidetests/statsd/apps:__subpackages__",
- ]
-}
-
-filegroup {
- name: "framework-statsd-sources",
- srcs: [
- "java/**/*.java",
- ":framework-statsd-aidl-sources",
- ":statslog-statsd-java-gen",
- ],
- visibility: [
- "//frameworks/base", // For the "global" stubs.
- "//frameworks/base/apex/statsd:__subpackages__",
- ],
-}
-java_sdk_library {
- name: "framework-statsd",
- defaults: ["framework-module-defaults"],
- installable: true,
-
- srcs: [
- ":framework-statsd-sources",
- ],
-
- permitted_packages: [
- "android.app",
- "android.os",
- "android.util",
- // From :statslog-statsd-java-gen
- "com.android.internal.statsd",
- ],
-
- api_packages: [
- "android.app",
- "android.os",
- "android.util",
- ],
-
- hostdex: true, // for hiddenapi check
-
- impl_library_visibility: ["//frameworks/base/apex/statsd/framework/test:__subpackages__"],
-
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
diff --git a/apex/statsd/framework/api/current.txt b/apex/statsd/framework/api/current.txt
deleted file mode 100644
index a65569347e7d..000000000000
--- a/apex/statsd/framework/api/current.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-// Signature format: 2.0
-package android.util {
-
- public final class StatsLog {
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public static boolean logBinaryPushStateChanged(@NonNull String, long, int, int, @NonNull long[]);
- method public static boolean logEvent(int);
- method public static boolean logStart(int);
- method public static boolean logStop(int);
- }
-
-}
-
diff --git a/apex/statsd/framework/api/module-lib-current.txt b/apex/statsd/framework/api/module-lib-current.txt
deleted file mode 100644
index 8b6e2170002e..000000000000
--- a/apex/statsd/framework/api/module-lib-current.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-// Signature format: 2.0
-package android.os {
-
- public class StatsFrameworkInitializer {
- method public static void registerServiceWrappers();
- method public static void setStatsServiceManager(@NonNull android.os.StatsServiceManager);
- }
-
-}
-
diff --git a/apex/statsd/framework/api/module-lib-removed.txt b/apex/statsd/framework/api/module-lib-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/statsd/framework/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/api/removed.txt b/apex/statsd/framework/api/removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/statsd/framework/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/api/system-current.txt b/apex/statsd/framework/api/system-current.txt
deleted file mode 100644
index 3ea572450c1c..000000000000
--- a/apex/statsd/framework/api/system-current.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-// Signature format: 2.0
-package android.app {
-
- public final class StatsManager {
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void addConfig(long, byte[]) throws android.app.StatsManager.StatsUnavailableException;
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
- method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void clearPullAtomCallback(int);
- method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getData(long);
- method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getMetadata();
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
- method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void setPullAtomCallback(int, @Nullable android.app.StatsManager.PullAtomMetadata, @NonNull java.util.concurrent.Executor, @NonNull android.app.StatsManager.StatsPullAtomCallback);
- field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
- field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
- field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
- field public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
- field public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
- field public static final String EXTRA_STATS_DIMENSIONS_VALUE = "android.app.extra.STATS_DIMENSIONS_VALUE";
- field public static final String EXTRA_STATS_SUBSCRIPTION_ID = "android.app.extra.STATS_SUBSCRIPTION_ID";
- field public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
- field public static final int PULL_SKIP = 1; // 0x1
- field public static final int PULL_SUCCESS = 0; // 0x0
- }
-
- public static class StatsManager.PullAtomMetadata {
- method @Nullable public int[] getAdditiveFields();
- method public long getCoolDownMillis();
- method public long getTimeoutMillis();
- }
-
- public static class StatsManager.PullAtomMetadata.Builder {
- ctor public StatsManager.PullAtomMetadata.Builder();
- method @NonNull public android.app.StatsManager.PullAtomMetadata build();
- method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setAdditiveFields(@NonNull int[]);
- method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setCoolDownMillis(long);
- method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setTimeoutMillis(long);
- }
-
- public static interface StatsManager.StatsPullAtomCallback {
- method public int onPullAtom(int, @NonNull java.util.List<android.util.StatsEvent>);
- }
-
- public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
- ctor public StatsManager.StatsUnavailableException(String);
- ctor public StatsManager.StatsUnavailableException(String, Throwable);
- }
-
-}
-
-package android.os {
-
- public final class StatsDimensionsValue implements android.os.Parcelable {
- method public int describeContents();
- method public boolean getBooleanValue();
- method public int getField();
- method public float getFloatValue();
- method public int getIntValue();
- method public long getLongValue();
- method public String getStringValue();
- method public java.util.List<android.os.StatsDimensionsValue> getTupleValueList();
- method public int getValueType();
- method public boolean isValueType(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BOOLEAN_VALUE_TYPE = 5; // 0x5
- field @NonNull public static final android.os.Parcelable.Creator<android.os.StatsDimensionsValue> CREATOR;
- field public static final int FLOAT_VALUE_TYPE = 6; // 0x6
- field public static final int INT_VALUE_TYPE = 3; // 0x3
- field public static final int LONG_VALUE_TYPE = 4; // 0x4
- field public static final int STRING_VALUE_TYPE = 2; // 0x2
- field public static final int TUPLE_VALUE_TYPE = 7; // 0x7
- }
-
-}
-
-package android.util {
-
- public final class StatsEvent {
- method @NonNull public static android.util.StatsEvent.Builder newBuilder();
- }
-
- public static final class StatsEvent.Builder {
- method @NonNull public android.util.StatsEvent.Builder addBooleanAnnotation(byte, boolean);
- method @NonNull public android.util.StatsEvent.Builder addIntAnnotation(byte, int);
- method @NonNull public android.util.StatsEvent build();
- method @NonNull public android.util.StatsEvent.Builder setAtomId(int);
- method @NonNull public android.util.StatsEvent.Builder usePooledBuffer();
- method @NonNull public android.util.StatsEvent.Builder writeAttributionChain(@NonNull int[], @NonNull String[]);
- method @NonNull public android.util.StatsEvent.Builder writeBoolean(boolean);
- method @NonNull public android.util.StatsEvent.Builder writeByteArray(@NonNull byte[]);
- method @NonNull public android.util.StatsEvent.Builder writeFloat(float);
- method @NonNull public android.util.StatsEvent.Builder writeInt(int);
- method @NonNull public android.util.StatsEvent.Builder writeKeyValuePairs(@Nullable android.util.SparseIntArray, @Nullable android.util.SparseLongArray, @Nullable android.util.SparseArray<java.lang.String>, @Nullable android.util.SparseArray<java.lang.Float>);
- method @NonNull public android.util.StatsEvent.Builder writeLong(long);
- method @NonNull public android.util.StatsEvent.Builder writeString(@NonNull String);
- }
-
- public final class StatsLog {
- method public static void write(@NonNull android.util.StatsEvent);
- method public static void writeRaw(@NonNull byte[], int);
- }
-
-}
-
diff --git a/apex/statsd/framework/api/system-removed.txt b/apex/statsd/framework/api/system-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/apex/statsd/framework/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/java/android/app/StatsManager.java b/apex/statsd/framework/java/android/app/StatsManager.java
deleted file mode 100644
index a7d20572ca96..000000000000
--- a/apex/statsd/framework/java/android/app/StatsManager.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.app;
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IPullAtomCallback;
-import android.os.IPullAtomResultReceiver;
-import android.os.IStatsManagerService;
-import android.os.RemoteException;
-import android.os.StatsFrameworkInitializer;
-import android.util.AndroidException;
-import android.util.Log;
-import android.util.StatsEvent;
-import android.util.StatsEventParcel;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * API for statsd clients to send configurations and retrieve data.
- *
- * @hide
- */
-@SystemApi
-public final class StatsManager {
- private static final String TAG = "StatsManager";
- private static final boolean DEBUG = false;
-
- private static final Object sLock = new Object();
- private final Context mContext;
-
- @GuardedBy("sLock")
- private IStatsManagerService mStatsManagerService;
-
- /**
- * Long extra of uid that added the relevant stats config.
- */
- public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
- /**
- * Long extra of the relevant stats config's configKey.
- */
- public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
- /**
- * Long extra of the relevant statsd_config.proto's Subscription.id.
- */
- public static final String EXTRA_STATS_SUBSCRIPTION_ID =
- "android.app.extra.STATS_SUBSCRIPTION_ID";
- /**
- * Long extra of the relevant statsd_config.proto's Subscription.rule_id.
- */
- public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID =
- "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
- /**
- * List<String> of the relevant statsd_config.proto's BroadcastSubscriberDetails.cookie.
- * Obtain using {@link android.content.Intent#getStringArrayListExtra(String)}.
- */
- public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES =
- "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
- /**
- * Extra of a {@link android.os.StatsDimensionsValue} representing sliced dimension value
- * information.
- */
- public static final String EXTRA_STATS_DIMENSIONS_VALUE =
- "android.app.extra.STATS_DIMENSIONS_VALUE";
- /**
- * Long array extra of the active configs for the uid that added those configs.
- */
- public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS =
- "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
-
- /**
- * Broadcast Action: Statsd has started.
- * Configurations and PendingIntents can now be sent to it.
- */
- public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
-
- // Pull atom callback return codes.
- /**
- * Value indicating that this pull was successful and that the result should be used.
- *
- **/
- public static final int PULL_SUCCESS = 0;
-
- /**
- * Value indicating that this pull was unsuccessful and that the result should not be used.
- **/
- public static final int PULL_SKIP = 1;
-
- /**
- * @hide
- **/
- @VisibleForTesting public static final long DEFAULT_COOL_DOWN_MILLIS = 1_000L; // 1 second.
-
- /**
- * @hide
- **/
- @VisibleForTesting public static final long DEFAULT_TIMEOUT_MILLIS = 2_000L; // 2 seconds.
-
- /**
- * Constructor for StatsManagerClient.
- *
- * @hide
- */
- public StatsManager(Context context) {
- mContext = context;
- }
-
- /**
- * Adds the given configuration and associates it with the given configKey. If a config with the
- * given configKey already exists for the caller's uid, it is replaced with the new one.
- *
- * @param configKey An arbitrary integer that allows clients to track the configuration.
- * @param config Wire-encoded StatsdConfig proto that specifies metrics (and all
- * dependencies eg, conditions and matchers).
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- * @throws IllegalArgumentException if config is not a wire-encoded StatsdConfig proto
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void addConfig(long configKey, byte[] config) throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- // can throw IllegalArgumentException
- service.addConfiguration(configKey, config, mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when adding configuration");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to addConfig in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #addConfig(long, byte[])}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean addConfiguration(long configKey, byte[] config) {
- try {
- addConfig(configKey, config);
- return true;
- } catch (StatsUnavailableException | IllegalArgumentException e) {
- return false;
- }
- }
-
- /**
- * Remove a configuration from logging.
- *
- * @param configKey Configuration key to remove.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void removeConfig(long configKey) throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- service.removeConfiguration(configKey, mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when removing configuration");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to removeConfig in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #removeConfig(long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean removeConfiguration(long configKey) {
- try {
- removeConfig(configKey);
- return true;
- } catch (StatsUnavailableException e) {
- return false;
- }
- }
-
- /**
- * Set the PendingIntent to be used when broadcasting subscriber information to the given
- * subscriberId within the given config.
- * <p>
- * Suppose that the calling uid has added a config with key configKey, and that in this config
- * it is specified that when a particular anomaly is detected, a broadcast should be sent to
- * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
- * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
- * when the anomaly is detected.
- * <p>
- * When statsd sends the broadcast, the PendingIntent will used to send an intent with
- * information of
- * {@link #EXTRA_STATS_CONFIG_UID},
- * {@link #EXTRA_STATS_CONFIG_KEY},
- * {@link #EXTRA_STATS_SUBSCRIPTION_ID},
- * {@link #EXTRA_STATS_SUBSCRIPTION_RULE_ID},
- * {@link #EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES}, and
- * {@link #EXTRA_STATS_DIMENSIONS_VALUE}.
- * <p>
- * This function can only be called by the owner (uid) of the config. It must be called each
- * time statsd starts. The config must have been added first (via {@link #addConfig}).
- *
- * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
- * associated with the given subscriberId. May be null, in which case
- * it undoes any previous setting of this subscriberId.
- * @param configKey The integer naming the config to which this subscriber is attached.
- * @param subscriberId ID of the subscriber, as used in the config.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void setBroadcastSubscriber(
- PendingIntent pendingIntent, long configKey, long subscriberId)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- if (pendingIntent != null) {
- service.setBroadcastSubscriber(configKey, subscriberId, pendingIntent,
- mContext.getOpPackageName());
- } else {
- service.unsetBroadcastSubscriber(configKey, subscriberId,
- mContext.getOpPackageName());
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when adding broadcast subscriber",
- e);
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #setBroadcastSubscriber(PendingIntent, long, long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean setBroadcastSubscriber(
- long configKey, long subscriberId, PendingIntent pendingIntent) {
- try {
- setBroadcastSubscriber(pendingIntent, configKey, subscriberId);
- return true;
- } catch (StatsUnavailableException e) {
- return false;
- }
- }
-
- /**
- * Registers the operation that is called to retrieve the metrics data. This must be called
- * each time statsd starts. The config must have been added first (via {@link #addConfig},
- * although addConfig could have been called on a previous boot). This operation allows
- * statsd to send metrics data whenever statsd determines that the metrics in memory are
- * approaching the memory limits. The fetch operation should call {@link #getReports} to fetch
- * the data, which also deletes the retrieved metrics from statsd's memory.
- *
- * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
- * associated with the given subscriberId. May be null, in which case
- * it removes any associated pending intent with this configKey.
- * @param configKey The integer naming the config to which this operation is attached.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void setFetchReportsOperation(PendingIntent pendingIntent, long configKey)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- if (pendingIntent == null) {
- service.removeDataFetchOperation(configKey, mContext.getOpPackageName());
- } else {
- service.setDataFetchOperation(configKey, pendingIntent,
- mContext.getOpPackageName());
- }
-
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when registering data listener.");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- /**
- * Registers the operation that is called whenever there is a change in which configs are
- * active. This must be called each time statsd starts. This operation allows
- * statsd to inform clients that they should pull data of the configs that are currently
- * active. The activeConfigsChangedOperation should set periodic alarms to pull data of configs
- * that are active and stop pulling data of configs that are no longer active.
- *
- * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
- * associated with the given subscriberId. May be null, in which case
- * it removes any associated pending intent for this client.
- * @return A list of configs that are currently active for this client. If the pendingIntent is
- * null, this will be an empty list.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public @NonNull long[] setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- if (pendingIntent == null) {
- service.removeActiveConfigsChangedOperation(mContext.getOpPackageName());
- return new long[0];
- } else {
- return service.setActiveConfigsChangedOperation(pendingIntent,
- mContext.getOpPackageName());
- }
-
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager "
- + "when registering active configs listener.");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #setFetchReportsOperation(PendingIntent, long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public boolean setDataFetchOperation(long configKey, PendingIntent pendingIntent) {
- try {
- setFetchReportsOperation(pendingIntent, configKey);
- return true;
- } catch (StatsUnavailableException e) {
- return false;
- }
- }
-
- /**
- * Request the data collected for the given configKey.
- * This getter is destructive - it also clears the retrieved metrics from statsd's memory.
- *
- * @param configKey Configuration key to retrieve data from.
- * @return Serialized ConfigMetricsReportList proto.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public byte[] getReports(long configKey) throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- return service.getData(configKey, mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when getting data");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to getReports in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #getReports(long)}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public @Nullable byte[] getData(long configKey) {
- try {
- return getReports(configKey);
- } catch (StatsUnavailableException e) {
- return null;
- }
- }
-
- /**
- * Clients can request metadata for statsd. Will contain stats across all configurations but not
- * the actual metrics themselves (metrics must be collected via {@link #getReports(long)}.
- * This getter is not destructive and will not reset any metrics/counters.
- *
- * @return Serialized StatsdStatsReport proto.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public byte[] getStatsMetadata() throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- return service.getMetadata(mContext.getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to connect to statsmanager when getting metadata");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to getStatsMetadata in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- // TODO: Temporary for backwards compatibility. Remove.
- /**
- * @deprecated Use {@link #getStatsMetadata()}
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public @Nullable byte[] getMetadata() {
- try {
- return getStatsMetadata();
- } catch (StatsUnavailableException e) {
- return null;
- }
- }
-
- /**
- * Returns the experiments IDs registered with statsd, or an empty array if there aren't any.
- *
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- */
- @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
- public long[] getRegisteredExperimentIds()
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- return service.getRegisteredExperimentIds();
- } catch (RemoteException e) {
- if (DEBUG) {
- Log.d(TAG,
- "Failed to connect to StatsManagerService when getting "
- + "registered experiment IDs");
- }
- throw new StatsUnavailableException("could not connect", e);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to getRegisteredExperimentIds in statsmanager");
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
- /**
- * Sets a callback for an atom when that atom is to be pulled. The stats service will
- * invoke pullData in the callback when the stats service determines that this atom needs to be
- * pulled. This method should not be called by third-party apps.
- *
- * @param atomTag The tag of the atom for this puller callback.
- * @param metadata Optional metadata specifying the timeout, cool down time, and
- * additive fields for mapping isolated to host uids.
- * @param executor The executor in which to run the callback.
- * @param callback The callback to be invoked when the stats service pulls the atom.
- *
- */
- @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM)
- public void setPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull StatsPullAtomCallback callback) {
- long coolDownMillis =
- metadata == null ? DEFAULT_COOL_DOWN_MILLIS : metadata.mCoolDownMillis;
- long timeoutMillis = metadata == null ? DEFAULT_TIMEOUT_MILLIS : metadata.mTimeoutMillis;
- int[] additiveFields = metadata == null ? new int[0] : metadata.mAdditiveFields;
- if (additiveFields == null) {
- additiveFields = new int[0];
- }
-
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- PullAtomCallbackInternal rec =
- new PullAtomCallbackInternal(atomTag, callback, executor);
- service.registerPullAtomCallback(
- atomTag, coolDownMillis, timeoutMillis, additiveFields, rec);
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to register pull callback", e);
- }
- }
- }
-
- /**
- * Clears a callback for an atom when that atom is to be pulled. Note that any ongoing
- * pulls will still occur. This method should not be called by third-party apps.
- *
- * @param atomTag The tag of the atom of which to unregister
- *
- */
- @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM)
- public void clearPullAtomCallback(int atomTag) {
- synchronized (sLock) {
- try {
- IStatsManagerService service = getIStatsManagerServiceLocked();
- service.unregisterPullAtomCallback(atomTag);
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to unregister pull atom callback");
- }
- }
- }
-
- private static class PullAtomCallbackInternal extends IPullAtomCallback.Stub {
- public final int mAtomId;
- public final StatsPullAtomCallback mCallback;
- public final Executor mExecutor;
-
- PullAtomCallbackInternal(int atomId, StatsPullAtomCallback callback, Executor executor) {
- mAtomId = atomId;
- mCallback = callback;
- mExecutor = executor;
- }
-
- @Override
- public void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver) {
- long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- List<StatsEvent> data = new ArrayList<>();
- int successInt = mCallback.onPullAtom(atomTag, data);
- boolean success = successInt == PULL_SUCCESS;
- StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
- for (int i = 0; i < data.size(); i++) {
- parcels[i] = new StatsEventParcel();
- parcels[i].buffer = data.get(i).getBytes();
- }
- try {
- resultReceiver.pullFinished(atomTag, success, parcels);
- } catch (RemoteException e) {
- Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
- + " due to TransactionTooLarge. Calling pullFinish with no data");
- StatsEventParcel[] emptyData = new StatsEventParcel[0];
- try {
- resultReceiver.pullFinished(atomTag, /*success=*/false, emptyData);
- } catch (RemoteException nestedException) {
- Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
- + " with empty payload");
- }
- }
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- }
-
- /**
- * Metadata required for registering a StatsPullAtomCallback.
- * All fields are optional, and defaults will be used for fields that are unspecified.
- *
- */
- public static class PullAtomMetadata {
- private final long mCoolDownMillis;
- private final long mTimeoutMillis;
- private final int[] mAdditiveFields;
-
- // Private Constructor for builder
- private PullAtomMetadata(long coolDownMillis, long timeoutMillis, int[] additiveFields) {
- mCoolDownMillis = coolDownMillis;
- mTimeoutMillis = timeoutMillis;
- mAdditiveFields = additiveFields;
- }
-
- /**
- * Builder for PullAtomMetadata.
- */
- public static class Builder {
- private long mCoolDownMillis;
- private long mTimeoutMillis;
- private int[] mAdditiveFields;
-
- /**
- * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
- * StatsManager#registerPullAtomCallback
- */
- public Builder() {
- mCoolDownMillis = DEFAULT_COOL_DOWN_MILLIS;
- mTimeoutMillis = DEFAULT_TIMEOUT_MILLIS;
- mAdditiveFields = null;
- }
-
- /**
- * Set the cool down time of the pull in milliseconds. If two successive pulls are
- * issued within the cool down, a cached version of the first pull will be used for the
- * second pull. The minimum allowed cool down is 1 second.
- */
- @NonNull
- public Builder setCoolDownMillis(long coolDownMillis) {
- mCoolDownMillis = coolDownMillis;
- return this;
- }
-
- /**
- * Set the maximum time the pull can take in milliseconds. The maximum allowed timeout
- * is 10 seconds.
- */
- @NonNull
- public Builder setTimeoutMillis(long timeoutMillis) {
- mTimeoutMillis = timeoutMillis;
- return this;
- }
-
- /**
- * Set the additive fields of this pulled atom.
- *
- * This is only applicable for atoms which have a uid field. When tasks are run in
- * isolated processes, the data will be attributed to the host uid. Additive fields
- * will be combined when the non-additive fields are the same.
- */
- @NonNull
- public Builder setAdditiveFields(@NonNull int[] additiveFields) {
- mAdditiveFields = additiveFields;
- return this;
- }
-
- /**
- * Builds and returns a PullAtomMetadata object with the values set in the builder and
- * defaults for unset fields.
- */
- @NonNull
- public PullAtomMetadata build() {
- return new PullAtomMetadata(mCoolDownMillis, mTimeoutMillis, mAdditiveFields);
- }
- }
-
- /**
- * Return the cool down time of this pull in milliseconds.
- */
- public long getCoolDownMillis() {
- return mCoolDownMillis;
- }
-
- /**
- * Return the maximum amount of time this pull can take in milliseconds.
- */
- public long getTimeoutMillis() {
- return mTimeoutMillis;
- }
-
- /**
- * Return the additive fields of this pulled atom.
- *
- * This is only applicable for atoms that have a uid field. When tasks are run in
- * isolated processes, the data will be attributed to the host uid. Additive fields
- * will be combined when the non-additive fields are the same.
- */
- @Nullable
- public int[] getAdditiveFields() {
- return mAdditiveFields;
- }
- }
-
- /**
- * Callback interface for pulling atoms requested by the stats service.
- *
- */
- public interface StatsPullAtomCallback {
- /**
- * Pull data for the specified atom tag, filling in the provided list of StatsEvent data.
- * @return {@link #PULL_SUCCESS} if the pull was successful, or {@link #PULL_SKIP} if not.
- */
- int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
- }
-
- @GuardedBy("sLock")
- private IStatsManagerService getIStatsManagerServiceLocked() {
- if (mStatsManagerService != null) {
- return mStatsManagerService;
- }
- mStatsManagerService = IStatsManagerService.Stub.asInterface(
- StatsFrameworkInitializer
- .getStatsServiceManager()
- .getStatsManagerServiceRegisterer()
- .get());
- return mStatsManagerService;
- }
-
- /**
- * Exception thrown when communication with the stats service fails (eg if it is not available).
- * This might be thrown early during boot before the stats service has started or if it crashed.
- */
- public static class StatsUnavailableException extends AndroidException {
- public StatsUnavailableException(String reason) {
- super("Failed to connect to statsd: " + reason);
- }
-
- public StatsUnavailableException(String reason, Throwable e) {
- super("Failed to connect to statsd: " + reason, e);
- }
- }
-}
diff --git a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
deleted file mode 100644
index 7d9349cefa48..000000000000
--- a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.os;
-
-import android.annotation.SystemApi;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container for statsd dimension value information, corresponding to a
- * stats_log.proto's DimensionValue.
- *
- * This consists of a field (an int representing a statsd atom field)
- * and a value (which may be one of a number of types).
- *
- * <p>
- * Only a single value is held, and it is necessarily one of the following types:
- * {@link String}, int, long, boolean, float,
- * or tuple (i.e. {@link List} of {@code StatsDimensionsValue}).
- *
- * The type of value held can be retrieved using {@link #getValueType()}, which returns one of the
- * following ints, depending on the type of value:
- * <ul>
- * <li>{@link #STRING_VALUE_TYPE}</li>
- * <li>{@link #INT_VALUE_TYPE}</li>
- * <li>{@link #LONG_VALUE_TYPE}</li>
- * <li>{@link #BOOLEAN_VALUE_TYPE}</li>
- * <li>{@link #FLOAT_VALUE_TYPE}</li>
- * <li>{@link #TUPLE_VALUE_TYPE}</li>
- * </ul>
- * Alternatively, this can be determined using {@link #isValueType(int)} with one of these constants
- * as a parameter.
- * The value itself can be retrieved using the correct get...Value() function for its type.
- *
- * <p>
- * The field is always an int, and always exists; it can be obtained using {@link #getField()}.
- *
- *
- * @hide
- */
-@SystemApi
-public final class StatsDimensionsValue implements Parcelable {
- private static final String TAG = "StatsDimensionsValue";
-
- // Values of the value type correspond to stats_log.proto's DimensionValue fields.
- // Keep constants in sync with frameworks/base/cmds/statsd/src/HashableDimensionKey.cpp.
- /** Indicates that this holds a String. */
- public static final int STRING_VALUE_TYPE = 2;
- /** Indicates that this holds an int. */
- public static final int INT_VALUE_TYPE = 3;
- /** Indicates that this holds a long. */
- public static final int LONG_VALUE_TYPE = 4;
- /** Indicates that this holds a boolean. */
- public static final int BOOLEAN_VALUE_TYPE = 5;
- /** Indicates that this holds a float. */
- public static final int FLOAT_VALUE_TYPE = 6;
- /** Indicates that this holds a List of StatsDimensionsValues. */
- public static final int TUPLE_VALUE_TYPE = 7;
-
- private final StatsDimensionsValueParcel mInner;
-
- /**
- * Creates a {@code StatsDimensionValue} from a parcel.
- *
- * @hide
- */
- public StatsDimensionsValue(Parcel in) {
- mInner = StatsDimensionsValueParcel.CREATOR.createFromParcel(in);
- }
-
- /**
- * Creates a {@code StatsDimensionsValue} from a StatsDimensionsValueParcel
- *
- * @hide
- */
- public StatsDimensionsValue(StatsDimensionsValueParcel parcel) {
- mInner = parcel;
- }
-
- /**
- * Return the field, i.e. the tag of a statsd atom.
- *
- * @return the field
- */
- public int getField() {
- return mInner.field;
- }
-
- /**
- * Retrieve the String held, if any.
- *
- * @return the {@link String} held if {@link #getValueType()} == {@link #STRING_VALUE_TYPE},
- * null otherwise
- */
- public String getStringValue() {
- if (mInner.valueType == STRING_VALUE_TYPE) {
- return mInner.stringValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not string.");
- return null;
- }
- }
-
- /**
- * Retrieve the int held, if any.
- *
- * @return the int held if {@link #getValueType()} == {@link #INT_VALUE_TYPE}, 0 otherwise
- */
- public int getIntValue() {
- if (mInner.valueType == INT_VALUE_TYPE) {
- return mInner.intValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not int.");
- return 0;
- }
- }
-
- /**
- * Retrieve the long held, if any.
- *
- * @return the long held if {@link #getValueType()} == {@link #LONG_VALUE_TYPE}, 0 otherwise
- */
- public long getLongValue() {
- if (mInner.valueType == LONG_VALUE_TYPE) {
- return mInner.longValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not long.");
- return 0;
- }
- }
-
- /**
- * Retrieve the boolean held, if any.
- *
- * @return the boolean held if {@link #getValueType()} == {@link #BOOLEAN_VALUE_TYPE},
- * false otherwise
- */
- public boolean getBooleanValue() {
- if (mInner.valueType == BOOLEAN_VALUE_TYPE) {
- return mInner.boolValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not boolean.");
- return false;
- }
- }
-
- /**
- * Retrieve the float held, if any.
- *
- * @return the float held if {@link #getValueType()} == {@link #FLOAT_VALUE_TYPE}, 0 otherwise
- */
- public float getFloatValue() {
- if (mInner.valueType == FLOAT_VALUE_TYPE) {
- return mInner.floatValue;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not float.");
- return 0;
- }
- }
-
- /**
- * Retrieve the tuple, in the form of a {@link List} of {@link StatsDimensionsValue}, held,
- * if any.
- *
- * @return the {@link List} of {@link StatsDimensionsValue} held
- * if {@link #getValueType()} == {@link #TUPLE_VALUE_TYPE},
- * null otherwise
- */
- public List<StatsDimensionsValue> getTupleValueList() {
- if (mInner.valueType == TUPLE_VALUE_TYPE) {
- int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
- List<StatsDimensionsValue> tupleValues = new ArrayList<>(length);
- for (int i = 0; i < length; i++) {
- tupleValues.add(new StatsDimensionsValue(mInner.tupleValue[i]));
- }
- return tupleValues;
- } else {
- Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not tuple.");
- return null;
- }
- }
-
- /**
- * Returns the constant representing the type of value stored, namely one of
- * <ul>
- * <li>{@link #STRING_VALUE_TYPE}</li>
- * <li>{@link #INT_VALUE_TYPE}</li>
- * <li>{@link #LONG_VALUE_TYPE}</li>
- * <li>{@link #BOOLEAN_VALUE_TYPE}</li>
- * <li>{@link #FLOAT_VALUE_TYPE}</li>
- * <li>{@link #TUPLE_VALUE_TYPE}</li>
- * </ul>
- *
- * @return the constant representing the type of value stored
- */
- public int getValueType() {
- return mInner.valueType;
- }
-
- /**
- * Returns whether the type of value stored is equal to the given type.
- *
- * @param valueType int representing the type of value stored, as used in {@link #getValueType}
- * @return true if {@link #getValueType()} is equal to {@code valueType}.
- */
- public boolean isValueType(int valueType) {
- return mInner.valueType == valueType;
- }
-
- /**
- * Returns a String representing the information in this StatsDimensionValue.
- * No guarantees are made about the format of this String.
- *
- * @return String representation
- *
- * @hide
- */
- // Follows the format of statsd's dimension.h toString.
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(mInner.field);
- sb.append(":");
- switch (mInner.valueType) {
- case STRING_VALUE_TYPE:
- sb.append(mInner.stringValue);
- break;
- case INT_VALUE_TYPE:
- sb.append(String.valueOf(mInner.intValue));
- break;
- case LONG_VALUE_TYPE:
- sb.append(String.valueOf(mInner.longValue));
- break;
- case BOOLEAN_VALUE_TYPE:
- sb.append(String.valueOf(mInner.boolValue));
- break;
- case FLOAT_VALUE_TYPE:
- sb.append(String.valueOf(mInner.floatValue));
- break;
- case TUPLE_VALUE_TYPE:
- sb.append("{");
- int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
- for (int i = 0; i < length; i++) {
- StatsDimensionsValue child = new StatsDimensionsValue(mInner.tupleValue[i]);
- sb.append(child.toString());
- sb.append("|");
- }
- sb.append("}");
- break;
- default:
- Log.w(TAG, "Incorrect value type");
- break;
- }
- return sb.toString();
- }
-
- /**
- * Parcelable Creator for StatsDimensionsValue.
- */
- public static final @android.annotation.NonNull
- Parcelable.Creator<StatsDimensionsValue> CREATOR = new
- Parcelable.Creator<StatsDimensionsValue>() {
- public StatsDimensionsValue createFromParcel(Parcel in) {
- return new StatsDimensionsValue(in);
- }
-
- public StatsDimensionsValue[] newArray(int size) {
- return new StatsDimensionsValue[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- mInner.writeToParcel(out, flags);
- }
-
- /**
- * Returns a string representation of the type of value stored.
- */
- private String getValueTypeAsString() {
- switch (mInner.valueType) {
- case STRING_VALUE_TYPE:
- return "string";
- case INT_VALUE_TYPE:
- return "int";
- case LONG_VALUE_TYPE:
- return "long";
- case BOOLEAN_VALUE_TYPE:
- return "boolean";
- case FLOAT_VALUE_TYPE:
- return "float";
- case TUPLE_VALUE_TYPE:
- return "tuple";
- default:
- return "unknown";
- }
- }
-}
diff --git a/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java b/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java
deleted file mode 100644
index 8dc91239c2e0..000000000000
--- a/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.os;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.annotation.SystemApi.Client;
-import android.app.StatsManager;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for all stats services
- *
- * @hide
- */
-@SystemApi(client = Client.MODULE_LIBRARIES)
-public class StatsFrameworkInitializer {
- private StatsFrameworkInitializer() {
- }
-
- private static volatile StatsServiceManager sStatsServiceManager;
-
- /**
- * Sets an instance of {@link StatsServiceManager} that allows
- * the statsd mainline module to register/obtain stats binder services. This is called
- * by the platform during the system initialization.
- *
- * @param statsServiceManager instance of {@link StatsServiceManager} that allows
- * the statsd mainline module to register/obtain statsd binder services.
- */
- public static void setStatsServiceManager(
- @NonNull StatsServiceManager statsServiceManager) {
- if (sStatsServiceManager != null) {
- throw new IllegalStateException("setStatsServiceManager called twice!");
- }
-
- if (statsServiceManager == null) {
- throw new NullPointerException("statsServiceManager is null");
- }
-
- sStatsServiceManager = statsServiceManager;
- }
-
- /** @hide */
- public static StatsServiceManager getStatsServiceManager() {
- return sStatsServiceManager;
- }
-
- /**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers all statsd
- * services to {@link Context}, so that {@link Context#getSystemService} can return them.
- *
- * @throws IllegalStateException if this is called from anywhere besides
- * {@link SystemServiceRegistry}
- */
- public static void registerServiceWrappers() {
- SystemServiceRegistry.registerContextAwareService(
- Context.STATS_MANAGER,
- StatsManager.class,
- context -> new StatsManager(context)
- );
- }
-}
diff --git a/apex/statsd/framework/java/android/util/StatsEvent.java b/apex/statsd/framework/java/android/util/StatsEvent.java
deleted file mode 100644
index 8be5c63f31e3..000000000000
--- a/apex/statsd/framework/java/android/util/StatsEvent.java
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.SystemClock;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
-
-/**
- * StatsEvent builds and stores the buffer sent over the statsd socket.
- * This class defines and encapsulates the socket protocol.
- *
- * <p>Usage:</p>
- * <pre>
- * // Pushed event
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeBoolean(false)
- * .writeString("annotated String field")
- * .addBooleanAnnotation(annotationId, true)
- * .usePooledBuffer()
- * .build();
- * StatsLog.write(statsEvent);
- *
- * // Pulled event
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeBoolean(false)
- * .writeString("annotated String field")
- * .addBooleanAnnotation(annotationId, true)
- * .build();
- * </pre>
- * @hide
- **/
-@SystemApi
-public final class StatsEvent {
- // Type Ids.
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_INT = 0x00;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_LONG = 0x01;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_STRING = 0x02;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_LIST = 0x03;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_FLOAT = 0x04;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_BOOLEAN = 0x05;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_BYTE_ARRAY = 0x06;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_OBJECT = 0x07;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_KEY_VALUE_PAIRS = 0x08;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_ATTRIBUTION_CHAIN = 0x09;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final byte TYPE_ERRORS = 0x0F;
-
- // Error flags.
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_NO_TIMESTAMP = 0x1;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_NO_ATOM_ID = 0x2;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_OVERFLOW = 0x4;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ATTRIBUTION_CHAIN_TOO_LONG = 0x8;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_TOO_MANY_KEY_VALUE_PAIRS = 0x10;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD = 0x20;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_INVALID_ANNOTATION_ID = 0x40;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ANNOTATION_ID_TOO_LARGE = 0x80;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_TOO_MANY_ANNOTATIONS = 0x100;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_TOO_MANY_FIELDS = 0x200;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x1000;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int ERROR_ATOM_ID_INVALID_POSITION = 0x2000;
-
- // Size limits.
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_ANNOTATION_COUNT = 15;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_ATTRIBUTION_NODES = 127;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_NUM_ELEMENTS = 127;
-
- /**
- * @hide
- **/
- @VisibleForTesting
- public static final int MAX_KEY_VALUE_PAIRS = 127;
-
- private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
-
- // Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag.
- // See android_util_StatsLog.cpp.
- private static final int MAX_PUSH_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4;
-
- private static final int MAX_PULL_PAYLOAD_SIZE = 50 * 1024; // 50 KB
-
- private final int mAtomId;
- private final byte[] mPayload;
- private Buffer mBuffer;
- private final int mNumBytes;
-
- private StatsEvent(final int atomId, @Nullable final Buffer buffer,
- @NonNull final byte[] payload, final int numBytes) {
- mAtomId = atomId;
- mBuffer = buffer;
- mPayload = payload;
- mNumBytes = numBytes;
- }
-
- /**
- * Returns a new StatsEvent.Builder for building StatsEvent object.
- **/
- @NonNull
- public static StatsEvent.Builder newBuilder() {
- return new StatsEvent.Builder(Buffer.obtain());
- }
-
- /**
- * Get the atom Id of the atom encoded in this StatsEvent object.
- *
- * @hide
- **/
- public int getAtomId() {
- return mAtomId;
- }
-
- /**
- * Get the byte array that contains the encoded payload that can be sent to statsd.
- *
- * @hide
- **/
- @NonNull
- public byte[] getBytes() {
- return mPayload;
- }
-
- /**
- * Get the number of bytes used to encode the StatsEvent payload.
- *
- * @hide
- **/
- public int getNumBytes() {
- return mNumBytes;
- }
-
- /**
- * Recycle resources used by this StatsEvent object.
- * No actions should be taken on this StatsEvent after release() is called.
- *
- * @hide
- **/
- public void release() {
- if (mBuffer != null) {
- mBuffer.release();
- mBuffer = null;
- }
- }
-
- /**
- * Builder for constructing a StatsEvent object.
- *
- * <p>This class defines and encapsulates the socket encoding for the buffer.
- * The write methods must be called in the same order as the order of fields in the
- * atom definition.</p>
- *
- * <p>setAtomId() can be called anytime before build().</p>
- *
- * <p>Example:</p>
- * <pre>
- * // Atom definition.
- * message MyAtom {
- * optional int32 field1 = 1;
- * optional int64 field2 = 2;
- * optional string field3 = 3 [(annotation1) = true];
- * }
- *
- * // StatsEvent construction for pushed event.
- * StatsEvent.newBuilder()
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeInt(3) // field1
- * .writeLong(8L) // field2
- * .writeString("foo") // field 3
- * .addBooleanAnnotation(annotation1Id, true)
- * .usePooledBuffer()
- * .build();
- *
- * // StatsEvent construction for pulled event.
- * StatsEvent.newBuilder()
- * StatsEvent statsEvent = StatsEvent.newBuilder()
- * .setAtomId(atomId)
- * .writeInt(3) // field1
- * .writeLong(8L) // field2
- * .writeString("foo") // field 3
- * .addBooleanAnnotation(annotation1Id, true)
- * .build();
- * </pre>
- **/
- public static final class Builder {
- // Fixed positions.
- private static final int POS_NUM_ELEMENTS = 1;
- private static final int POS_TIMESTAMP_NS = POS_NUM_ELEMENTS + Byte.BYTES;
- private static final int POS_ATOM_ID = POS_TIMESTAMP_NS + Byte.BYTES + Long.BYTES;
-
- private final Buffer mBuffer;
- private long mTimestampNs;
- private int mAtomId;
- private byte mCurrentAnnotationCount;
- private int mPos;
- private int mPosLastField;
- private byte mLastType;
- private int mNumElements;
- private int mErrorMask;
- private boolean mUsePooledBuffer = false;
-
- private Builder(final Buffer buffer) {
- mBuffer = buffer;
- mCurrentAnnotationCount = 0;
- mAtomId = 0;
- mTimestampNs = SystemClock.elapsedRealtimeNanos();
- mNumElements = 0;
-
- // Set mPos to 0 for writing TYPE_OBJECT at 0th position.
- mPos = 0;
- writeTypeId(TYPE_OBJECT);
-
- // Write timestamp.
- mPos = POS_TIMESTAMP_NS;
- writeLong(mTimestampNs);
- }
-
- /**
- * Sets the atom id for this StatsEvent.
- *
- * This should be called immediately after StatsEvent.newBuilder()
- * and should only be called once.
- * Not calling setAtomId will result in ERROR_NO_ATOM_ID.
- * Calling setAtomId out of order will result in ERROR_ATOM_ID_INVALID_POSITION.
- **/
- @NonNull
- public Builder setAtomId(final int atomId) {
- if (0 == mAtomId) {
- mAtomId = atomId;
-
- if (1 == mNumElements) { // Only timestamp is written so far.
- writeInt(atomId);
- } else {
- // setAtomId called out of order.
- mErrorMask |= ERROR_ATOM_ID_INVALID_POSITION;
- }
- }
-
- return this;
- }
-
- /**
- * Write a boolean field to this StatsEvent.
- **/
- @NonNull
- public Builder writeBoolean(final boolean value) {
- // Write boolean typeId byte followed by boolean byte representation.
- writeTypeId(TYPE_BOOLEAN);
- mPos += mBuffer.putBoolean(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write an integer field to this StatsEvent.
- **/
- @NonNull
- public Builder writeInt(final int value) {
- // Write integer typeId byte followed by 4-byte representation of value.
- writeTypeId(TYPE_INT);
- mPos += mBuffer.putInt(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write a long field to this StatsEvent.
- **/
- @NonNull
- public Builder writeLong(final long value) {
- // Write long typeId byte followed by 8-byte representation of value.
- writeTypeId(TYPE_LONG);
- mPos += mBuffer.putLong(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write a float field to this StatsEvent.
- **/
- @NonNull
- public Builder writeFloat(final float value) {
- // Write float typeId byte followed by 4-byte representation of value.
- writeTypeId(TYPE_FLOAT);
- mPos += mBuffer.putFloat(mPos, value);
- mNumElements++;
- return this;
- }
-
- /**
- * Write a String field to this StatsEvent.
- **/
- @NonNull
- public Builder writeString(@NonNull final String value) {
- // Write String typeId byte, followed by 4-byte representation of number of bytes
- // in the UTF-8 encoding, followed by the actual UTF-8 byte encoding of value.
- final byte[] valueBytes = stringToBytes(value);
- writeByteArray(valueBytes, TYPE_STRING);
- return this;
- }
-
- /**
- * Write a byte array field to this StatsEvent.
- **/
- @NonNull
- public Builder writeByteArray(@NonNull final byte[] value) {
- // Write byte array typeId byte, followed by 4-byte representation of number of bytes
- // in value, followed by the actual byte array.
- writeByteArray(value, TYPE_BYTE_ARRAY);
- return this;
- }
-
- private void writeByteArray(@NonNull final byte[] value, final byte typeId) {
- writeTypeId(typeId);
- final int numBytes = value.length;
- mPos += mBuffer.putInt(mPos, numBytes);
- mPos += mBuffer.putByteArray(mPos, value);
- mNumElements++;
- }
-
- /**
- * Write an attribution chain field to this StatsEvent.
- *
- * The sizes of uids and tags must be equal. The AttributionNode at position i is
- * made up of uids[i] and tags[i].
- *
- * @param uids array of uids in the attribution nodes.
- * @param tags array of tags in the attribution nodes.
- **/
- @NonNull
- public Builder writeAttributionChain(
- @NonNull final int[] uids, @NonNull final String[] tags) {
- final byte numUids = (byte) uids.length;
- final byte numTags = (byte) tags.length;
-
- if (numUids != numTags) {
- mErrorMask |= ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL;
- } else if (numUids > MAX_ATTRIBUTION_NODES) {
- mErrorMask |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
- } else {
- // Write attribution chain typeId byte, followed by 1-byte representation of
- // number of attribution nodes, followed by encoding of each attribution node.
- writeTypeId(TYPE_ATTRIBUTION_CHAIN);
- mPos += mBuffer.putByte(mPos, numUids);
- for (int i = 0; i < numUids; i++) {
- // Each uid is encoded as 4-byte representation of its int value.
- mPos += mBuffer.putInt(mPos, uids[i]);
-
- // Each tag is encoded as 4-byte representation of number of bytes in its
- // UTF-8 encoding, followed by the actual UTF-8 bytes.
- final byte[] tagBytes = stringToBytes(tags[i]);
- mPos += mBuffer.putInt(mPos, tagBytes.length);
- mPos += mBuffer.putByteArray(mPos, tagBytes);
- }
- mNumElements++;
- }
- return this;
- }
-
- /**
- * Write KeyValuePairsAtom entries to this StatsEvent.
- *
- * @param intMap Integer key-value pairs.
- * @param longMap Long key-value pairs.
- * @param stringMap String key-value pairs.
- * @param floatMap Float key-value pairs.
- **/
- @NonNull
- public Builder writeKeyValuePairs(
- @Nullable final SparseIntArray intMap,
- @Nullable final SparseLongArray longMap,
- @Nullable final SparseArray<String> stringMap,
- @Nullable final SparseArray<Float> floatMap) {
- final int intMapSize = null == intMap ? 0 : intMap.size();
- final int longMapSize = null == longMap ? 0 : longMap.size();
- final int stringMapSize = null == stringMap ? 0 : stringMap.size();
- final int floatMapSize = null == floatMap ? 0 : floatMap.size();
- final int totalCount = intMapSize + longMapSize + stringMapSize + floatMapSize;
-
- if (totalCount > MAX_KEY_VALUE_PAIRS) {
- mErrorMask |= ERROR_TOO_MANY_KEY_VALUE_PAIRS;
- } else {
- writeTypeId(TYPE_KEY_VALUE_PAIRS);
- mPos += mBuffer.putByte(mPos, (byte) totalCount);
-
- for (int i = 0; i < intMapSize; i++) {
- final int key = intMap.keyAt(i);
- final int value = intMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_INT);
- mPos += mBuffer.putInt(mPos, value);
- }
-
- for (int i = 0; i < longMapSize; i++) {
- final int key = longMap.keyAt(i);
- final long value = longMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_LONG);
- mPos += mBuffer.putLong(mPos, value);
- }
-
- for (int i = 0; i < stringMapSize; i++) {
- final int key = stringMap.keyAt(i);
- final String value = stringMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_STRING);
- final byte[] valueBytes = stringToBytes(value);
- mPos += mBuffer.putInt(mPos, valueBytes.length);
- mPos += mBuffer.putByteArray(mPos, valueBytes);
- }
-
- for (int i = 0; i < floatMapSize; i++) {
- final int key = floatMap.keyAt(i);
- final float value = floatMap.valueAt(i);
- mPos += mBuffer.putInt(mPos, key);
- writeTypeId(TYPE_FLOAT);
- mPos += mBuffer.putFloat(mPos, value);
- }
-
- mNumElements++;
- }
-
- return this;
- }
-
- /**
- * Write a boolean annotation for the last field written.
- **/
- @NonNull
- public Builder addBooleanAnnotation(
- final byte annotationId, final boolean value) {
- // Ensure there's a field written to annotate.
- if (mNumElements < 2) {
- mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
- } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
- mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
- } else {
- mPos += mBuffer.putByte(mPos, annotationId);
- mPos += mBuffer.putByte(mPos, TYPE_BOOLEAN);
- mPos += mBuffer.putBoolean(mPos, value);
- mCurrentAnnotationCount++;
- writeAnnotationCount();
- }
-
- return this;
- }
-
- /**
- * Write an integer annotation for the last field written.
- **/
- @NonNull
- public Builder addIntAnnotation(final byte annotationId, final int value) {
- if (mNumElements < 2) {
- mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
- } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
- mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
- } else {
- mPos += mBuffer.putByte(mPos, annotationId);
- mPos += mBuffer.putByte(mPos, TYPE_INT);
- mPos += mBuffer.putInt(mPos, value);
- mCurrentAnnotationCount++;
- writeAnnotationCount();
- }
-
- return this;
- }
-
- /**
- * Indicates to reuse Buffer's byte array as the underlying payload in StatsEvent.
- * This should be called for pushed events to reduce memory allocations and garbage
- * collections.
- **/
- @NonNull
- public Builder usePooledBuffer() {
- mUsePooledBuffer = true;
- mBuffer.setMaxSize(MAX_PUSH_PAYLOAD_SIZE, mPos);
- return this;
- }
-
- /**
- * Builds a StatsEvent object with values entered in this Builder.
- **/
- @NonNull
- public StatsEvent build() {
- if (0L == mTimestampNs) {
- mErrorMask |= ERROR_NO_TIMESTAMP;
- }
- if (0 == mAtomId) {
- mErrorMask |= ERROR_NO_ATOM_ID;
- }
- if (mBuffer.hasOverflowed()) {
- mErrorMask |= ERROR_OVERFLOW;
- }
- if (mNumElements > MAX_NUM_ELEMENTS) {
- mErrorMask |= ERROR_TOO_MANY_FIELDS;
- }
-
- if (0 == mErrorMask) {
- mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements);
- } else {
- // Write atom id and error mask. Overwrite any annotations for atom Id.
- mPos = POS_ATOM_ID;
- mPos += mBuffer.putByte(mPos, TYPE_INT);
- mPos += mBuffer.putInt(mPos, mAtomId);
- mPos += mBuffer.putByte(mPos, TYPE_ERRORS);
- mPos += mBuffer.putInt(mPos, mErrorMask);
- mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
- }
-
- final int size = mPos;
-
- if (mUsePooledBuffer) {
- return new StatsEvent(mAtomId, mBuffer, mBuffer.getBytes(), size);
- } else {
- // Create a copy of the buffer with the required number of bytes.
- final byte[] payload = new byte[size];
- System.arraycopy(mBuffer.getBytes(), 0, payload, 0, size);
-
- // Return Buffer instance to the pool.
- mBuffer.release();
-
- return new StatsEvent(mAtomId, null, payload, size);
- }
- }
-
- private void writeTypeId(final byte typeId) {
- mPosLastField = mPos;
- mLastType = typeId;
- mCurrentAnnotationCount = 0;
- final byte encodedId = (byte) (typeId & 0x0F);
- mPos += mBuffer.putByte(mPos, encodedId);
- }
-
- private void writeAnnotationCount() {
- // Use first 4 bits for annotation count and last 4 bits for typeId.
- final byte encodedId = (byte) ((mCurrentAnnotationCount << 4) | (mLastType & 0x0F));
- mBuffer.putByte(mPosLastField, encodedId);
- }
-
- @NonNull
- private static byte[] stringToBytes(@Nullable final String value) {
- return (null == value ? "" : value).getBytes(UTF_8);
- }
- }
-
- private static final class Buffer {
- private static Object sLock = new Object();
-
- @GuardedBy("sLock")
- private static Buffer sPool;
-
- private byte[] mBytes = new byte[MAX_PUSH_PAYLOAD_SIZE];
- private boolean mOverflow = false;
- private int mMaxSize = MAX_PULL_PAYLOAD_SIZE;
-
- @NonNull
- private static Buffer obtain() {
- final Buffer buffer;
- synchronized (sLock) {
- buffer = null == sPool ? new Buffer() : sPool;
- sPool = null;
- }
- buffer.reset();
- return buffer;
- }
-
- private Buffer() {
- }
-
- @NonNull
- private byte[] getBytes() {
- return mBytes;
- }
-
- private void release() {
- // Recycle this Buffer if its size is MAX_PUSH_PAYLOAD_SIZE or under.
- if (mBytes.length <= MAX_PUSH_PAYLOAD_SIZE) {
- synchronized (sLock) {
- if (null == sPool) {
- sPool = this;
- }
- }
- }
- }
-
- private void reset() {
- mOverflow = false;
- mMaxSize = MAX_PULL_PAYLOAD_SIZE;
- }
-
- private void setMaxSize(final int maxSize, final int numBytesWritten) {
- mMaxSize = maxSize;
- if (numBytesWritten > maxSize) {
- mOverflow = true;
- }
- }
-
- private boolean hasOverflowed() {
- return mOverflow;
- }
-
- /**
- * Checks for available space in the byte array.
- *
- * @param index starting position in the buffer to start the check.
- * @param numBytes number of bytes to check from index.
- * @return true if space is available, false otherwise.
- **/
- private boolean hasEnoughSpace(final int index, final int numBytes) {
- final int totalBytesNeeded = index + numBytes;
-
- if (totalBytesNeeded > mMaxSize) {
- mOverflow = true;
- return false;
- }
-
- // Expand buffer if needed.
- if (mBytes.length < mMaxSize && totalBytesNeeded > mBytes.length) {
- int newSize = mBytes.length;
- do {
- newSize *= 2;
- } while (newSize <= totalBytesNeeded);
-
- if (newSize > mMaxSize) {
- newSize = mMaxSize;
- }
-
- mBytes = Arrays.copyOf(mBytes, newSize);
- }
-
- return true;
- }
-
- /**
- * Writes a byte into the buffer.
- *
- * @param index position in the buffer where the byte is written.
- * @param value the byte to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putByte(final int index, final byte value) {
- if (hasEnoughSpace(index, Byte.BYTES)) {
- mBytes[index] = (byte) (value);
- return Byte.BYTES;
- }
- return 0;
- }
-
- /**
- * Writes a boolean into the buffer.
- *
- * @param index position in the buffer where the boolean is written.
- * @param value the boolean to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putBoolean(final int index, final boolean value) {
- return putByte(index, (byte) (value ? 1 : 0));
- }
-
- /**
- * Writes an integer into the buffer.
- *
- * @param index position in the buffer where the integer is written.
- * @param value the integer to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putInt(final int index, final int value) {
- if (hasEnoughSpace(index, Integer.BYTES)) {
- // Use little endian byte order.
- mBytes[index] = (byte) (value);
- mBytes[index + 1] = (byte) (value >> 8);
- mBytes[index + 2] = (byte) (value >> 16);
- mBytes[index + 3] = (byte) (value >> 24);
- return Integer.BYTES;
- }
- return 0;
- }
-
- /**
- * Writes a long into the buffer.
- *
- * @param index position in the buffer where the long is written.
- * @param value the long to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putLong(final int index, final long value) {
- if (hasEnoughSpace(index, Long.BYTES)) {
- // Use little endian byte order.
- mBytes[index] = (byte) (value);
- mBytes[index + 1] = (byte) (value >> 8);
- mBytes[index + 2] = (byte) (value >> 16);
- mBytes[index + 3] = (byte) (value >> 24);
- mBytes[index + 4] = (byte) (value >> 32);
- mBytes[index + 5] = (byte) (value >> 40);
- mBytes[index + 6] = (byte) (value >> 48);
- mBytes[index + 7] = (byte) (value >> 56);
- return Long.BYTES;
- }
- return 0;
- }
-
- /**
- * Writes a float into the buffer.
- *
- * @param index position in the buffer where the float is written.
- * @param value the float to write.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putFloat(final int index, final float value) {
- return putInt(index, Float.floatToIntBits(value));
- }
-
- /**
- * Copies a byte array into the buffer.
- *
- * @param index position in the buffer where the byte array is copied.
- * @param value the byte array to copy.
- * @return number of bytes written to buffer from this write operation.
- **/
- private int putByteArray(final int index, @NonNull final byte[] value) {
- final int numBytes = value.length;
- if (hasEnoughSpace(index, numBytes)) {
- System.arraycopy(value, 0, mBytes, index, numBytes);
- return numBytes;
- }
- return 0;
- }
- }
-}
diff --git a/apex/statsd/framework/java/android/util/StatsLog.java b/apex/statsd/framework/java/android/util/StatsLog.java
deleted file mode 100644
index 0a9f4ebabdf0..000000000000
--- a/apex/statsd/framework/java/android/util/StatsLog.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.IStatsd;
-import android.os.Process;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.statsd.StatsdStatsLog;
-
-/**
- * StatsLog provides an API for developers to send events to statsd. The events can be used to
- * define custom metrics inside statsd.
- */
-public final class StatsLog {
-
- // Load JNI library
- static {
- System.loadLibrary("stats_jni");
- }
- private static final String TAG = "StatsLog";
- private static final boolean DEBUG = false;
- private static final int EXPERIMENT_IDS_FIELD_ID = 1;
-
- private StatsLog() {
- }
-
- /**
- * Logs a start event.
- *
- * @param label developer-chosen label.
- * @return True if the log request was sent to statsd.
- */
- public static boolean logStart(int label) {
- int callingUid = Process.myUid();
- StatsdStatsLog.write(
- StatsdStatsLog.APP_BREADCRUMB_REPORTED,
- callingUid,
- label,
- StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
- return true;
- }
-
- /**
- * Logs a stop event.
- *
- * @param label developer-chosen label.
- * @return True if the log request was sent to statsd.
- */
- public static boolean logStop(int label) {
- int callingUid = Process.myUid();
- StatsdStatsLog.write(
- StatsdStatsLog.APP_BREADCRUMB_REPORTED,
- callingUid,
- label,
- StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
- return true;
- }
-
- /**
- * Logs an event that does not represent a start or stop boundary.
- *
- * @param label developer-chosen label.
- * @return True if the log request was sent to statsd.
- */
- public static boolean logEvent(int label) {
- int callingUid = Process.myUid();
- StatsdStatsLog.write(
- StatsdStatsLog.APP_BREADCRUMB_REPORTED,
- callingUid,
- label,
- StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
- return true;
- }
-
- /**
- * Logs an event for binary push for module updates.
- *
- * @param trainName name of install train.
- * @param trainVersionCode version code of the train.
- * @param options optional flags about this install.
- * The last 3 bits indicate options:
- * 0x01: FLAG_REQUIRE_STAGING
- * 0x02: FLAG_ROLLBACK_ENABLED
- * 0x04: FLAG_REQUIRE_LOW_LATENCY_MONITOR
- * @param state current install state. Defined as State enums in
- * BinaryPushStateChanged atom in
- * frameworks/base/cmds/statsd/src/atoms.proto
- * @param experimentIds experiment ids.
- * @return True if the log request was sent to statsd.
- */
- @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
- public static boolean logBinaryPushStateChanged(@NonNull String trainName,
- long trainVersionCode, int options, int state,
- @NonNull long[] experimentIds) {
- ProtoOutputStream proto = new ProtoOutputStream();
- for (long id : experimentIds) {
- proto.write(
- ProtoOutputStream.FIELD_TYPE_INT64
- | ProtoOutputStream.FIELD_COUNT_REPEATED
- | EXPERIMENT_IDS_FIELD_ID,
- id);
- }
- StatsdStatsLog.write(StatsdStatsLog.BINARY_PUSH_STATE_CHANGED,
- trainName,
- trainVersionCode,
- (options & IStatsd.FLAG_REQUIRE_STAGING) > 0,
- (options & IStatsd.FLAG_ROLLBACK_ENABLED) > 0,
- (options & IStatsd.FLAG_REQUIRE_LOW_LATENCY_MONITOR) > 0,
- state,
- proto.getBytes(),
- 0,
- 0,
- false);
- return true;
- }
-
- /**
- * Write an event to stats log using the raw format.
- *
- * @param buffer The encoded buffer of data to write.
- * @param size The number of bytes from the buffer to write.
- * @hide
- */
- // TODO(b/144935988): Mark deprecated.
- @SystemApi
- public static void writeRaw(@NonNull byte[] buffer, int size) {
- // TODO(b/144935988): make this no-op once clients have migrated to StatsEvent.
- writeImpl(buffer, size, 0);
- }
-
- /**
- * Write an event to stats log using the raw format.
- *
- * @param buffer The encoded buffer of data to write.
- * @param size The number of bytes from the buffer to write.
- * @param atomId The id of the atom to which the event belongs.
- */
- private static native void writeImpl(@NonNull byte[] buffer, int size, int atomId);
-
- /**
- * Write an event to stats log using the raw format encapsulated in StatsEvent.
- * After writing to stats log, release() is called on the StatsEvent object.
- * No further action should be taken on the StatsEvent object following this call.
- *
- * @param statsEvent The StatsEvent object containing the encoded buffer of data to write.
- * @hide
- */
- @SystemApi
- public static void write(@NonNull final StatsEvent statsEvent) {
- writeImpl(statsEvent.getBytes(), statsEvent.getNumBytes(), statsEvent.getAtomId());
- statsEvent.release();
- }
-
- private static void enforceDumpCallingPermission(Context context) {
- context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission.");
- }
-
- private static void enforcesageStatsCallingPermission(Context context) {
- context.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS,
- "Need PACKAGE_USAGE_STATS permission.");
- }
-}
diff --git a/apex/statsd/framework/test/Android.bp b/apex/statsd/framework/test/Android.bp
deleted file mode 100644
index b113d595b57c..000000000000
--- a/apex/statsd/framework/test/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
- name: "FrameworkStatsdTest",
- platform_apis: true,
- srcs: [
- // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
- ":framework-statsd-sources",
- "**/*.java",
- ],
- manifest: "AndroidManifest.xml",
- static_libs: [
- "androidx.test.rules",
- "truth-prebuilt",
- ],
- libs: [
- "android.test.runner.stubs",
- "android.test.base.stubs",
- ],
- test_suites: [
- "device-tests",
- "mts",
- ],
-} \ No newline at end of file
diff --git a/apex/statsd/framework/test/AndroidManifest.xml b/apex/statsd/framework/test/AndroidManifest.xml
deleted file mode 100644
index 8f89d2332b12..000000000000
--- a/apex/statsd/framework/test/AndroidManifest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.os.statsd.framework.test"
- >
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.os.statsd.framework.test"
- android:label="Framework Statsd Tests" />
-
-</manifest>
diff --git a/apex/statsd/framework/test/AndroidTest.xml b/apex/statsd/framework/test/AndroidTest.xml
deleted file mode 100644
index fb519150ecd5..000000000000
--- a/apex/statsd/framework/test/AndroidTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Runs Tests for Statsd.">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
- <option name="test-file-name" value="FrameworkStatsdTest.apk" />
- <option name="install-arg" value="-g" />
- </target_preparer>
-
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="mts" />
- <option name="test-tag" value="FrameworkStatsdTest" />
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.android.os.statsd.framework.test" />
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- <option name="hidden-api-checks" value="false"/>
- </test>
-
- <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
- <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
- </object>
-</configuration> \ No newline at end of file
diff --git a/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java b/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
deleted file mode 100644
index fd386bd8e32e..000000000000
--- a/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager.PullAtomMetadata;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class PullAtomMetadataTest {
-
- @Test
- public void testEmpty() {
- PullAtomMetadata metadata = new PullAtomMetadata.Builder().build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
- assertThat(metadata.getAdditiveFields()).isNull();
- }
-
- @Test
- public void testSetTimeoutMillis() {
- long timeoutMillis = 500L;
- PullAtomMetadata metadata =
- new PullAtomMetadata.Builder().setTimeoutMillis(timeoutMillis).build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(timeoutMillis);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
- assertThat(metadata.getAdditiveFields()).isNull();
- }
-
- @Test
- public void testSetCoolDownMillis() {
- long coolDownMillis = 10_000L;
- PullAtomMetadata metadata =
- new PullAtomMetadata.Builder().setCoolDownMillis(coolDownMillis).build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(coolDownMillis);
- assertThat(metadata.getAdditiveFields()).isNull();
- }
-
- @Test
- public void testSetAdditiveFields() {
- int[] fields = {2, 4, 6};
- PullAtomMetadata metadata =
- new PullAtomMetadata.Builder().setAdditiveFields(fields).build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
- assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
- }
-
- @Test
- public void testSetAllElements() {
- long timeoutMillis = 300L;
- long coolDownMillis = 9572L;
- int[] fields = {3, 2};
- PullAtomMetadata metadata = new PullAtomMetadata.Builder()
- .setTimeoutMillis(timeoutMillis)
- .setCoolDownMillis(coolDownMillis)
- .setAdditiveFields(fields)
- .build();
- assertThat(metadata.getTimeoutMillis()).isEqualTo(timeoutMillis);
- assertThat(metadata.getCoolDownMillis()).isEqualTo(coolDownMillis);
- assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
- }
-}
diff --git a/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java b/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java
deleted file mode 100644
index db25911e6eee..000000000000
--- a/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public final class StatsDimensionsValueTest {
-
- @Test
- public void testConversionFromStructuredParcel() {
- int tupleField = 100; // atom id
- String stringValue = "Hello";
- int intValue = 123;
- long longValue = 123456789L;
- float floatValue = 1.1f;
- boolean boolValue = true;
-
- // Construct structured parcel
- StatsDimensionsValueParcel sdvp = new StatsDimensionsValueParcel();
- sdvp.field = tupleField;
- sdvp.valueType = StatsDimensionsValue.TUPLE_VALUE_TYPE;
- sdvp.tupleValue = new StatsDimensionsValueParcel[5];
-
- for (int i = 0; i < 5; i++) {
- sdvp.tupleValue[i] = new StatsDimensionsValueParcel();
- sdvp.tupleValue[i].field = i + 1;
- }
-
- sdvp.tupleValue[0].valueType = StatsDimensionsValue.STRING_VALUE_TYPE;
- sdvp.tupleValue[1].valueType = StatsDimensionsValue.INT_VALUE_TYPE;
- sdvp.tupleValue[2].valueType = StatsDimensionsValue.LONG_VALUE_TYPE;
- sdvp.tupleValue[3].valueType = StatsDimensionsValue.FLOAT_VALUE_TYPE;
- sdvp.tupleValue[4].valueType = StatsDimensionsValue.BOOLEAN_VALUE_TYPE;
-
- sdvp.tupleValue[0].stringValue = stringValue;
- sdvp.tupleValue[1].intValue = intValue;
- sdvp.tupleValue[2].longValue = longValue;
- sdvp.tupleValue[3].floatValue = floatValue;
- sdvp.tupleValue[4].boolValue = boolValue;
-
- // Convert to StatsDimensionsValue and check result
- StatsDimensionsValue sdv = new StatsDimensionsValue(sdvp);
-
- assertThat(sdv.getField()).isEqualTo(tupleField);
- assertThat(sdv.getValueType()).isEqualTo(StatsDimensionsValue.TUPLE_VALUE_TYPE);
- List<StatsDimensionsValue> sdvChildren = sdv.getTupleValueList();
- assertThat(sdvChildren.size()).isEqualTo(5);
-
- for (int i = 0; i < 5; i++) {
- assertThat(sdvChildren.get(i).getField()).isEqualTo(i + 1);
- }
-
- assertThat(sdvChildren.get(0).getValueType())
- .isEqualTo(StatsDimensionsValue.STRING_VALUE_TYPE);
- assertThat(sdvChildren.get(1).getValueType())
- .isEqualTo(StatsDimensionsValue.INT_VALUE_TYPE);
- assertThat(sdvChildren.get(2).getValueType())
- .isEqualTo(StatsDimensionsValue.LONG_VALUE_TYPE);
- assertThat(sdvChildren.get(3).getValueType())
- .isEqualTo(StatsDimensionsValue.FLOAT_VALUE_TYPE);
- assertThat(sdvChildren.get(4).getValueType())
- .isEqualTo(StatsDimensionsValue.BOOLEAN_VALUE_TYPE);
-
- assertThat(sdvChildren.get(0).getStringValue()).isEqualTo(stringValue);
- assertThat(sdvChildren.get(1).getIntValue()).isEqualTo(intValue);
- assertThat(sdvChildren.get(2).getLongValue()).isEqualTo(longValue);
- assertThat(sdvChildren.get(3).getFloatValue()).isEqualTo(floatValue);
- assertThat(sdvChildren.get(4).getBooleanValue()).isEqualTo(boolValue);
-
- // Ensure that StatsDimensionsValue and StatsDimensionsValueParcel are
- // parceled equivalently
- Parcel sdvpParcel = Parcel.obtain();
- Parcel sdvParcel = Parcel.obtain();
- sdvp.writeToParcel(sdvpParcel, 0);
- sdv.writeToParcel(sdvParcel, 0);
- assertThat(sdvpParcel.dataSize()).isEqualTo(sdvParcel.dataSize());
- }
-
- @Test
- public void testNullTupleArray() {
- int tupleField = 100; // atom id
-
- StatsDimensionsValueParcel parcel = new StatsDimensionsValueParcel();
- parcel.field = tupleField;
- parcel.valueType = StatsDimensionsValue.TUPLE_VALUE_TYPE;
- parcel.tupleValue = null;
-
- StatsDimensionsValue sdv = new StatsDimensionsValue(parcel);
- assertThat(sdv.getField()).isEqualTo(tupleField);
- assertThat(sdv.getValueType()).isEqualTo(StatsDimensionsValue.TUPLE_VALUE_TYPE);
- List<StatsDimensionsValue> sdvChildren = sdv.getTupleValueList();
- assertThat(sdvChildren.size()).isEqualTo(0);
- }
-}
diff --git a/apex/statsd/framework/test/src/android/util/StatsEventTest.java b/apex/statsd/framework/test/src/android/util/StatsEventTest.java
deleted file mode 100644
index 8d263699d9c8..000000000000
--- a/apex/statsd/framework/test/src/android/util/StatsEventTest.java
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.os.SystemClock;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.common.collect.Range;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Random;
-
-/**
- * Internal tests for {@link StatsEvent}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StatsEventTest {
-
- @Test
- public void testNoFields() {
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder().usePooledBuffer().build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- final int expectedAtomId = 0;
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_NO_ATOM_ID should be the only error in the error mask")
- .that(errorMask).isEqualTo(StatsEvent.ERROR_NO_ATOM_ID);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testOnlyAtomId() {
- final int expectedAtomId = 109;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(2);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testIntBooleanIntInt() {
- final int expectedAtomId = 109;
- final int field1 = 1;
- final boolean field2 = true;
- final int field3 = 3;
- final int field4 = 4;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeInt(field1)
- .writeBoolean(field2)
- .writeInt(field3)
- .writeInt(field4)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(6);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not Int")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect field 1")
- .that(buffer.getInt()).isEqualTo(field1);
-
- assertWithMessage("Second field is not Boolean")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-
- assertWithMessage("Incorrect field 2")
- .that(buffer.get()).isEqualTo(1);
-
- assertWithMessage("Third field is not Int")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect field 3")
- .that(buffer.getInt()).isEqualTo(field3);
-
- assertWithMessage("Fourth field is not Int")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect field 4")
- .that(buffer.getInt()).isEqualTo(field4);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testStringFloatByteArray() {
- final int expectedAtomId = 109;
- final String field1 = "Str 1";
- final float field2 = 9.334f;
- final byte[] field3 = new byte[] { 56, 23, 89, -120 };
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeString(field1)
- .writeFloat(field2)
- .writeByteArray(field3)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(5);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not String")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING);
-
- final String field1Actual = getStringFromByteBuffer(buffer);
- assertWithMessage("Incorrect field 1")
- .that(field1Actual).isEqualTo(field1);
-
- assertWithMessage("Second field is not Float")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT);
-
- assertWithMessage("Incorrect field 2")
- .that(buffer.getFloat()).isEqualTo(field2);
-
- assertWithMessage("Third field is not byte array")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BYTE_ARRAY);
-
- final byte[] field3Actual = getByteArrayFromByteBuffer(buffer);
- assertWithMessage("Incorrect field 3")
- .that(field3Actual).isEqualTo(field3);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testAttributionChainLong() {
- final int expectedAtomId = 109;
- final int[] uids = new int[] { 1, 2, 3, 4, 5 };
- final String[] tags = new String[] { "1", "2", "3", "4", "5" };
- final long field2 = -230909823L;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeAttributionChain(uids, tags)
- .writeLong(field2)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(4);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not Attribution Chain")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ATTRIBUTION_CHAIN);
-
- assertWithMessage("Incorrect number of attribution nodes")
- .that(buffer.get()).isEqualTo((byte) uids.length);
-
- for (int i = 0; i < tags.length; i++) {
- assertWithMessage("Incorrect uid in Attribution Chain")
- .that(buffer.getInt()).isEqualTo(uids[i]);
-
- final String tag = getStringFromByteBuffer(buffer);
- assertWithMessage("Incorrect tag in Attribution Chain")
- .that(tag).isEqualTo(tags[i]);
- }
-
- assertWithMessage("Second field is not Long")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect field 2")
- .that(buffer.getLong()).isEqualTo(field2);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testKeyValuePairs() {
- final int expectedAtomId = 109;
- final SparseIntArray intMap = new SparseIntArray();
- final SparseLongArray longMap = new SparseLongArray();
- final SparseArray<String> stringMap = new SparseArray<>();
- final SparseArray<Float> floatMap = new SparseArray<>();
- intMap.put(1, -1);
- intMap.put(2, -2);
- stringMap.put(3, "abc");
- stringMap.put(4, "2h");
- floatMap.put(9, -234.344f);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeKeyValuePairs(intMap, longMap, stringMap, floatMap)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("First field is not KeyValuePairs")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_KEY_VALUE_PAIRS);
-
- assertWithMessage("Incorrect number of key value pairs")
- .that(buffer.get()).isEqualTo(
- (byte) (intMap.size() + longMap.size() + stringMap.size()
- + floatMap.size()));
-
- for (int i = 0; i < intMap.size(); i++) {
- assertWithMessage("Incorrect key in intMap")
- .that(buffer.getInt()).isEqualTo(intMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_INT in intMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Incorrect value in intMap")
- .that(buffer.getInt()).isEqualTo(intMap.valueAt(i));
- }
-
- for (int i = 0; i < longMap.size(); i++) {
- assertWithMessage("Incorrect key in longMap")
- .that(buffer.getInt()).isEqualTo(longMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_LONG in longMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
- assertWithMessage("Incorrect value in longMap")
- .that(buffer.getLong()).isEqualTo(longMap.valueAt(i));
- }
-
- for (int i = 0; i < stringMap.size(); i++) {
- assertWithMessage("Incorrect key in stringMap")
- .that(buffer.getInt()).isEqualTo(stringMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_STRING in stringMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING);
- final String value = getStringFromByteBuffer(buffer);
- assertWithMessage("Incorrect value in stringMap")
- .that(value).isEqualTo(stringMap.valueAt(i));
- }
-
- for (int i = 0; i < floatMap.size(); i++) {
- assertWithMessage("Incorrect key in floatMap")
- .that(buffer.getInt()).isEqualTo(floatMap.keyAt(i));
- assertWithMessage("The type id of the value should be TYPE_FLOAT in floatMap")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT);
- assertWithMessage("Incorrect value in floatMap")
- .that(buffer.getFloat()).isEqualTo(floatMap.valueAt(i));
- }
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testSingleAnnotations() {
- final int expectedAtomId = 109;
- final int field1 = 1;
- final byte field1AnnotationId = 45;
- final boolean field1AnnotationValue = false;
- final boolean field2 = true;
- final byte field2AnnotationId = 1;
- final int field2AnnotationValue = 23;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeInt(field1)
- .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue)
- .writeBoolean(field2)
- .addIntAnnotation(field2AnnotationId, field2AnnotationValue)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(4);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- final byte field1Header = buffer.get();
- final int field1AnnotationValueCount = field1Header >> 4;
- final byte field1Type = (byte) (field1Header & 0x0F);
- assertWithMessage("First field is not Int")
- .that(field1Type).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("First field annotation count is wrong")
- .that(field1AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 1")
- .that(buffer.getInt()).isEqualTo(field1);
- assertWithMessage("First field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationId);
- assertWithMessage("First field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("First field's annotation value is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0);
-
- final byte field2Header = buffer.get();
- final int field2AnnotationValueCount = field2Header >> 4;
- final byte field2Type = (byte) (field2Header & 0x0F);
- assertWithMessage("Second field is not boolean")
- .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("Second field annotation count is wrong")
- .that(field2AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 2")
- .that(buffer.get()).isEqualTo(field2 ? 1 : 0);
- assertWithMessage("Second field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field2AnnotationId);
- assertWithMessage("Second field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Second field's annotation value is wrong")
- .that(buffer.getInt()).isEqualTo(field2AnnotationValue);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testAtomIdAnnotations() {
- final int expectedAtomId = 109;
- final byte atomAnnotationId = 84;
- final int atomAnnotationValue = 9;
- final int field1 = 1;
- final byte field1AnnotationId = 45;
- final boolean field1AnnotationValue = false;
- final boolean field2 = true;
- final byte field2AnnotationId = 1;
- final int field2AnnotationValue = 23;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .addIntAnnotation(atomAnnotationId, atomAnnotationValue)
- .writeInt(field1)
- .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue)
- .writeBoolean(field2)
- .addIntAnnotation(field2AnnotationId, field2AnnotationValue)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(4);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- final byte atomIdHeader = buffer.get();
- final int atomIdAnnotationValueCount = atomIdHeader >> 4;
- final byte atomIdValueType = (byte) (atomIdHeader & 0x0F);
- assertWithMessage("Second element is not atom id")
- .that(atomIdValueType).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Atom id annotation count is wrong")
- .that(atomIdAnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
- assertWithMessage("Atom id's annotation id is wrong")
- .that(buffer.get()).isEqualTo(atomAnnotationId);
- assertWithMessage("Atom id's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Atom id's annotation value is wrong")
- .that(buffer.getInt()).isEqualTo(atomAnnotationValue);
-
- final byte field1Header = buffer.get();
- final int field1AnnotationValueCount = field1Header >> 4;
- final byte field1Type = (byte) (field1Header & 0x0F);
- assertWithMessage("First field is not Int")
- .that(field1Type).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("First field annotation count is wrong")
- .that(field1AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 1")
- .that(buffer.getInt()).isEqualTo(field1);
- assertWithMessage("First field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationId);
- assertWithMessage("First field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("First field's annotation value is wrong")
- .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0);
-
- final byte field2Header = buffer.get();
- final int field2AnnotationValueCount = field2Header >> 4;
- final byte field2Type = (byte) (field2Header & 0x0F);
- assertWithMessage("Second field is not boolean")
- .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN);
- assertWithMessage("Second field annotation count is wrong")
- .that(field2AnnotationValueCount).isEqualTo(1);
- assertWithMessage("Incorrect field 2")
- .that(buffer.get()).isEqualTo(field2 ? 1 : 0);
- assertWithMessage("Second field's annotation id is wrong")
- .that(buffer.get()).isEqualTo(field2AnnotationId);
- assertWithMessage("Second field's annotation type is wrong")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
- assertWithMessage("Second field's annotation value is wrong")
- .that(buffer.getInt()).isEqualTo(field2AnnotationValue);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testSetAtomIdNotCalledImmediately() {
- final int expectedAtomId = 109;
- final int field1 = 25;
- final boolean field2 = true;
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .writeInt(field1)
- .setAtomId(expectedAtomId)
- .writeBoolean(field2)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get()).isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id")
- .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_ATOM_ID_INVALID_POSITION should be the only error in the mask")
- .that(errorMask).isEqualTo(StatsEvent.ERROR_ATOM_ID_INVALID_POSITION);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testLargePulledEvent() {
- final int expectedAtomId = 10_020;
- byte[] field1 = new byte[10 * 1024];
- new Random().nextBytes(field1);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent =
- StatsEvent.newBuilder().setAtomId(expectedAtomId).writeByteArray(field1).build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get())
- .isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong())
- .isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not byte array")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_BYTE_ARRAY);
-
- final byte[] field1Actual = getByteArrayFromByteBuffer(buffer);
- assertWithMessage("Incorrect field 1").that(field1Actual).isEqualTo(field1);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testPulledEventOverflow() {
- final int expectedAtomId = 10_020;
- byte[] field1 = new byte[50 * 1024];
- new Random().nextBytes(field1);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent =
- StatsEvent.newBuilder().setAtomId(expectedAtomId).writeByteArray(field1).build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get())
- .isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong())
- .isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_OVERFLOW should be the only error in the error mask")
- .that(errorMask)
- .isEqualTo(StatsEvent.ERROR_OVERFLOW);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- @Test
- public void testPushedEventOverflow() {
- final int expectedAtomId = 10_020;
- byte[] field1 = new byte[10 * 1024];
- new Random().nextBytes(field1);
-
- final long minTimestamp = SystemClock.elapsedRealtimeNanos();
- final StatsEvent statsEvent = StatsEvent.newBuilder()
- .setAtomId(expectedAtomId)
- .writeByteArray(field1)
- .usePooledBuffer()
- .build();
- final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
- assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
- final ByteBuffer buffer =
- ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
- assertWithMessage("Root element in buffer is not TYPE_OBJECT")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_OBJECT);
-
- assertWithMessage("Incorrect number of elements in root object")
- .that(buffer.get())
- .isEqualTo(3);
-
- assertWithMessage("First element is not timestamp")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_LONG);
-
- assertWithMessage("Incorrect timestamp")
- .that(buffer.getLong())
- .isIn(Range.closed(minTimestamp, maxTimestamp));
-
- assertWithMessage("Second element is not atom id")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_INT);
-
- assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
- assertWithMessage("Third element is not errors type")
- .that(buffer.get())
- .isEqualTo(StatsEvent.TYPE_ERRORS);
-
- final int errorMask = buffer.getInt();
-
- assertWithMessage("ERROR_OVERFLOW should be the only error in the error mask")
- .that(errorMask)
- .isEqualTo(StatsEvent.ERROR_OVERFLOW);
-
- assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
- statsEvent.release();
- }
-
- private static byte[] getByteArrayFromByteBuffer(final ByteBuffer buffer) {
- final int numBytes = buffer.getInt();
- byte[] bytes = new byte[numBytes];
- buffer.get(bytes);
- return bytes;
- }
-
- private static String getStringFromByteBuffer(final ByteBuffer buffer) {
- final byte[] bytes = getByteArrayFromByteBuffer(buffer);
- return new String(bytes, UTF_8);
- }
-}
diff --git a/apex/statsd/jni/android_util_StatsLog.cpp b/apex/statsd/jni/android_util_StatsLog.cpp
deleted file mode 100644
index 71ce94923c8d..000000000000
--- a/apex/statsd/jni/android_util_StatsLog.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_NAMESPACE "StatsLog.tag."
-#define LOG_TAG "StatsLog_println"
-
-#include <jni.h>
-#include <log/log.h>
-#include <nativehelper/scoped_local_ref.h>
-#include "stats_buffer_writer.h"
-
-namespace android {
-
-static void android_util_StatsLog_write(JNIEnv* env, jobject clazz, jbyteArray buf, jint size,
- jint atomId) {
- if (buf == NULL) {
- return;
- }
- jint actualSize = env->GetArrayLength(buf);
- if (actualSize < size) {
- return;
- }
-
- jbyte* bufferArray = env->GetByteArrayElements(buf, NULL);
- if (bufferArray == NULL) {
- return;
- }
-
- write_buffer_to_statsd((void*) bufferArray, size, atomId);
-
- env->ReleaseByteArrayElements(buf, bufferArray, 0);
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "writeImpl", "([BII)V", (void*) android_util_StatsLog_write },
-};
-
-int register_android_util_StatsLog(JNIEnv* env)
-{
- static const char* kStatsLogClass = "android/util/StatsLog";
-
- ScopedLocalRef<jclass> cls(env, env->FindClass(kStatsLogClass));
- if (cls.get() == nullptr) {
- ALOGE("jni statsd registration failure, class not found '%s'", kStatsLogClass);
- return JNI_ERR;
- }
-
- const jint count = sizeof(gMethods) / sizeof(gMethods[0]);
- int status = env->RegisterNatives(cls.get(), gMethods, count);
- if (status < 0) {
- ALOGE("jni statsd registration failure, status: %d", status);
- return JNI_ERR;
- }
- return JNI_VERSION_1_4;
-}
-
-}; // namespace android
-
-/*
- * JNI Initialization
- */
-jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
- JNIEnv* e;
-
- ALOGV("statsd : loading JNI\n");
- // Check JNI version
- if (jvm->GetEnv((void**)&e, JNI_VERSION_1_4)) {
- ALOGE("JNI version mismatch error");
- return JNI_ERR;
- }
-
- return android::register_android_util_StatsLog(e);
-}
diff --git a/apex/statsd/service/Android.bp b/apex/statsd/service/Android.bp
deleted file mode 100644
index df0ccfc54d64..000000000000
--- a/apex/statsd/service/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-filegroup {
- name: "service-statsd-sources",
- srcs: [
- "java/**/*.java",
- ],
-}
-
-java_library {
- name: "service-statsd",
- srcs: [ ":service-statsd-sources" ],
- sdk_version: "system_server_current",
- libs: [
- "framework-annotations-lib",
- "framework-statsd",
- ],
- plugins: ["java_api_finder"],
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
deleted file mode 100644
index dc477a5590ea..000000000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.stats;
-
-import android.app.PendingIntent;
-import android.app.StatsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.IPendingIntentRef;
-import android.os.Process;
-import android.os.StatsDimensionsValue;
-import android.os.StatsDimensionsValueParcel;
-import android.util.Log;
-
-import com.android.server.SystemService;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * @hide
- */
-public class StatsCompanion {
- private static final String TAG = "StatsCompanion";
- private static final boolean DEBUG = false;
-
- private static final int AID_STATSD = 1066;
-
- private static final String STATS_COMPANION_SERVICE = "statscompanion";
- private static final String STATS_MANAGER_SERVICE = "statsmanager";
-
- static void enforceStatsdCallingUid() {
- if (Binder.getCallingPid() == Process.myPid()) {
- return;
- }
- if (Binder.getCallingUid() != AID_STATSD) {
- throw new SecurityException("Not allowed to access StatsCompanion");
- }
- }
-
- /**
- * Lifecycle class for both {@link StatsCompanionService} and {@link StatsManagerService}.
- */
- public static final class Lifecycle extends SystemService {
- private StatsCompanionService mStatsCompanionService;
- private StatsManagerService mStatsManagerService;
-
- public Lifecycle(Context context) {
- super(context);
- }
-
- @Override
- public void onStart() {
- mStatsCompanionService = new StatsCompanionService(getContext());
- mStatsManagerService = new StatsManagerService(getContext());
- mStatsCompanionService.setStatsManagerService(mStatsManagerService);
- mStatsManagerService.setStatsCompanionService(mStatsCompanionService);
-
- try {
- publishBinderService(STATS_COMPANION_SERVICE, mStatsCompanionService);
- if (DEBUG) Log.d(TAG, "Published " + STATS_COMPANION_SERVICE);
- publishBinderService(STATS_MANAGER_SERVICE, mStatsManagerService);
- if (DEBUG) Log.d(TAG, "Published " + STATS_MANAGER_SERVICE);
- } catch (Exception e) {
- Log.e(TAG, "Failed to publishBinderService", e);
- }
- }
-
- @Override
- public void onBootPhase(int phase) {
- super.onBootPhase(phase);
- if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- mStatsCompanionService.systemReady();
- }
- if (phase == PHASE_BOOT_COMPLETED) {
- mStatsCompanionService.bootCompleted();
- }
- }
- }
-
- /**
- * Wrapper for {@link PendingIntent}. Allows Statsd to send PendingIntents.
- */
- public static class PendingIntentRef extends IPendingIntentRef.Stub {
-
- private static final String TAG = "PendingIntentRef";
-
- /**
- * The last report time is provided with each intent registered to
- * StatsManager#setFetchReportsOperation. This allows easy de-duping in the receiver if
- * statsd is requesting the client to retrieve the same statsd data. The last report time
- * corresponds to the last_report_elapsed_nanos that will provided in the current
- * ConfigMetricsReport, and this timestamp also corresponds to the
- * current_report_elapsed_nanos of the most recently obtained ConfigMetricsReport.
- */
- private static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME";
- private static final int CODE_DATA_BROADCAST = 1;
- private static final int CODE_ACTIVE_CONFIGS_BROADCAST = 1;
- private static final int CODE_SUBSCRIBER_BROADCAST = 1;
-
- private final PendingIntent mPendingIntent;
- private final Context mContext;
-
- public PendingIntentRef(PendingIntent pendingIntent, Context context) {
- mPendingIntent = pendingIntent;
- mContext = context;
- }
-
- @Override
- public void sendDataBroadcast(long lastReportTimeNs) {
- enforceStatsdCallingUid();
- Intent intent = new Intent();
- intent.putExtra(EXTRA_LAST_REPORT_TIME, lastReportTimeNs);
- try {
- mPendingIntent.send(mContext, CODE_DATA_BROADCAST, intent, null, null);
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Unable to send PendingIntent");
- }
- }
-
- @Override
- public void sendActiveConfigsChangedBroadcast(long[] configIds) {
- enforceStatsdCallingUid();
- Intent intent = new Intent();
- intent.putExtra(StatsManager.EXTRA_STATS_ACTIVE_CONFIG_KEYS, configIds);
- try {
- mPendingIntent.send(mContext, CODE_ACTIVE_CONFIGS_BROADCAST, intent, null, null);
- if (DEBUG) {
- Log.d(TAG, "Sent broadcast with config ids " + Arrays.toString(configIds));
- }
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Unable to send active configs changed broadcast using PendingIntent");
- }
- }
-
- @Override
- public void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
- long subscriptionRuleId, String[] cookies,
- StatsDimensionsValueParcel dimensionsValueParcel) {
- enforceStatsdCallingUid();
- StatsDimensionsValue dimensionsValue = new StatsDimensionsValue(dimensionsValueParcel);
- Intent intent =
- new Intent()
- .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
- .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configId)
- .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId)
- .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID,
- subscriptionRuleId)
- .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue);
-
- ArrayList<String> cookieList = new ArrayList<>(cookies.length);
- cookieList.addAll(Arrays.asList(cookies));
- intent.putStringArrayListExtra(
- StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList);
-
- if (DEBUG) {
- Log.d(TAG,
- String.format(
- "Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
- configUid, configId, subscriptionId, subscriptionRuleId,
- Arrays.toString(cookies),
- dimensionsValue));
- }
- try {
- mPendingIntent.send(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null);
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG,
- "Unable to send using PendingIntent from uid " + configUid
- + "; presumably it had been cancelled.");
- }
- }
- }
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
deleted file mode 100644
index b5e72247a4a3..000000000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.stats;
-
-import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.OnAlarmListener;
-import android.app.StatsManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.IStatsCompanionService;
-import android.os.IStatsd;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.StatsFrameworkInitializer;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Helper service for statsd (the native stats management service in cmds/statsd/).
- * Used for registering and receiving alarms on behalf of statsd.
- *
- * @hide
- */
-public class StatsCompanionService extends IStatsCompanionService.Stub {
-
- private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
-
- public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
- public static final String CONFIG_DIR = "/data/misc/stats-service";
-
- static final String TAG = "StatsCompanionService";
- static final boolean DEBUG = false;
- /**
- * Hard coded field ids of frameworks/base/cmds/statsd/src/uid_data.proto
- * to be used in ProtoOutputStream.
- */
- private static final int APPLICATION_INFO_FIELD_ID = 1;
- private static final int UID_FIELD_ID = 1;
- private static final int VERSION_FIELD_ID = 2;
- private static final int VERSION_STRING_FIELD_ID = 3;
- private static final int PACKAGE_NAME_FIELD_ID = 4;
- private static final int INSTALLER_FIELD_ID = 5;
-
- public static final int DEATH_THRESHOLD = 10;
-
- static final class CompanionHandler extends Handler {
- CompanionHandler(Looper looper) {
- super(looper);
- }
- }
-
- private final Context mContext;
- private final AlarmManager mAlarmManager;
- @GuardedBy("sStatsdLock")
- private static IStatsd sStatsd;
- private static final Object sStatsdLock = new Object();
-
- private final OnAlarmListener mPullingAlarmListener;
- private final OnAlarmListener mPeriodicAlarmListener;
-
- private StatsManagerService mStatsManagerService;
-
- @GuardedBy("sStatsdLock")
- private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
- @GuardedBy("sStatsdLock")
- private final HashMap<Long, String> mDeletedFiles = new HashMap<>();
- private final CompanionHandler mHandler;
-
- // Flag that is set when PHASE_BOOT_COMPLETED is triggered in the StatsCompanion lifecycle.
- private AtomicBoolean mBootCompleted = new AtomicBoolean(false);
-
- public StatsCompanionService(Context context) {
- super();
- mContext = context;
- mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
- if (DEBUG) Log.d(TAG, "Registered receiver for ACTION_PACKAGE_REPLACED and ADDED.");
- HandlerThread handlerThread = new HandlerThread(TAG);
- handlerThread.start();
- mHandler = new CompanionHandler(handlerThread.getLooper());
-
- mPullingAlarmListener = new PullingAlarmListener(context);
- mPeriodicAlarmListener = new PeriodicAlarmListener(context);
- }
-
- private final static int[] toIntArray(List<Integer> list) {
- int[] ret = new int[list.size()];
- for (int i = 0; i < ret.length; i++) {
- ret[i] = list.get(i);
- }
- return ret;
- }
-
- private final static long[] toLongArray(List<Long> list) {
- long[] ret = new long[list.size()];
- for (int i = 0; i < ret.length; i++) {
- ret[i] = list.get(i);
- }
- return ret;
- }
-
- /**
- * Non-blocking call to retrieve a reference to statsd
- *
- * @return IStatsd object if statsd is ready, null otherwise.
- */
- private static IStatsd getStatsdNonblocking() {
- synchronized (sStatsdLock) {
- return sStatsd;
- }
- }
-
- private static void informAllUids(Context context) {
- ParcelFileDescriptor[] fds;
- try {
- fds = ParcelFileDescriptor.createPipe();
- } catch (IOException e) {
- Log.e(TAG, "Failed to create a pipe to send uid map data.", e);
- return;
- }
- HandlerThread backgroundThread = new HandlerThread(
- "statsCompanionService.bg", THREAD_PRIORITY_BACKGROUND);
- backgroundThread.start();
- Handler handler = new Handler(backgroundThread.getLooper());
- handler.post(() -> {
- UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- PackageManager pm = context.getPackageManager();
- final List<UserHandle> users = um.getUserHandles(true);
- if (DEBUG) {
- Log.d(TAG, "Iterating over " + users.size() + " userHandles.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- return;
- }
- try {
- statsd.informAllUidData(fds[0]);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send uid map to statsd");
- }
- try {
- fds[0].close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close the read side of the pipe.", e);
- }
- final ParcelFileDescriptor writeFd = fds[1];
- FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd);
- try {
- ProtoOutputStream output = new ProtoOutputStream(fout);
- int numRecords = 0;
- // Add in all the apps for every user/profile.
- for (UserHandle userHandle : users) {
- List<PackageInfo> pi =
- pm.getInstalledPackagesAsUser(PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_ANY_USER
- | PackageManager.MATCH_APEX,
- userHandle.getIdentifier());
- for (int j = 0; j < pi.size(); j++) {
- if (pi.get(j).applicationInfo != null) {
- String installer;
- try {
- installer = pm.getInstallerPackageName(pi.get(j).packageName);
- } catch (IllegalArgumentException e) {
- installer = "";
- }
- long applicationInfoToken =
- output.start(ProtoOutputStream.FIELD_TYPE_MESSAGE
- | ProtoOutputStream.FIELD_COUNT_REPEATED
- | APPLICATION_INFO_FIELD_ID);
- output.write(ProtoOutputStream.FIELD_TYPE_INT32
- | ProtoOutputStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
- pi.get(j).applicationInfo.uid);
- output.write(ProtoOutputStream.FIELD_TYPE_INT64
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | VERSION_FIELD_ID, pi.get(j).getLongVersionCode());
- output.write(ProtoOutputStream.FIELD_TYPE_STRING
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | VERSION_STRING_FIELD_ID,
- pi.get(j).versionName);
- output.write(ProtoOutputStream.FIELD_TYPE_STRING
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | PACKAGE_NAME_FIELD_ID, pi.get(j).packageName);
- output.write(ProtoOutputStream.FIELD_TYPE_STRING
- | ProtoOutputStream.FIELD_COUNT_SINGLE
- | INSTALLER_FIELD_ID,
- installer == null ? "" : installer);
- numRecords++;
- output.end(applicationInfoToken);
- }
- }
- }
- output.flush();
- if (DEBUG) {
- Log.d(TAG, "Sent data for " + numRecords + " apps");
- }
- } finally {
- FileUtils.closeQuietly(fout);
- backgroundThread.quit();
- backgroundThread.interrupt();
- }
- });
- }
-
- private static class WakelockThread extends Thread {
- private final PowerManager.WakeLock mWl;
- private final Runnable mRunnable;
-
- WakelockThread(Context context, String wakelockName, Runnable runnable) {
- PowerManager powerManager = (PowerManager)
- context.getSystemService(Context.POWER_SERVICE);
- mWl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakelockName);
- mRunnable = runnable;
- }
- @Override
- public void run() {
- try {
- mRunnable.run();
- } finally {
- mWl.release();
- }
- }
- @Override
- public void start() {
- mWl.acquire();
- super.start();
- }
- }
-
- private final static class AppUpdateReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- /**
- * App updates actually consist of REMOVE, ADD, and then REPLACE broadcasts. To avoid
- * waste, we ignore the REMOVE and ADD broadcasts that contain the replacing flag.
- * If we can't find the value for EXTRA_REPLACING, we default to false.
- */
- if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)
- && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
- return; // Keep only replacing or normal add and remove.
- }
- if (DEBUG) Log.d(TAG, "StatsCompanionService noticed an app was updated.");
- synchronized (sStatsdLock) {
- if (sStatsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of an app update");
- return;
- }
- try {
- if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
- Bundle b = intent.getExtras();
- int uid = b.getInt(Intent.EXTRA_UID);
- boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
- if (!replacing) {
- // Don't bother sending an update if we're right about to get another
- // intent for the new version that's added.
- String app = intent.getData().getSchemeSpecificPart();
- sStatsd.informOnePackageRemoved(app, uid);
- }
- } else {
- PackageManager pm = context.getPackageManager();
- Bundle b = intent.getExtras();
- int uid = b.getInt(Intent.EXTRA_UID);
- String app = intent.getData().getSchemeSpecificPart();
- PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
- String installer;
- try {
- installer = pm.getInstallerPackageName(app);
- } catch (IllegalArgumentException e) {
- installer = "";
- }
- sStatsd.informOnePackage(
- app,
- uid,
- pi.getLongVersionCode(),
- pi.versionName == null ? "" : pi.versionName,
- installer == null ? "" : installer);
- }
- } catch (Exception e) {
- Log.w(TAG, "Failed to inform statsd of an app update", e);
- }
- }
- }
- }
-
- private static final class UserUpdateReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // Pull the latest state of UID->app name, version mapping.
- // Needed since the new user basically has a version of every app.
- informAllUids(context);
- }
- }
-
- public final static class PullingAlarmListener implements OnAlarmListener {
- private final Context mContext;
-
- PullingAlarmListener(Context context) {
- mContext = context;
- }
-
- @Override
- public void onAlarm() {
- if (DEBUG) {
- Log.d(TAG, "Time to poll something.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of pulling alarm firing.");
- return;
- }
-
- // Wakelock needs to be retained while calling statsd.
- Thread thread = new WakelockThread(mContext,
- PullingAlarmListener.class.getCanonicalName(), new Runnable() {
- @Override
- public void run() {
- try {
- statsd.informPollAlarmFired();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to inform statsd of pulling alarm firing.", e);
- }
- }
- });
- thread.start();
- }
- }
-
- public final static class PeriodicAlarmListener implements OnAlarmListener {
- private final Context mContext;
-
- PeriodicAlarmListener(Context context) {
- mContext = context;
- }
-
- @Override
- public void onAlarm() {
- if (DEBUG) {
- Log.d(TAG, "Time to trigger periodic alarm.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
- return;
- }
-
- // Wakelock needs to be retained while calling statsd.
- Thread thread = new WakelockThread(mContext,
- PeriodicAlarmListener.class.getCanonicalName(), new Runnable() {
- @Override
- public void run() {
- try {
- statsd.informAlarmForSubscriberTriggeringFired();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to inform statsd of periodic alarm firing.", e);
- }
- }
- });
- thread.start();
- }
- }
-
- public final static class ShutdownEventReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- /**
- * Skip immediately if intent is not relevant to device shutdown.
- */
- if (!intent.getAction().equals(Intent.ACTION_REBOOT)
- && !(intent.getAction().equals(Intent.ACTION_SHUTDOWN)
- && (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0)) {
- return;
- }
-
- if (DEBUG) {
- Log.i(TAG, "StatsCompanionService noticed a shutdown.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of a shutdown event.");
- return;
- }
- try {
- // two way binder call
- statsd.informDeviceShutdown();
- } catch (Exception e) {
- Log.w(TAG, "Failed to inform statsd of a shutdown event.", e);
- }
- }
- }
-
- @Override // Binder call
- public void setAlarmForSubscriberTriggering(long timestampMs) {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG,
- "Setting periodic alarm in about " + (timestampMs
- - SystemClock.elapsedRealtime()));
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
- // only fire when it awakens.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".periodic",
- mPeriodicAlarmListener, mHandler);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void cancelAlarmForSubscriberTriggering() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "Cancelling periodic alarm");
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- mAlarmManager.cancel(mPeriodicAlarmListener);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void setPullingAlarm(long nextPullTimeMs) {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "Setting pulling alarm in about "
- + (nextPullTimeMs - SystemClock.elapsedRealtime()));
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
- // only fire when it awakens.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextPullTimeMs, TAG + ".pull",
- mPullingAlarmListener, mHandler);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void cancelPullingAlarm() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "Cancelling pulling alarm");
- }
- final long callingToken = Binder.clearCallingIdentity();
- try {
- mAlarmManager.cancel(mPullingAlarmListener);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void statsdReady() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) {
- Log.d(TAG, "learned that statsdReady");
- }
- sayHiToStatsd(); // tell statsd that we're ready too and link to it
-
- final Intent intent = new Intent(StatsManager.ACTION_STATSD_STARTED);
- // Retrieve list of broadcast receivers for this broadcast & send them directed broadcasts
- // to wake them up (if they're in background).
- List<ResolveInfo> resolveInfos =
- mContext.getPackageManager().queryBroadcastReceiversAsUser(
- intent, 0, UserHandle.SYSTEM);
- if (resolveInfos == null || resolveInfos.isEmpty()) {
- return; // No need to send broadcast.
- }
-
- for (ResolveInfo resolveInfo : resolveInfos) {
- Intent intentToSend = new Intent(intent);
- intentToSend.setComponent(new ComponentName(
- resolveInfo.activityInfo.applicationInfo.packageName,
- resolveInfo.activityInfo.name));
- mContext.sendBroadcastAsUser(intentToSend, UserHandle.SYSTEM,
- android.Manifest.permission.DUMP);
- }
- }
-
- @Override // Binder call
- public boolean checkPermission(String permission, int pid, int uid) {
- StatsCompanion.enforceStatsdCallingUid();
- return mContext.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED;
- }
-
- // Statsd related code
-
- /**
- * Fetches the statsd IBinder service. This is a blocking call that always refetches statsd
- * instead of returning the cached sStatsd.
- * Note: This should only be called from {@link #sayHiToStatsd()}. All other clients should use
- * the cached sStatsd via {@link #getStatsdNonblocking()}.
- */
- private IStatsd fetchStatsdServiceLocked() {
- sStatsd = IStatsd.Stub.asInterface(StatsFrameworkInitializer
- .getStatsServiceManager()
- .getStatsdServiceRegisterer()
- .get());
- return sStatsd;
- }
-
- private void registerStatsdDeathRecipient(IStatsd statsd, List<BroadcastReceiver> receivers) {
- StatsdDeathRecipient deathRecipient = new StatsdDeathRecipient(statsd, receivers);
-
- try {
- statsd.asBinder().linkToDeath(deathRecipient, /*flags=*/0);
- } catch (RemoteException e) {
- Log.e(TAG, "linkToDeath (StatsdDeathRecipient) failed");
- // Statsd has already died. Unregister receivers ourselves.
- for (BroadcastReceiver receiver : receivers) {
- mContext.unregisterReceiver(receiver);
- }
- synchronized (sStatsdLock) {
- if (statsd == sStatsd) {
- statsdNotReadyLocked();
- }
- }
- }
- }
-
- /**
- * Now that the android system is ready, StatsCompanion is ready too, so inform statsd.
- */
- void systemReady() {
- if (DEBUG) Log.d(TAG, "Learned that systemReady");
- sayHiToStatsd();
- }
-
- void setStatsManagerService(StatsManagerService statsManagerService) {
- mStatsManagerService = statsManagerService;
- }
-
- /**
- * Tells statsd that statscompanion is ready. If the binder call returns, link to
- * statsd.
- */
- private void sayHiToStatsd() {
- IStatsd statsd;
- synchronized (sStatsdLock) {
- if (sStatsd != null && sStatsd.asBinder().isBinderAlive()) {
- Log.e(TAG, "statsd has already been fetched before",
- new IllegalStateException("IStatsd object should be null or dead"));
- return;
- }
- statsd = fetchStatsdServiceLocked();
- }
-
- if (statsd == null) {
- Log.i(TAG, "Could not yet find statsd to tell it that StatsCompanion is alive.");
- return;
- }
-
- // Cleann up from previous statsd - cancel any alarms that had been set. Do this here
- // instead of in binder death because statsd can come back and set different alarms, or not
- // want to set an alarm when it had been set. This guarantees that when we get a new statsd,
- // we cancel any alarms before it is able to set them.
- cancelPullingAlarm();
- cancelAlarmForSubscriberTriggering();
-
- if (DEBUG) Log.d(TAG, "Saying hi to statsd");
- mStatsManagerService.statsdReady(statsd);
- try {
- statsd.statsCompanionReady();
-
- BroadcastReceiver appUpdateReceiver = new AppUpdateReceiver();
- BroadcastReceiver userUpdateReceiver = new UserUpdateReceiver();
- BroadcastReceiver shutdownEventReceiver = new ShutdownEventReceiver();
-
- // Setup broadcast receiver for updates.
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
- filter.addAction(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addDataScheme("package");
- mContext.registerReceiverForAllUsers(appUpdateReceiver, filter, null, null);
-
- // Setup receiver for user initialize (which happens once for a new user)
- // and if a user is removed.
- filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE);
- filter.addAction(Intent.ACTION_USER_REMOVED);
- mContext.registerReceiverForAllUsers(userUpdateReceiver, filter, null, null);
-
- // Setup receiver for device reboots or shutdowns.
- filter = new IntentFilter(Intent.ACTION_REBOOT);
- filter.addAction(Intent.ACTION_SHUTDOWN);
- mContext.registerReceiverForAllUsers(shutdownEventReceiver, filter, null, null);
-
- // Register death recipient.
- List<BroadcastReceiver> broadcastReceivers =
- List.of(appUpdateReceiver, userUpdateReceiver, shutdownEventReceiver);
- registerStatsdDeathRecipient(statsd, broadcastReceivers);
-
- // Tell statsd that boot has completed. The signal may have already been sent, but since
- // the signal-receiving function is idempotent, that's ok.
- if (mBootCompleted.get()) {
- statsd.bootCompleted();
- }
-
- // Pull the latest state of UID->app name, version mapping when statsd starts.
- informAllUids(mContext);
-
- Log.i(TAG, "Told statsd that StatsCompanionService is alive.");
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
- }
- }
-
- private class StatsdDeathRecipient implements IBinder.DeathRecipient {
-
- private final IStatsd mStatsd;
- private final List<BroadcastReceiver> mReceiversToUnregister;
-
- StatsdDeathRecipient(IStatsd statsd, List<BroadcastReceiver> receivers) {
- mStatsd = statsd;
- mReceiversToUnregister = receivers;
- }
-
- // It is possible for binderDied to be called after a restarted statsd calls statsdReady,
- // but that's alright because the code does not assume an ordering of the two calls.
- @Override
- public void binderDied() {
- Log.i(TAG, "Statsd is dead - erase all my knowledge, except pullers");
- synchronized (sStatsdLock) {
- long now = SystemClock.elapsedRealtime();
- for (Long timeMillis : mDeathTimeMillis) {
- long ageMillis = now - timeMillis;
- if (ageMillis > MILLIS_IN_A_DAY) {
- mDeathTimeMillis.remove(timeMillis);
- }
- }
- for (Long timeMillis : mDeletedFiles.keySet()) {
- long ageMillis = now - timeMillis;
- if (ageMillis > MILLIS_IN_A_DAY * 7) {
- mDeletedFiles.remove(timeMillis);
- }
- }
- mDeathTimeMillis.add(now);
- if (mDeathTimeMillis.size() >= DEATH_THRESHOLD) {
- mDeathTimeMillis.clear();
- File[] configs = new File(CONFIG_DIR).listFiles();
- if (configs != null && configs.length > 0) {
- String fileName = configs[0].getName();
- if (configs[0].delete()) {
- mDeletedFiles.put(now, fileName);
- }
- }
- }
-
- // Unregister receivers on death because receivers can only be unregistered once.
- // Otherwise, an IllegalArgumentException is thrown.
- for (BroadcastReceiver receiver: mReceiversToUnregister) {
- mContext.unregisterReceiver(receiver);
- }
-
- // It's possible for statsd to have restarted and called statsdReady, causing a new
- // sStatsd binder object to be fetched, before the binderDied callback runs. Only
- // call #statsdNotReadyLocked if that hasn't happened yet.
- if (mStatsd == sStatsd) {
- statsdNotReadyLocked();
- }
- }
- }
- }
-
- private void statsdNotReadyLocked() {
- sStatsd = null;
- mStatsManagerService.statsdNotReady();
- }
-
- void bootCompleted() {
- mBootCompleted.set(true);
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- // Statsd is not yet ready.
- // Delay the boot completed ping to {@link #sayHiToStatsd()}
- return;
- }
- try {
- statsd.bootCompleted();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to notify statsd that boot completed");
- }
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- return;
- }
-
- synchronized (sStatsdLock) {
- writer.println("Number of configuration files deleted: " + mDeletedFiles.size());
- if (mDeletedFiles.size() > 0) {
- writer.println(" timestamp, deleted file name");
- }
- long lastBootMillis =
- SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime();
- for (Long elapsedMillis : mDeletedFiles.keySet()) {
- long deletionMillis = lastBootMillis + elapsedMillis;
- writer.println(" " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
- }
- }
- }
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
deleted file mode 100644
index 1e3846bc4a0b..000000000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.stats;
-
-import static com.android.server.stats.StatsCompanion.PendingIntentRef;
-
-import android.Manifest;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IPullAtomCallback;
-import android.os.IStatsManagerService;
-import android.os.IStatsd;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Service for {@link android.app.StatsManager}.
- *
- * @hide
- */
-public class StatsManagerService extends IStatsManagerService.Stub {
-
- private static final String TAG = "StatsManagerService";
- private static final boolean DEBUG = false;
-
- private static final int STATSD_TIMEOUT_MILLIS = 5000;
-
- private static final String USAGE_STATS_PERMISSION_OPS = "android:get_usage_stats";
-
- @GuardedBy("mLock")
- private IStatsd mStatsd;
- private final Object mLock = new Object();
-
- private StatsCompanionService mStatsCompanionService;
- private Context mContext;
-
- @GuardedBy("mLock")
- private ArrayMap<ConfigKey, PendingIntentRef> mDataFetchPirMap = new ArrayMap<>();
- @GuardedBy("mLock")
- private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>();
- @GuardedBy("mLock")
- private ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> mBroadcastSubscriberPirMap =
- new ArrayMap<>();
-
- public StatsManagerService(Context context) {
- super();
- mContext = context;
- }
-
- private static class ConfigKey {
- private final int mUid;
- private final long mConfigId;
-
- ConfigKey(int uid, long configId) {
- mUid = uid;
- mConfigId = configId;
- }
-
- public int getUid() {
- return mUid;
- }
-
- public long getConfigId() {
- return mConfigId;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUid, mConfigId);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ConfigKey) {
- ConfigKey other = (ConfigKey) obj;
- return this.mUid == other.getUid() && this.mConfigId == other.getConfigId();
- }
- return false;
- }
- }
-
- private static class PullerKey {
- private final int mUid;
- private final int mAtomTag;
-
- PullerKey(int uid, int atom) {
- mUid = uid;
- mAtomTag = atom;
- }
-
- public int getUid() {
- return mUid;
- }
-
- public int getAtom() {
- return mAtomTag;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mUid, mAtomTag);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof PullerKey) {
- PullerKey other = (PullerKey) obj;
- return this.mUid == other.getUid() && this.mAtomTag == other.getAtom();
- }
- return false;
- }
- }
-
- private static class PullerValue {
- private final long mCoolDownMillis;
- private final long mTimeoutMillis;
- private final int[] mAdditiveFields;
- private final IPullAtomCallback mCallback;
-
- PullerValue(long coolDownMillis, long timeoutMillis, int[] additiveFields,
- IPullAtomCallback callback) {
- mCoolDownMillis = coolDownMillis;
- mTimeoutMillis = timeoutMillis;
- mAdditiveFields = additiveFields;
- mCallback = callback;
- }
-
- public long getCoolDownMillis() {
- return mCoolDownMillis;
- }
-
- public long getTimeoutMillis() {
- return mTimeoutMillis;
- }
-
- public int[] getAdditiveFields() {
- return mAdditiveFields;
- }
-
- public IPullAtomCallback getCallback() {
- return mCallback;
- }
- }
-
- private final ArrayMap<PullerKey, PullerValue> mPullers = new ArrayMap<>();
-
- @Override
- public void registerPullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
- int[] additiveFields, IPullAtomCallback pullerCallback) {
- enforceRegisterStatsPullAtomPermission();
- if (pullerCallback == null) {
- Log.w(TAG, "Puller callback is null for atom " + atomTag);
- return;
- }
- int callingUid = Binder.getCallingUid();
- PullerKey key = new PullerKey(callingUid, atomTag);
- PullerValue val =
- new PullerValue(coolDownMillis, timeoutMillis, additiveFields, pullerCallback);
-
- // Always cache the puller in StatsManagerService. If statsd is down, we will register the
- // puller when statsd comes back up.
- synchronized (mLock) {
- mPullers.put(key, val);
- }
-
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- statsd.registerPullAtomCallback(callingUid, atomTag, coolDownMillis, timeoutMillis,
- additiveFields, pullerCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to access statsd to register puller for atom " + atomTag);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void unregisterPullAtomCallback(int atomTag) {
- enforceRegisterStatsPullAtomPermission();
- int callingUid = Binder.getCallingUid();
- PullerKey key = new PullerKey(callingUid, atomTag);
-
- // Always remove the puller from StatsManagerService even if statsd is down. When statsd
- // comes back up, we will not re-register the removed puller.
- synchronized (mLock) {
- mPullers.remove(key);
- }
-
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- statsd.unregisterPullAtomCallback(callingUid, atomTag);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to access statsd to unregister puller for atom " + atomTag);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void setDataFetchOperation(long configId, PendingIntent pendingIntent,
- String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
- ConfigKey key = new ConfigKey(callingUid, configId);
- // We add the PIR to a map so we can reregister if statsd is unavailable.
- synchronized (mLock) {
- mDataFetchPirMap.put(key, pir);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.setDataFetchOperation(configId, pir, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setDataFetchOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void removeDataFetchOperation(long configId, String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- ConfigKey key = new ConfigKey(callingUid, configId);
- synchronized (mLock) {
- mDataFetchPirMap.remove(key);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.removeDataFetchOperation(configId, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to removeDataFetchOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public long[] setActiveConfigsChangedOperation(PendingIntent pendingIntent,
- String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
- // We add the PIR to a map so we can reregister if statsd is unavailable.
- synchronized (mLock) {
- mActiveConfigsPirMap.put(callingUid, pir);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- return statsd.setActiveConfigsChangedOperation(pir, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setActiveConfigsChangedOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- return new long[] {};
- }
-
- @Override
- public void removeActiveConfigsChangedOperation(String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- synchronized (mLock) {
- mActiveConfigsPirMap.remove(callingUid);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.removeActiveConfigsChangedOperation(callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to removeActiveConfigsChangedOperation with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void setBroadcastSubscriber(long configId, long subscriberId,
- PendingIntent pendingIntent, String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
- ConfigKey key = new ConfigKey(callingUid, configId);
- // We add the PIR to a map so we can reregister if statsd is unavailable.
- synchronized (mLock) {
- ArrayMap<Long, PendingIntentRef> innerMap = mBroadcastSubscriberPirMap
- .getOrDefault(key, new ArrayMap<>());
- innerMap.put(subscriberId, pir);
- mBroadcastSubscriberPirMap.put(key, innerMap);
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.setBroadcastSubscriber(
- configId, subscriberId, pir, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setBroadcastSubscriber with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void unsetBroadcastSubscriber(long configId, long subscriberId, String packageName) {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- ConfigKey key = new ConfigKey(callingUid, configId);
- synchronized (mLock) {
- ArrayMap<Long, PendingIntentRef> innerMap = mBroadcastSubscriberPirMap
- .getOrDefault(key, new ArrayMap<>());
- innerMap.remove(subscriberId);
- if (innerMap.isEmpty()) {
- mBroadcastSubscriberPirMap.remove(key);
- }
- }
- try {
- IStatsd statsd = getStatsdNonblocking();
- if (statsd != null) {
- statsd.unsetBroadcastSubscriber(configId, subscriberId, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to unsetBroadcastSubscriber with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public long[] getRegisteredExperimentIds() throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(null);
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- return statsd.getRegisteredExperimentIds();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to getRegisteredExperimentIds with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to registerExperimentIds");
- }
-
- @Override
- public byte[] getMetadata(String packageName) throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- return statsd.getMetadata();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to getMetadata with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to getMetadata");
- }
-
- @Override
- public byte[] getData(long key, String packageName) throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- PowerManager powerManager = (PowerManager)
- mContext.getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- /*tag=*/ StatsManagerService.class.getCanonicalName());
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- wl.acquire();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- return statsd.getData(key, callingUid);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to getData with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- wl.release();
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to getData");
- }
-
- @Override
- public void addConfiguration(long configId, byte[] config, String packageName)
- throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- statsd.addConfiguration(configId, config, callingUid);
- return;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to addConfiguration with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to addConfig");
- }
-
- @Override
- public void removeConfiguration(long configId, String packageName)
- throws IllegalStateException {
- enforceDumpAndUsageStatsPermission(packageName);
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- IStatsd statsd = waitForStatsd();
- if (statsd != null) {
- statsd.removeConfiguration(configId, callingUid);
- return;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to removeConfiguration with statsd");
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- throw new IllegalStateException("Failed to connect to statsd to removeConfig");
- }
-
- void setStatsCompanionService(StatsCompanionService statsCompanionService) {
- mStatsCompanionService = statsCompanionService;
- }
-
- /**
- * Checks that the caller has both DUMP and PACKAGE_USAGE_STATS permissions. Also checks that
- * the caller has USAGE_STATS_PERMISSION_OPS for the specified packageName if it is not null.
- *
- * @param packageName The packageName to check USAGE_STATS_PERMISSION_OPS.
- */
- private void enforceDumpAndUsageStatsPermission(@Nullable String packageName) {
- int callingUid = Binder.getCallingUid();
- int callingPid = Binder.getCallingPid();
-
- if (callingPid == Process.myPid()) {
- return;
- }
-
- mContext.enforceCallingPermission(Manifest.permission.DUMP, null);
- mContext.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS, null);
-
- if (packageName == null) {
- return;
- }
- AppOpsManager appOpsManager = (AppOpsManager) mContext
- .getSystemService(Context.APP_OPS_SERVICE);
- switch (appOpsManager.noteOp(USAGE_STATS_PERMISSION_OPS,
- Binder.getCallingUid(), packageName, null, null)) {
- case AppOpsManager.MODE_ALLOWED:
- case AppOpsManager.MODE_DEFAULT:
- break;
- default:
- throw new SecurityException(
- String.format("UID %d / PID %d lacks app-op %s",
- callingUid, callingPid, USAGE_STATS_PERMISSION_OPS)
- );
- }
- }
-
- private void enforceRegisterStatsPullAtomPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.REGISTER_STATS_PULL_ATOM,
- "Need REGISTER_STATS_PULL_ATOM permission.");
- }
-
-
- /**
- * Clients should call this if blocking until statsd to be ready is desired
- *
- * @return IStatsd object if statsd becomes ready within the timeout, null otherwise.
- */
- private IStatsd waitForStatsd() {
- synchronized (mLock) {
- if (mStatsd == null) {
- try {
- mLock.wait(STATSD_TIMEOUT_MILLIS);
- } catch (InterruptedException e) {
- Log.e(TAG, "wait for statsd interrupted");
- }
- }
- return mStatsd;
- }
- }
-
- /**
- * Clients should call this to receive a reference to statsd.
- *
- * @return IStatsd object if statsd is ready, null otherwise.
- */
- private IStatsd getStatsdNonblocking() {
- synchronized (mLock) {
- return mStatsd;
- }
- }
-
- /**
- * Called from {@link StatsCompanionService}.
- *
- * Tells StatsManagerService that Statsd is ready and updates
- * Statsd with the contents of our local cache.
- */
- void statsdReady(IStatsd statsd) {
- synchronized (mLock) {
- mStatsd = statsd;
- mLock.notify();
- }
- sayHiToStatsd(statsd);
- }
-
- /**
- * Called from {@link StatsCompanionService}.
- *
- * Tells StatsManagerService that Statsd is no longer ready
- * and we should no longer make binder calls with statsd.
- */
- void statsdNotReady() {
- synchronized (mLock) {
- mStatsd = null;
- }
- }
-
- private void sayHiToStatsd(IStatsd statsd) {
- if (statsd == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- registerAllPullers(statsd);
- registerAllDataFetchOperations(statsd);
- registerAllActiveConfigsChangedOperations(statsd);
- registerAllBroadcastSubscribers(statsd);
- } catch (RemoteException e) {
- Log.e(TAG, "StatsManager failed to (re-)register data with statsd");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllPullers(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a copy of the
- // data with the lock held before iterating through the map.
- ArrayMap<PullerKey, PullerValue> pullersCopy;
- synchronized (mLock) {
- pullersCopy = new ArrayMap<>(mPullers);
- }
-
- for (Map.Entry<PullerKey, PullerValue> entry : pullersCopy.entrySet()) {
- PullerKey key = entry.getKey();
- PullerValue value = entry.getValue();
- statsd.registerPullAtomCallback(key.getUid(), key.getAtom(), value.getCoolDownMillis(),
- value.getTimeoutMillis(), value.getAdditiveFields(), value.getCallback());
- }
- statsd.allPullersFromBootRegistered();
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllDataFetchOperations(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a copy of the
- // data with the lock held before iterating through the map.
- ArrayMap<ConfigKey, PendingIntentRef> dataFetchCopy;
- synchronized (mLock) {
- dataFetchCopy = new ArrayMap<>(mDataFetchPirMap);
- }
-
- for (Map.Entry<ConfigKey, PendingIntentRef> entry : dataFetchCopy.entrySet()) {
- ConfigKey key = entry.getKey();
- statsd.setDataFetchOperation(key.getConfigId(), entry.getValue(), key.getUid());
- }
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllActiveConfigsChangedOperations(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a copy of the
- // data with the lock held before iterating through the map.
- ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy;
- synchronized (mLock) {
- activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap);
- }
-
- for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) {
- statsd.setActiveConfigsChangedOperation(entry.getValue(), entry.getKey());
- }
- }
-
- // Pre-condition: the Binder calling identity has already been cleared
- private void registerAllBroadcastSubscribers(IStatsd statsd) throws RemoteException {
- // Since we do not want to make an IPC with the lock held, we first create a deep copy of
- // the data with the lock held before iterating through the map.
- ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy =
- new ArrayMap<>();
- synchronized (mLock) {
- for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry :
- mBroadcastSubscriberPirMap.entrySet()) {
- broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap(entry.getValue()));
- }
- }
-
- for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry :
- mBroadcastSubscriberPirMap.entrySet()) {
- ConfigKey configKey = entry.getKey();
- for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) {
- statsd.setBroadcastSubscriber(configKey.getConfigId(), subscriberEntry.getKey(),
- subscriberEntry.getValue(), configKey.getUid());
- }
- }
- }
-}
diff --git a/apex/statsd/statsd.rc b/apex/statsd/statsd.rc
deleted file mode 100644
index 605da2af0c19..000000000000
--- a/apex/statsd/statsd.rc
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-service statsd /apex/com.android.os.statsd/bin/statsd
- class main
- socket statsdw dgram+passcred 0222 statsd statsd
- user statsd
- group statsd log
- writepid /dev/cpuset/system-background/tasks
diff --git a/apex/statsd/testing/Android.bp b/apex/statsd/testing/Android.bp
deleted file mode 100644
index a9cd0ccb53e8..000000000000
--- a/apex/statsd/testing/Android.bp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-apex_test {
- name: "test_com.android.os.statsd",
- visibility: [
- "//system/apex/tests",
- ],
- defaults: ["com.android.os.statsd-defaults"],
- manifest: "test_manifest.json",
- file_contexts: ":com.android.os.statsd-file_contexts",
- // Test APEX, should never be installed
- installable: false,
-}
diff --git a/apex/statsd/testing/test_manifest.json b/apex/statsd/testing/test_manifest.json
deleted file mode 100644
index 57343d3e6ae5..000000000000
--- a/apex/statsd/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.os.statsd",
- "version": 2147483647
-}
diff --git a/apex/statsd/tests/libstatspull/Android.bp b/apex/statsd/tests/libstatspull/Android.bp
deleted file mode 100644
index 05b3e049ac39..000000000000
--- a/apex/statsd/tests/libstatspull/Android.bp
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
- name: "LibStatsPullTests",
- static_libs: [
- "androidx.test.rules",
- "platformprotoslite",
- "statsdprotolite",
- "truth-prebuilt",
- ],
- libs: [
- "android.test.runner.stubs",
- "android.test.base.stubs",
- ],
- jni_libs: [
- "libstatspull_testhelper",
- ],
- srcs: [
- "src/**/*.java",
- "protos/**/*.proto",
- ],
- test_suites: [
- "device-tests",
- "mts",
- ],
- platform_apis: true,
- privileged: true,
- certificate: "platform",
- compile_multilib: "both",
-}
-
-cc_library_shared {
- name: "libstatspull_testhelper",
- srcs: ["jni/stats_pull_helper.cpp"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- shared_libs: [
- "libbinder_ndk",
- "statsd-aidl-ndk_platform",
- ],
- static_libs: [
- "libstatspull_private",
- "libstatssocket_private",
- "libutils",
- "libcutils",
- ],
-}
diff --git a/apex/statsd/tests/libstatspull/AndroidManifest.xml b/apex/statsd/tests/libstatspull/AndroidManifest.xml
deleted file mode 100644
index 0c669b051c86..000000000000
--- a/apex/statsd/tests/libstatspull/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.internal.os.statsd.libstats" >
-
-
- <uses-permission android:name="android.permission.DUMP" />
- <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
- <uses-permission android:name="android.permission.REGISTER_STATS_PULL_ATOM" />
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.internal.os.statsd.libstats"
- android:label="Tests for libstatspull">
- </instrumentation>
-</manifest>
-
diff --git a/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp b/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp
deleted file mode 100644
index 166592d35151..000000000000
--- a/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <log/log.h>
-#include <stats_event.h>
-#include <stats_pull_atom_callback.h>
-
-#include <chrono>
-#include <thread>
-
-using std::this_thread::sleep_for;
-
-namespace {
-static int32_t sAtomTag;
-static int32_t sPullReturnVal;
-static int64_t sLatencyMillis;
-static int32_t sAtomsPerPull;
-static int32_t sNumPulls = 0;
-
-static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atomTag, AStatsEventList* data,
- void* /*cookie*/) {
- sNumPulls++;
- sleep_for(std::chrono::milliseconds(sLatencyMillis));
- for (int i = 0; i < sAtomsPerPull; i++) {
- AStatsEvent* event = AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(event, atomTag);
- AStatsEvent_writeInt64(event, (int64_t) sNumPulls);
- AStatsEvent_build(event);
- }
- return sPullReturnVal;
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_setStatsPuller(
- JNIEnv* /*env*/, jobject /* this */, jint atomTag, jlong timeoutMillis,
- jlong coolDownMillis, jint pullRetVal, jlong latencyMillis, int atomsPerPull) {
- sAtomTag = atomTag;
- sPullReturnVal = pullRetVal;
- sLatencyMillis = latencyMillis;
- sAtomsPerPull = atomsPerPull;
- sNumPulls = 0;
- AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
- AStatsManager_PullAtomMetadata_setCoolDownMillis(metadata, coolDownMillis);
- AStatsManager_PullAtomMetadata_setTimeoutMillis(metadata, timeoutMillis);
-
- AStatsManager_setPullAtomCallback(sAtomTag, metadata, &pullAtomCallback, nullptr);
- AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_clearStatsPuller(JNIEnv* /*env*/,
- jobject /* this */,
- jint /*atomTag*/) {
- AStatsManager_clearPullAtomCallback(sAtomTag);
-}
-} // namespace
diff --git a/apex/statsd/tests/libstatspull/protos/test_atoms.proto b/apex/statsd/tests/libstatspull/protos/test_atoms.proto
deleted file mode 100644
index 56c1b534a7ce..000000000000
--- a/apex/statsd/tests/libstatspull/protos/test_atoms.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-
-package com.android.internal.os.statsd.protos;
-
-option java_package = "com.android.internal.os.statsd.protos";
-option java_outer_classname = "TestAtoms";
-
-message PullCallbackAtomWrapper {
- optional PullCallbackAtom pull_callback_atom = 150030;
-}
-
-message PullCallbackAtom {
- optional int64 long_val = 1;
-}
-
-
-
diff --git a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java b/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java
deleted file mode 100644
index 6108a324e15e..000000000000
--- a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.os.statsd.libstats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager;
-import android.content.Context;
-import android.util.Log;
-import android.util.StatsLog;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.PullAtomPackages;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.statsd.protos.TestAtoms;
-import com.android.os.AtomsProto.Atom;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * Test puller registration.
- */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class LibStatsPullTests {
- private static final String LOG_TAG = LibStatsPullTests.class.getSimpleName();
- private static final int SHORT_SLEEP_MILLIS = 250;
- private static final int LONG_SLEEP_MILLIS = 1_000;
- private Context mContext;
- private static final int PULL_ATOM_TAG = 150030;
- private static final int APP_BREADCRUMB_LABEL = 3;
- private static int sPullReturnValue;
- private static long sConfigId;
- private static long sPullLatencyMillis;
- private static long sPullTimeoutMillis;
- private static long sCoolDownMillis;
- private static int sAtomsPerPull;
-
- static {
- System.loadLibrary("statspull_testhelper");
- }
-
- /**
- * Setup the tests. Initialize shared data.
- */
- @Before
- public void setup() {
- mContext = InstrumentationRegistry.getTargetContext();
- assertThat(InstrumentationRegistry.getInstrumentation()).isNotNull();
- sPullReturnValue = StatsManager.PULL_SUCCESS;
- sPullLatencyMillis = 0;
- sPullTimeoutMillis = 10_000L;
- sCoolDownMillis = 1_000L;
- sAtomsPerPull = 1;
- }
-
- /**
- * Teardown the tests.
- */
- @After
- public void tearDown() throws Exception {
- clearStatsPuller(PULL_ATOM_TAG);
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- statsManager.removeConfig(sConfigId);
- }
-
- /**
- * Tests adding a puller callback and that pulls complete successfully.
- */
- @Test
- public void testPullAtomCallbackRegistration() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- // Upload a config that captures that pulled atom.
- createAndAddConfigToStatsd(statsManager);
-
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish.
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(1);
- TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
- try {
- atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
- .parseFrom(data.get(0).toByteArray());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to parse primitive atoms");
- }
- assertThat(atomWrapper).isNotNull();
- assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
- TestAtoms.PullCallbackAtom atom =
- atomWrapper.getPullCallbackAtom();
- assertThat(atom.getLongVal()).isEqualTo(1);
- }
-
- /**
- * Tests that a failed pull is skipped.
- */
- @Test
- public void testPullAtomCallbackFailure() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- createAndAddConfigToStatsd(statsManager);
- sPullReturnValue = StatsManager.PULL_SKIP;
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish.
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(0);
- }
-
- /**
- * Tests that a pull that times out is skipped.
- */
- @Test
- public void testPullAtomCallbackTimeout() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- createAndAddConfigToStatsd(statsManager);
- // The puller will sleep for 1.5 sec.
- sPullLatencyMillis = 1_500;
- // 1 second timeout
- sPullTimeoutMillis = 1_000;
-
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish and the pull timeout.
- Thread.sleep(sPullLatencyMillis * 2);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(0);
- }
-
- /**
- * Tests that 2 pulls in quick succession use the cache instead of pulling again.
- */
- @Test
- public void testPullAtomCallbackCache() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- createAndAddConfigToStatsd(statsManager);
-
- // Set the cooldown to 10 seconds
- sCoolDownMillis = 10_000L;
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
-
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Pull from cache.
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(2);
- for (int i = 0; i < data.size(); i++) {
- TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
- try {
- atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
- .parseFrom(data.get(i).toByteArray());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to parse primitive atoms");
- }
- assertThat(atomWrapper).isNotNull();
- assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
- TestAtoms.PullCallbackAtom atom =
- atomWrapper.getPullCallbackAtom();
- assertThat(atom.getLongVal()).isEqualTo(1);
- }
- }
-
- /**
- * Tests that a pull that returns 1000 stats events works properly.
- */
- @Test
- public void testPullAtomCallbackStress() throws Exception {
- StatsManager statsManager = (StatsManager) mContext.getSystemService(
- Context.STATS_MANAGER);
- // Upload a config that captures that pulled atom.
- createAndAddConfigToStatsd(statsManager);
- sAtomsPerPull = 1000;
- // Add the puller.
- setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
- sPullLatencyMillis, sAtomsPerPull);
-
- Thread.sleep(SHORT_SLEEP_MILLIS);
- StatsLog.logStart(APP_BREADCRUMB_LABEL);
- // Let the current bucket finish.
- Thread.sleep(LONG_SLEEP_MILLIS);
- List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
- clearStatsPuller(PULL_ATOM_TAG);
- assertThat(data.size()).isEqualTo(sAtomsPerPull);
-
- for (int i = 0; i < data.size(); i++) {
- TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
- try {
- atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
- .parseFrom(data.get(i).toByteArray());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to parse primitive atoms");
- }
- assertThat(atomWrapper).isNotNull();
- assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
- TestAtoms.PullCallbackAtom atom =
- atomWrapper.getPullCallbackAtom();
- assertThat(atom.getLongVal()).isEqualTo(1);
- }
- }
-
- private void createAndAddConfigToStatsd(StatsManager statsManager) throws Exception {
- sConfigId = System.currentTimeMillis();
- long triggerMatcherId = sConfigId + 10;
- long pullerMatcherId = sConfigId + 11;
- long metricId = sConfigId + 100;
- StatsdConfig config = StatsConfigUtils.getSimpleTestConfig(sConfigId)
- .addAtomMatcher(
- StatsConfigUtils.getAppBreadcrumbMatcher(triggerMatcherId,
- APP_BREADCRUMB_LABEL))
- .addAtomMatcher(AtomMatcher.newBuilder()
- .setId(pullerMatcherId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(PULL_ATOM_TAG))
- )
- .addGaugeMetric(GaugeMetric.newBuilder()
- .setId(metricId)
- .setWhat(pullerMatcherId)
- .setTriggerEvent(triggerMatcherId)
- .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true))
- .setBucket(TimeUnit.CTS)
- .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES)
- .setMaxNumGaugeAtomsPerBucket(1000)
- )
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(PULL_ATOM_TAG)
- .addPackages(LibStatsPullTests.class.getPackage().getName()))
- .build();
- statsManager.addConfig(sConfigId, config.toByteArray());
- assertThat(StatsConfigUtils.verifyValidConfigExists(statsManager, sConfigId)).isTrue();
- }
-
- private native void setStatsPuller(int atomTag, long timeoutMillis, long coolDownMillis,
- int pullReturnVal, long latencyMillis, int atomPerPull);
-
- private native void clearStatsPuller(int atomTag);
-}
-
diff --git a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java b/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java
deleted file mode 100644
index b5afb94886de..000000000000
--- a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.os.statsd.libstats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager;
-import android.util.Log;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.os.StatsLog.StatsdStatsReport.ConfigStats;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Util class for constructing statsd configs.
- */
-public class StatsConfigUtils {
- public static final String TAG = "statsd.StatsConfigUtils";
- public static final int SHORT_WAIT = 2_000; // 2 seconds.
-
- /**
- * @return An empty StatsdConfig in serialized proto format.
- */
- public static StatsdConfig.Builder getSimpleTestConfig(long configId) {
- return StatsdConfig.newBuilder().setId(configId)
- .addAllowedLogSource(StatsConfigUtils.class.getPackage().getName());
- }
-
-
- public static boolean verifyValidConfigExists(StatsManager statsManager, long configId) {
- StatsdStatsReport report = null;
- try {
- report = StatsdStatsReport.parser().parseFrom(statsManager.getStatsMetadata());
- } catch (Exception e) {
- Log.e(TAG, "getMetadata failed", e);
- }
- assertThat(report).isNotNull();
- boolean foundConfig = false;
- for (ConfigStats configStats : report.getConfigStatsList()) {
- if (configStats.getId() == configId && configStats.getIsValid()
- && configStats.getDeletionTimeSec() == 0) {
- foundConfig = true;
- }
- }
- return foundConfig;
- }
-
- public static AtomMatcher getAppBreadcrumbMatcher(long id, int label) {
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(
- SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
- .setEqInt(label)
- )
- )
- .build();
- }
-
- public static ConfigMetricsReport getConfigMetricsReport(StatsManager statsManager,
- long configId) {
- ConfigMetricsReportList reportList = null;
- try {
- reportList = ConfigMetricsReportList.parser()
- .parseFrom(statsManager.getReports(configId));
- } catch (Exception e) {
- Log.e(TAG, "getData failed", e);
- }
- assertThat(reportList).isNotNull();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- ConfigMetricsReport report = reportList.getReports(0);
- assertThat(report.getDumpReportReason())
- .isEqualTo(ConfigMetricsReport.DumpReportReason.GET_DATA_CALLED);
- return report;
-
- }
- public static List<Atom> getGaugeMetricDataList(ConfigMetricsReport report) {
- List<Atom> data = new ArrayList<>();
- for (StatsLogReport metric : report.getMetricsList()) {
- for (GaugeMetricData gaugeMetricData : metric.getGaugeMetrics().getDataList()) {
- for (GaugeBucketInfo bucketInfo : gaugeMetricData.getBucketInfoList()) {
- for (Atom atom : bucketInfo.getAtomList()) {
- data.add(atom);
- }
- }
- }
- }
- return data;
- }
-
- public static List<Atom> getGaugeMetricDataList(StatsManager statsManager, long configId) {
- ConfigMetricsReport report = getConfigMetricsReport(statsManager, configId);
- return getGaugeMetricDataList(report);
- }
-}
-
diff --git a/cmds/statsd/.clang-format b/cmds/statsd/.clang-format
deleted file mode 100644
index cead3a079435..000000000000
--- a/cmds/statsd/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
- - Regex: '^"Log\.h"'
- Priority: -1
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
deleted file mode 100644
index 124f815f51f0..000000000000
--- a/cmds/statsd/Android.bp
+++ /dev/null
@@ -1,429 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// ==========================================================
-// Build the library for use on the host
-// ==========================================================
-cc_library_host_shared {
- name: "libstats_proto_host",
- srcs: [
- "src/atoms.proto",
- "src/atom_field_options.proto",
- ],
-
- shared_libs: [
- "libplatformprotos",
- ],
-
- proto: {
- type: "full",
- export_proto_headers: true,
- include_dirs: [
- "external/protobuf/src",
- ],
- },
-
- export_shared_lib_headers: [
- "libplatformprotos",
- ]
-
-}
-
-cc_defaults {
- name: "statsd_defaults",
-
- srcs: [
- "src/active_config_list.proto",
- "src/anomaly/AlarmMonitor.cpp",
- "src/anomaly/AlarmTracker.cpp",
- "src/anomaly/AnomalyTracker.cpp",
- "src/anomaly/DurationAnomalyTracker.cpp",
- "src/anomaly/subscriber_util.cpp",
- "src/condition/CombinationConditionTracker.cpp",
- "src/condition/condition_util.cpp",
- "src/condition/ConditionWizard.cpp",
- "src/condition/SimpleConditionTracker.cpp",
- "src/config/ConfigKey.cpp",
- "src/config/ConfigListener.cpp",
- "src/config/ConfigManager.cpp",
- "src/experiment_ids.proto",
- "src/external/Perfetto.cpp",
- "src/external/PullResultReceiver.cpp",
- "src/external/puller_util.cpp",
- "src/external/StatsCallbackPuller.cpp",
- "src/external/StatsPuller.cpp",
- "src/external/StatsPullerManager.cpp",
- "src/external/TrainInfoPuller.cpp",
- "src/FieldValue.cpp",
- "src/guardrail/StatsdStats.cpp",
- "src/hash.cpp",
- "src/HashableDimensionKey.cpp",
- "src/logd/LogEvent.cpp",
- "src/logd/LogEventQueue.cpp",
- "src/matchers/CombinationLogMatchingTracker.cpp",
- "src/matchers/EventMatcherWizard.cpp",
- "src/matchers/matcher_util.cpp",
- "src/matchers/SimpleLogMatchingTracker.cpp",
- "src/metadata_util.cpp",
- "src/metrics/CountMetricProducer.cpp",
- "src/metrics/duration_helper/MaxDurationTracker.cpp",
- "src/metrics/duration_helper/OringDurationTracker.cpp",
- "src/metrics/DurationMetricProducer.cpp",
- "src/metrics/EventMetricProducer.cpp",
- "src/metrics/GaugeMetricProducer.cpp",
- "src/metrics/MetricProducer.cpp",
- "src/metrics/metrics_manager_util.cpp",
- "src/metrics/MetricsManager.cpp",
- "src/metrics/ValueMetricProducer.cpp",
- "src/packages/UidMap.cpp",
- "src/shell/shell_config.proto",
- "src/shell/ShellSubscriber.cpp",
- "src/socket/StatsSocketListener.cpp",
- "src/state/StateManager.cpp",
- "src/state/StateTracker.cpp",
- "src/stats_log_util.cpp",
- "src/statscompanion_util.cpp",
- "src/statsd_config.proto",
- "src/statsd_metadata.proto",
- "src/StatsLogProcessor.cpp",
- "src/StatsService.cpp",
- "src/storage/StorageManager.cpp",
- "src/subscriber/IncidentdReporter.cpp",
- "src/subscriber/SubscriberReporter.cpp",
- "src/uid_data.proto",
- "src/utils/MultiConditionTrigger.cpp",
- ],
-
- local_include_dirs: [
- "src",
- ],
-
- static_libs: [
- "libbase",
- "libcutils",
- "libgtest_prod",
- "libprotoutil",
- "libstatslog_statsd",
- "libsysutils",
- "libutils",
- "statsd-aidl-ndk_platform",
- ],
- shared_libs: [
- "libbinder_ndk",
- "libincident",
- "liblog",
- ],
-}
-
-genrule {
- name: "statslog_statsd.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsd.h --module statsd --namespace android,os,statsd,util",
- out: [
- "statslog_statsd.h",
- ],
-}
-
-genrule {
- name: "statslog_statsd.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsd.cpp --module statsd --namespace android,os,statsd,util --importHeader statslog_statsd.h",
- out: [
- "statslog_statsd.cpp",
- ],
-}
-
-genrule {
- name: "statslog_statsdtest.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsdtest.h --module statsdtest --namespace android,os,statsd,util",
- out: [
- "statslog_statsdtest.h",
- ],
-}
-
-genrule {
- name: "statslog_statsdtest.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsdtest.cpp --module statsdtest --namespace android,os,statsd,util --importHeader statslog_statsdtest.h",
- out: [
- "statslog_statsdtest.cpp",
- ],
-}
-
-cc_library_static {
- name: "libstatslog_statsdtest",
- generated_sources: ["statslog_statsdtest.cpp"],
- generated_headers: ["statslog_statsdtest.h"],
- export_generated_headers: ["statslog_statsdtest.h"],
- shared_libs: [
- "libstatssocket",
- ]
-}
-
-cc_library_static {
- name: "libstatslog_statsd",
- generated_sources: ["statslog_statsd.cpp"],
- generated_headers: ["statslog_statsd.h"],
- export_generated_headers: ["statslog_statsd.h"],
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
- shared_libs: [
- "libstatssocket",
- ]
-}
-
-// =========
-// statsd
-// =========
-
-cc_binary {
- name: "statsd",
- defaults: ["statsd_defaults"],
-
- srcs: ["src/main.cpp"],
-
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wno-unused-parameter",
- // optimize for size (protobuf glop can get big)
- "-Os",
- // "-g",
- // "-O0",
- ],
-
- product_variables: {
- eng: {
- // Enable sanitizer ONLY on eng builds
- //sanitize: {
- // address: true,
- //},
- },
- },
-
- proto: {
- type: "lite",
- static: true,
- },
- stl: "libc++_static",
-
- shared_libs: [
- "libstatssocket",
- ],
-
- apex_available: [
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
-
-// ==============
-// statsd_test
-// ==============
-
-cc_test {
- name: "statsd_test",
- defaults: ["statsd_defaults"],
- test_suites: ["device-tests", "mts"],
- test_config: "statsd_test.xml",
-
- //TODO(b/153588990): Remove when the build system properly separates
- //32bit and 64bit architectures.
- compile_multilib: "both",
- multilib: {
- lib64: {
- suffix: "64",
- },
- lib32: {
- suffix: "32",
- },
- },
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-missing-field-initializers",
- "-Wno-unused-variable",
- "-Wno-unused-function",
- "-Wno-unused-parameter",
- ],
-
- require_root: true,
-
- srcs: [
- // atom_field_options.proto needs field_options.proto, but that is
- // not included in libprotobuf-cpp-lite, so compile it here.
- ":libprotobuf-internal-protos",
-
- "src/atom_field_options.proto",
- "src/atoms.proto",
- "src/shell/shell_data.proto",
- "src/stats_log.proto",
- "tests/AlarmMonitor_test.cpp",
- "tests/anomaly/AlarmTracker_test.cpp",
- "tests/anomaly/AnomalyTracker_test.cpp",
- "tests/condition/CombinationConditionTracker_test.cpp",
- "tests/condition/ConditionTimer_test.cpp",
- "tests/condition/SimpleConditionTracker_test.cpp",
- "tests/ConfigManager_test.cpp",
- "tests/e2e/Alarm_e2e_test.cpp",
- "tests/e2e/Anomaly_count_e2e_test.cpp",
- "tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
- "tests/e2e/Attribution_e2e_test.cpp",
- "tests/e2e/ConfigTtl_e2e_test.cpp",
- "tests/e2e/CountMetric_e2e_test.cpp",
- "tests/e2e/DurationMetric_e2e_test.cpp",
- "tests/e2e/GaugeMetric_e2e_pull_test.cpp",
- "tests/e2e/GaugeMetric_e2e_push_test.cpp",
- "tests/e2e/MetricActivation_e2e_test.cpp",
- "tests/e2e/MetricConditionLink_e2e_test.cpp",
- "tests/e2e/PartialBucket_e2e_test.cpp",
- "tests/e2e/ValueMetric_pull_e2e_test.cpp",
- "tests/e2e/WakelockDuration_e2e_test.cpp",
- "tests/external/puller_util_test.cpp",
- "tests/external/StatsCallbackPuller_test.cpp",
- "tests/external/StatsPuller_test.cpp",
- "tests/external/StatsPullerManager_test.cpp",
- "tests/FieldValue_test.cpp",
- "tests/guardrail/StatsdStats_test.cpp",
- "tests/HashableDimensionKey_test.cpp",
- "tests/indexed_priority_queue_test.cpp",
- "tests/log_event/LogEventQueue_test.cpp",
- "tests/LogEntryMatcher_test.cpp",
- "tests/LogEvent_test.cpp",
- "tests/metadata_util_test.cpp",
- "tests/metrics/CountMetricProducer_test.cpp",
- "tests/metrics/DurationMetricProducer_test.cpp",
- "tests/metrics/EventMetricProducer_test.cpp",
- "tests/metrics/GaugeMetricProducer_test.cpp",
- "tests/metrics/MaxDurationTracker_test.cpp",
- "tests/metrics/metrics_test_helper.cpp",
- "tests/metrics/OringDurationTracker_test.cpp",
- "tests/metrics/ValueMetricProducer_test.cpp",
- "tests/MetricsManager_test.cpp",
- "tests/shell/ShellSubscriber_test.cpp",
- "tests/state/StateTracker_test.cpp",
- "tests/statsd_test_util.cpp",
- "tests/StatsLogProcessor_test.cpp",
- "tests/StatsService_test.cpp",
- "tests/storage/StorageManager_test.cpp",
- "tests/UidMap_test.cpp",
- "tests/utils/MultiConditionTrigger_test.cpp",
- ],
-
- static_libs: [
- "libgmock",
- "libplatformprotos",
- "libstatslog_statsdtest",
- "libstatssocket_private",
- ],
-
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
-}
-
-//#############################
-// statsd micro benchmark
-//#############################
-
-cc_benchmark {
- name: "statsd_benchmark",
- defaults: ["statsd_defaults"],
-
- srcs: [
- // atom_field_options.proto needs field_options.proto, but that is
- // not included in libprotobuf-cpp-lite, so compile it here.
- ":libprotobuf-internal-protos",
-
- "benchmark/duration_metric_benchmark.cpp",
- "benchmark/filter_value_benchmark.cpp",
- "benchmark/get_dimensions_for_condition_benchmark.cpp",
- "benchmark/hello_world_benchmark.cpp",
- "benchmark/log_event_benchmark.cpp",
- "benchmark/main.cpp",
- "benchmark/metric_util.cpp",
- "benchmark/stats_write_benchmark.cpp",
- "src/atom_field_options.proto",
- "src/atoms.proto",
- "src/stats_log.proto",
- ],
-
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wno-unused-variable",
- "-Wno-unused-function",
-
- // Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
- "-Wno-varargs",
- ],
-
- static_libs: [
- "libplatformprotos",
- "libstatssocket_private",
- ],
-
- shared_libs: [
- "libgtest_prod",
- "libprotobuf-cpp-lite",
- "libstatslog",
- ],
-}
-
-// ==== java proto device library (for test only) ==============================
-java_library {
- name: "statsdprotolite",
- sdk_version: "core_current",
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- srcs: [
- "src/atoms.proto",
- "src/shell/shell_config.proto",
- "src/shell/shell_data.proto",
- "src/stats_log.proto",
- "src/statsd_config.proto",
- ],
-
- static_libs: [
- "platformprotoslite",
- ],
- // Protos have lots of MissingOverride and similar.
- errorprone: {
- javacflags: ["-XepDisableAllChecks"],
- },
-}
-
-// Filegroup for statsd config proto definition.
-filegroup {
- name: "statsd-config-proto-def",
- srcs: ["src/statsd_config.proto"],
-}
diff --git a/cmds/statsd/OWNERS b/cmds/statsd/OWNERS
deleted file mode 100644
index a61babf32e58..000000000000
--- a/cmds/statsd/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-jeffreyhuang@google.com
-joeo@google.com
-jtnguyen@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
diff --git a/cmds/statsd/TEST_MAPPING b/cmds/statsd/TEST_MAPPING
deleted file mode 100644
index 8dee073aca22..000000000000
--- a/cmds/statsd/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "presubmit" : [
- {
- "name" : "statsd_test"
- }
- ]
-} \ No newline at end of file
diff --git a/cmds/statsd/benchmark/duration_metric_benchmark.cpp b/cmds/statsd/benchmark/duration_metric_benchmark.cpp
deleted file mode 100644
index 2d315d9395bc..000000000000
--- a/cmds/statsd/benchmark/duration_metric_benchmark.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-#include "benchmark/benchmark.h"
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-#include "metric_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static StatsdConfig CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensions->add_child()->set_field(2); // job name field.
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
- {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- auto dimensionWhat = metric->mutable_dimensions_in_what();
- dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(2); // job name field.
- *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-static StatsdConfig CreateDurationMetricConfig_Link_AND_CombinationCondition(
- DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
- StatsdConfig config;
- *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto scheduledJobPredicate = CreateScheduledJobPredicate();
- auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
- *dimensions = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- dimensions->add_child()->set_field(2); // job name field.
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- if (addExtraDimensionInCondition) {
- syncDimension->add_child()->set_field(2 /* name field*/);
- }
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- *config.add_predicate() = scheduledJobPredicate;
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("CombinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
- auto metric = config.add_duration_metric();
- metric->set_bucket(FIVE_MINUTES);
- metric->set_id(StringToId("scheduledJob"));
- metric->set_what(scheduledJobPredicate.id());
- metric->set_condition(combinationPredicate->id());
- metric->set_aggregation_type(aggregationType);
- *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-
- auto links = metric->add_links();
- links->set_condition(isSyncingPredicate.id());
- *links->mutable_fields_in_what() =
- CreateAttributionUidDimensions(
- android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
- *links->mutable_fields_in_condition() =
- CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
- return config;
-}
-
-static void BM_DurationMetricNoLink(benchmark::State& state) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
- DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 11,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(
- CreateScreenStateChangedEvent(bucketStartTimeNs + 40, android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 102,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 450,
- android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 650,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 640,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 650,
- android::view::DISPLAY_STATE_ON));
-
- vector<int> attributionUids1 = {9999};
- vector<string> attributionTags1 = {""};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "job0"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 101, attributionUids1,
- attributionTags1, "job0"));
-
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 201, attributionUids1,
- attributionTags1, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 500, attributionUids1,
- attributionTags1, "job2"));
-
- vector<int> attributionUids2 = {8888};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 600, attributionUids2,
- attributionTags1, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 850,
- attributionUids2, attributionTags1, "job2"));
-
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 600,
- attributionUids2, attributionTags1, "job1"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 900,
- attributionUids2, attributionTags1, "job1"));
-
- vector<int> attributionUids3 = {111, 222, 222};
- vector<string> attributionTags3 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 10, attributionUids3,
- attributionTags3, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 50, attributionUids3, attributionTags3,
- "ReadEmail"));
-
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200, attributionUids3,
- attributionTags3, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids3,
- attributionTags3, "ReadEmail"));
-
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400, attributionUids3,
- attributionTags3, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids3,
- attributionTags3, "ReadDoc"));
-
- vector<int> attributionUids4 = {333, 222, 555};
- vector<string> attributionTags4 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 401, attributionUids4,
- attributionTags4, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids4,
- attributionTags4, "ReadEmail"));
- sortLogEventsByTimestamp(&events);
-
- while (state.KeepRunning()) {
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- }
-}
-
-BENCHMARK(BM_DurationMetricNoLink);
-
-
-static void BM_DurationMetricLink(benchmark::State& state) {
- ConfigKey cfgKey;
- auto config = CreateDurationMetricConfig_Link_AND_CombinationCondition(
- DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 55,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 120,
- android::view::DISPLAY_STATE_ON));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 121,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 450,
- android::view::DISPLAY_STATE_ON));
-
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 501,
- android::view::DISPLAY_STATE_OFF));
- events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_ON));
-
- vector<int> attributionUids1 = {111};
- vector<string> attributionTags1 = {"App1"};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 1, attributionUids1,
- attributionTags1, "job1"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 101, attributionUids1,
- attributionTags1, "job1"));
-
- vector<int> attributionUids2 = {333};
- vector<string> attributionTags2 = {"App2"};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 201, attributionUids2,
- attributionTags2, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 500, attributionUids2,
- attributionTags2, "job2"));
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 600, attributionUids2,
- attributionTags2, "job2"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 850,
- attributionUids2, attributionTags2, "job2"));
-
- vector<int> attributionUids3 = {444};
- vector<string> attributionTags3 = {"App3"};
- events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + bucketSizeNs - 2,
- attributionUids3, attributionTags3, "job3"));
- events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 900,
- attributionUids3, attributionTags3, "job3"));
-
- vector<int> attributionUids4 = {111, 222, 222};
- vector<string> attributionTags4 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids4,
- attributionTags4, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 110, attributionUids4, attributionTags4,
- "ReadEmail"));
-
- vector<int> attributionUids5 = {333, 222, 555};
- vector<string> attributionTags5 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 300, attributionUids5,
- attributionTags5, "ReadEmail"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids5,
- attributionTags5, "ReadEmail"));
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400, attributionUids5,
- attributionTags5, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids5,
- attributionTags5, "ReadDoc"));
-
- vector<int> attributionUids6 = {444, 222, 555};
- vector<string> attributionTags6 = {"App3", "GMSCoreModule1", "GMSCoreModule2"};
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 550, attributionUids6,
- attributionTags6, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 800, attributionUids6, attributionTags6,
- "ReadDoc"));
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids6,
- attributionTags6, "ReadDoc"));
- events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids6,
- attributionTags6, "ReadDoc"));
- sortLogEventsByTimestamp(&events);
-
- while (state.KeepRunning()) {
- auto processor = CreateStatsLogProcessor(
- bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- }
-}
-
-BENCHMARK(BM_DurationMetricLink);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/filter_value_benchmark.cpp b/cmds/statsd/benchmark/filter_value_benchmark.cpp
deleted file mode 100644
index 743ccc4ed451..000000000000
--- a/cmds/statsd/benchmark/filter_value_benchmark.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "metric_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static void createLogEventAndMatcher(LogEvent* event, FieldMatcher* field_matcher) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 1);
- AStatsEvent_overwriteTimestamp(statsEvent, 100000);
-
- std::vector<int> attributionUids = {100, 100};
- std::vector<string> attributionTags = {"LOCATION", "LOCATION"};
- writeAttribution(statsEvent, attributionUids, attributionTags);
-
- AStatsEvent_writeFloat(statsEvent, 3.2f);
- AStatsEvent_writeString(statsEvent, "LOCATION");
- AStatsEvent_writeInt64(statsEvent, 990);
-
- parseStatsEventToLogEvent(statsEvent, event);
-
- field_matcher->set_field(1);
- auto child = field_matcher->add_child();
- child->set_field(1);
- child->set_position(FIRST);
- child->add_child()->set_field(1);
-}
-
-static void BM_FilterValue(benchmark::State& state) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- FieldMatcher field_matcher;
- createLogEventAndMatcher(&event, &field_matcher);
-
- std::vector<Matcher> matchers;
- translateFieldMatcher(field_matcher, &matchers);
-
- while (state.KeepRunning()) {
- HashableDimensionKey output;
- filterValues(matchers, event.getValues(), &output);
- }
-}
-
-BENCHMARK(BM_FilterValue);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp b/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp
deleted file mode 100644
index 7a455650a31b..000000000000
--- a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "metric_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static void createLogEventAndLink(LogEvent* event, Metric2Condition *link) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 1);
- AStatsEvent_overwriteTimestamp(statsEvent, 100000);
-
- std::vector<int> attributionUids = {100, 100};
- std::vector<string> attributionTags = {"LOCATION", "LOCATION"};
- writeAttribution(statsEvent, attributionUids, attributionTags);
-
- AStatsEvent_writeFloat(statsEvent, 3.2f);
- AStatsEvent_writeString(statsEvent, "LOCATION");
- AStatsEvent_writeInt64(statsEvent, 990);
-
- parseStatsEventToLogEvent(statsEvent, event);
-
- link->conditionId = 1;
-
- FieldMatcher field_matcher;
- field_matcher.set_field(event->GetTagId());
- auto child = field_matcher.add_child();
- child->set_field(1);
- child->set_position(FIRST);
- child->add_child()->set_field(1);
-
- translateFieldMatcher(field_matcher, &link->metricFields);
- field_matcher.set_field(event->GetTagId() + 1);
- translateFieldMatcher(field_matcher, &link->conditionFields);
-}
-
-static void BM_GetDimensionInCondition(benchmark::State& state) {
- Metric2Condition link;
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createLogEventAndLink(&event, &link);
-
- while (state.KeepRunning()) {
- HashableDimensionKey output;
- getDimensionForCondition(event.getValues(), link, &output);
- }
-}
-
-BENCHMARK(BM_GetDimensionInCondition);
-
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/hello_world_benchmark.cpp b/cmds/statsd/benchmark/hello_world_benchmark.cpp
deleted file mode 100644
index c732d394bf64..000000000000
--- a/cmds/statsd/benchmark/hello_world_benchmark.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "benchmark/benchmark.h"
-
-static void BM_StringCreation(benchmark::State& state) {
- while (state.KeepRunning()) std::string empty_string;
-}
-// Register the function as a benchmark
-BENCHMARK(BM_StringCreation);
-
-// Define another benchmark
-static void BM_StringCopy(benchmark::State& state) {
- std::string x = "hello";
- while (state.KeepRunning()) std::string copy(x);
-}
-BENCHMARK(BM_StringCopy);
diff --git a/cmds/statsd/benchmark/log_event_benchmark.cpp b/cmds/statsd/benchmark/log_event_benchmark.cpp
deleted file mode 100644
index 057e00bde202..000000000000
--- a/cmds/statsd/benchmark/log_event_benchmark.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "stats_event.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static size_t createAndParseStatsEvent(uint8_t* msg) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- AStatsEvent_writeInt32(event, 2);
- AStatsEvent_writeFloat(event, 2.0);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
- memcpy(msg, buf, size);
- return size;
-}
-
-static void BM_LogEventCreation(benchmark::State& state) {
- uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
- size_t size = createAndParseStatsEvent(msg);
- while (state.KeepRunning()) {
- LogEvent event(/*uid=*/ 1000, /*pid=*/ 1001);
- benchmark::DoNotOptimize(event.parseBuffer(msg, size));
- }
-}
-BENCHMARK(BM_LogEventCreation);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/main.cpp b/cmds/statsd/benchmark/main.cpp
deleted file mode 100644
index 08921f3c3f52..000000000000
--- a/cmds/statsd/benchmark/main.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <benchmark/benchmark.h>
-
-BENCHMARK_MAIN();
diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp
deleted file mode 100644
index 89fd3d9b29ab..000000000000
--- a/cmds/statsd/benchmark/metric_util.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "metric_util.h"
-
-#include "stats_event.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(atomId);
- return atom_matcher;
-}
-
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
- ScheduledJobStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateStartScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
- ScheduledJobStateChanged::STARTED);
-}
-
-AtomMatcher CreateFinishScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
- ScheduledJobStateChanged::FINISHED);
-}
-
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("UidProcessStateChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
- WakelockStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateAcquireWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
-}
-
-AtomMatcher CreateReleaseWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
-}
-
-AtomMatcher CreateScreenStateChangedAtomMatcher(
- const string& name, android::view::DisplayStateEnum state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateScreenTurnedOnAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-AtomMatcher CreateScreenTurnedOffAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
- ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-}
-
-AtomMatcher CreateSyncStateChangedAtomMatcher(
- const string& name, SyncStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateSyncStartAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
-}
-
-AtomMatcher CreateSyncEndAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
-}
-
-AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
- const string& name, ActivityForegroundStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // Activity field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateMoveToBackgroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToBackground", ActivityForegroundStateChanged::BACKGROUND);
-}
-
-AtomMatcher CreateMoveToForegroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "MoveToForeground", ActivityForegroundStateChanged::FOREGROUND);
-}
-
-Predicate CreateScheduledJobPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
- return predicate;
-}
-
-Predicate CreateBatterySaverModePredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("BatterySaverIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
- return predicate;
-}
-
-Predicate CreateScreenIsOnPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScreenIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
- return predicate;
-}
-
-Predicate CreateScreenIsOffPredicate() {
- Predicate predicate;
- predicate.set_id(1111123);
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
- return predicate;
-}
-
-Predicate CreateHoldingWakelockPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("HoldingWakelock"));
- predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
- return predicate;
-}
-
-Predicate CreateIsSyncingPredicate() {
- Predicate predicate;
- predicate.set_id(33333333333333);
- predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
- return predicate;
-}
-
-Predicate CreateIsInBackgroundPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("IsInBackground"));
- predicate.mutable_simple_predicate()->set_start(StringToId("MoveToBackground"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("MoveToForeground"));
- return predicate;
-}
-
-void addPredicateToPredicateCombination(const Predicate& predicate,
- Predicate* combinationPredicate) {
- combinationPredicate->mutable_combination()->add_predicate(predicate.id());
-}
-
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- }
- return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
- }
- return dimensions;
-}
-
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const int field : fields) {
- dimensions.add_child()->set_field(field);
- }
- return dimensions;
-}
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags) {
- vector<const char*> cTags(attributionTags.size());
- for (int i = 0; i < cTags.size(); i++) {
- cTags[i] = attributionTags[i].c_str();
- }
-
- AStatsEvent_writeAttributionChain(statsEvent,
- reinterpret_cast<const uint32_t*>(attributionUids.data()),
- cTags.data(), attributionUids.size());
-}
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- logEvent->parseBuffer(buf, size);
-
- AStatsEvent_release(statsEvent);
-}
-
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
- uint64_t timestampNs, const android::view::DisplayStateEnum state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, jobName.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::STARTED, timestampNs);
-}
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::FINISHED, timestampNs);
-}
-
-std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name,
- const SyncStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::ON);
-}
-
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::OFF);
-}
-
-sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
- const ConfigKey& key) {
- sp<UidMap> uidMap = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- sp<StatsLogProcessor> processor =
- new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec * NS_PER_SEC, [](const ConfigKey&) { return true; },
- [](const int&, const vector<int64_t>&) { return true; });
- processor->OnConfigUpdated(timeBaseSec * NS_PER_SEC, key, config);
- return processor;
-}
-
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
- std::sort(events->begin(), events->end(),
- [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
- return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
- });
-}
-
-int64_t StringToId(const string& str) {
- return static_cast<int64_t>(std::hash<std::string>()(str));
-}
-
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/metric_util.h b/cmds/statsd/benchmark/metric_util.h
deleted file mode 100644
index 3efaa850a921..000000000000
--- a/cmds/statsd/benchmark/metric_util.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/logd/LogEvent.h"
-#include "stats_event.h"
-#include "statslog.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Create AtomMatcher proto to simply match a specific atom type.
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
-
-// Create AtomMatcher proto for scheduled job state changed.
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting a scheduled job.
-AtomMatcher CreateStartScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for a scheduled job is done.
-AtomMatcher CreateFinishScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for screen brightness state changed.
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
-
-// Create AtomMatcher proto for acquiring wakelock.
-AtomMatcher CreateAcquireWakelockAtomMatcher();
-
-// Create AtomMatcher proto for releasing wakelock.
-AtomMatcher CreateReleaseWakelockAtomMatcher() ;
-
-// Create AtomMatcher proto for screen turned on.
-AtomMatcher CreateScreenTurnedOnAtomMatcher();
-
-// Create AtomMatcher proto for screen turned off.
-AtomMatcher CreateScreenTurnedOffAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned on.
-AtomMatcher CreateSyncStartAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned off.
-AtomMatcher CreateSyncEndAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to background.
-AtomMatcher CreateMoveToBackgroundAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to foreground.
-AtomMatcher CreateMoveToForegroundAtomMatcher();
-
-// Create Predicate proto for screen is off.
-Predicate CreateScreenIsOffPredicate();
-
-// Create Predicate proto for a running scheduled job.
-Predicate CreateScheduledJobPredicate();
-
-// Create Predicate proto for holding wakelock.
-Predicate CreateHoldingWakelockPredicate();
-
-// Create a Predicate proto for app syncing.
-Predicate CreateIsSyncingPredicate();
-
-// Create a Predicate proto for app is in background.
-Predicate CreateIsInBackgroundPredicate();
-
-// Add a predicate to the predicate combination.
-void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
-
-// Create dimensions from primitive fields.
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
-
-// Create dimensions by attribution uid and tag.
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-// Create dimensions by attribution uid only.
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags);
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
-
-// Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
- uint64_t timestampNs, const android::view::DisplayStateEnum state);
-
-// Create log event when scheduled job starts.
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when the app sync starts.
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name);
-
-// Create a statsd log event processor upon the start time in seconds, config and key.
-sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
- const ConfigKey& key);
-
-// Util function to sort the log events by timestamp.
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
-
-int64_t StringToId(const string& str);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/benchmark/stats_write_benchmark.cpp b/cmds/statsd/benchmark/stats_write_benchmark.cpp
deleted file mode 100644
index f5a0cd5dfb39..000000000000
--- a/cmds/statsd/benchmark/stats_write_benchmark.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "benchmark/benchmark.h"
-#include <statslog.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static void BM_StatsWrite(benchmark::State& state) {
- const char* reason = "test";
- int64_t boot_end_time = 1234567;
- int64_t total_duration = 100;
- int64_t bootloader_duration = 10;
- int64_t time_since_last_boot = 99999999;
- while (state.KeepRunning()) {
- android::util::stats_write(
- android::util::BOOT_SEQUENCE_REPORTED, reason, reason,
- boot_end_time, total_duration, bootloader_duration, time_since_last_boot);
- total_duration++;
- }
-}
-BENCHMARK(BM_StatsWrite);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
deleted file mode 100644
index c9ccfb93c86d..000000000000
--- a/cmds/statsd/src/FieldValue.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-#include "Log.h"
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "math.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
- int32_t field = 0;
- for (int32_t i = 0; i <= depth; i++) {
- int32_t shiftBits = 8 * (kMaxLogDepth - i);
- field |= (pos[i] << shiftBits);
- }
-
- if (includeDepth) {
- field |= (depth << 24);
- }
- return field;
-}
-
-int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
- return getEncodedField(mask, depth, false) | 0xff000000;
-}
-
-bool Field::matches(const Matcher& matcher) const {
- if (mTag != matcher.mMatcher.getTag()) {
- return false;
- }
- if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
- return true;
- }
-
- if (matcher.hasAllPositionMatcher() &&
- (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
- return true;
- }
-
- return false;
-}
-
-void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
- std::vector<Matcher>* output) {
- if (depth > kMaxLogDepth) {
- ALOGE("depth > 2");
- return;
- }
-
- pos[depth] = matcher.field();
- mask[depth] = 0x7f;
-
- if (matcher.has_position()) {
- depth++;
- if (depth > 2) {
- return;
- }
- switch (matcher.position()) {
- case Position::ALL:
- pos[depth] = 0x00;
- mask[depth] = 0x7f;
- break;
- case Position::ANY:
- pos[depth] = 0;
- mask[depth] = 0;
- break;
- case Position::FIRST:
- pos[depth] = 1;
- mask[depth] = 0x7f;
- break;
- case Position::LAST:
- pos[depth] = 0x80;
- mask[depth] = 0x80;
- break;
- case Position::POSITION_UNKNOWN:
- pos[depth] = 0;
- mask[depth] = 0;
- break;
- }
- }
-
- if (matcher.child_size() == 0) {
- output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
- } else {
- for (const auto& child : matcher.child()) {
- translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
- }
- }
-}
-
-void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
- int pos[] = {1, 1, 1};
- int mask[] = {0x7f, 0x7f, 0x7f};
- int tag = matcher.field();
- for (const auto& child : matcher.child()) {
- translateFieldMatcher(tag, child, 0, pos, mask, output);
- }
-}
-
-bool isAttributionUidField(const FieldValue& value) {
- return isAttributionUidField(value.mField, value.mValue);
-}
-
-int32_t getUidIfExists(const FieldValue& value) {
- // the field is uid field if the field is the uid field in attribution node
- // or annotated as such in the atom
- bool isUid = isAttributionUidField(value) || isUidField(value);
- return isUid ? value.mValue.int_value : -1;
-}
-
-bool isAttributionUidField(const Field& field, const Value& value) {
- int f = field.getField() & 0xff007f;
- if (f == 0x10001 && value.getType() == INT) {
- return true;
- }
- return false;
-}
-
-bool isUidField(const FieldValue& fieldValue) {
- return fieldValue.mAnnotations.isUidField();
-}
-
-Value::Value(const Value& from) {
- type = from.getType();
- switch (type) {
- case INT:
- int_value = from.int_value;
- break;
- case LONG:
- long_value = from.long_value;
- break;
- case FLOAT:
- float_value = from.float_value;
- break;
- case DOUBLE:
- double_value = from.double_value;
- break;
- case STRING:
- str_value = from.str_value;
- break;
- case STORAGE:
- storage_value = from.storage_value;
- break;
- default:
- break;
- }
-}
-
-std::string Value::toString() const {
- switch (type) {
- case INT:
- return std::to_string(int_value) + "[I]";
- case LONG:
- return std::to_string(long_value) + "[L]";
- case FLOAT:
- return std::to_string(float_value) + "[F]";
- case DOUBLE:
- return std::to_string(double_value) + "[D]";
- case STRING:
- return str_value + "[S]";
- case STORAGE:
- return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
- default:
- return "[UNKNOWN]";
- }
-}
-
-bool Value::isZero() const {
- switch (type) {
- case INT:
- return int_value == 0;
- case LONG:
- return long_value == 0;
- case FLOAT:
- return fabs(float_value) <= std::numeric_limits<float>::epsilon();
- case DOUBLE:
- return fabs(double_value) <= std::numeric_limits<double>::epsilon();
- case STRING:
- return str_value.size() == 0;
- case STORAGE:
- return storage_value.size() == 0;
- default:
- return false;
- }
-}
-
-bool Value::operator==(const Value& that) const {
- if (type != that.getType()) return false;
-
- switch (type) {
- case INT:
- return int_value == that.int_value;
- case LONG:
- return long_value == that.long_value;
- case FLOAT:
- return float_value == that.float_value;
- case DOUBLE:
- return double_value == that.double_value;
- case STRING:
- return str_value == that.str_value;
- case STORAGE:
- return storage_value == that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator!=(const Value& that) const {
- if (type != that.getType()) return true;
- switch (type) {
- case INT:
- return int_value != that.int_value;
- case LONG:
- return long_value != that.long_value;
- case FLOAT:
- return float_value != that.float_value;
- case DOUBLE:
- return double_value != that.double_value;
- case STRING:
- return str_value != that.str_value;
- case STORAGE:
- return storage_value != that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator<(const Value& that) const {
- if (type != that.getType()) return type < that.getType();
-
- switch (type) {
- case INT:
- return int_value < that.int_value;
- case LONG:
- return long_value < that.long_value;
- case FLOAT:
- return float_value < that.float_value;
- case DOUBLE:
- return double_value < that.double_value;
- case STRING:
- return str_value < that.str_value;
- case STORAGE:
- return storage_value < that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator>(const Value& that) const {
- if (type != that.getType()) return type > that.getType();
-
- switch (type) {
- case INT:
- return int_value > that.int_value;
- case LONG:
- return long_value > that.long_value;
- case FLOAT:
- return float_value > that.float_value;
- case DOUBLE:
- return double_value > that.double_value;
- case STRING:
- return str_value > that.str_value;
- case STORAGE:
- return storage_value > that.storage_value;
- default:
- return false;
- }
-}
-
-bool Value::operator>=(const Value& that) const {
- if (type != that.getType()) return type >= that.getType();
-
- switch (type) {
- case INT:
- return int_value >= that.int_value;
- case LONG:
- return long_value >= that.long_value;
- case FLOAT:
- return float_value >= that.float_value;
- case DOUBLE:
- return double_value >= that.double_value;
- case STRING:
- return str_value >= that.str_value;
- case STORAGE:
- return storage_value >= that.storage_value;
- default:
- return false;
- }
-}
-
-Value Value::operator-(const Value& that) const {
- Value v;
- if (type != that.type) {
- ALOGE("Can't operate on different value types, %d, %d", type, that.type);
- return v;
- }
- if (type == STRING) {
- ALOGE("Can't operate on string value type");
- return v;
- }
-
- if (type == STORAGE) {
- ALOGE("Can't operate on storage value type");
- return v;
- }
-
- switch (type) {
- case INT:
- v.setInt(int_value - that.int_value);
- break;
- case LONG:
- v.setLong(long_value - that.long_value);
- break;
- case FLOAT:
- v.setFloat(float_value - that.float_value);
- break;
- case DOUBLE:
- v.setDouble(double_value - that.double_value);
- break;
- default:
- break;
- }
- return v;
-}
-
-Value& Value::operator=(const Value& that) {
- type = that.type;
- switch (type) {
- case INT:
- int_value = that.int_value;
- break;
- case LONG:
- long_value = that.long_value;
- break;
- case FLOAT:
- float_value = that.float_value;
- break;
- case DOUBLE:
- double_value = that.double_value;
- break;
- case STRING:
- str_value = that.str_value;
- break;
- case STORAGE:
- storage_value = that.storage_value;
- break;
- default:
- break;
- }
- return *this;
-}
-
-Value& Value::operator+=(const Value& that) {
- if (type != that.type) {
- ALOGE("Can't operate on different value types, %d, %d", type, that.type);
- return *this;
- }
- if (type == STRING) {
- ALOGE("Can't operate on string value type");
- return *this;
- }
- if (type == STORAGE) {
- ALOGE("Can't operate on storage value type");
- return *this;
- }
-
- switch (type) {
- case INT:
- int_value += that.int_value;
- break;
- case LONG:
- long_value += that.long_value;
- break;
- case FLOAT:
- float_value += that.float_value;
- break;
- case DOUBLE:
- double_value += that.double_value;
- break;
- default:
- break;
- }
- return *this;
-}
-
-double Value::getDouble() const {
- switch (type) {
- case INT:
- return int_value;
- case LONG:
- return long_value;
- case FLOAT:
- return float_value;
- case DOUBLE:
- return double_value;
- default:
- return 0;
- }
-}
-
-bool equalDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b) {
- bool eq = dimension_a.size() == dimension_b.size();
- for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
- if (dimension_b[i] != dimension_a[i]) {
- eq = false;
- }
- }
- return eq;
-}
-
-bool subsetDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b) {
- if (dimension_a.size() > dimension_b.size()) {
- return false;
- }
- for (size_t i = 0; i < dimension_a.size(); ++i) {
- bool found = false;
- for (size_t j = 0; j < dimension_b.size(); ++j) {
- if (dimension_a[i] == dimension_b[j]) {
- found = true;
- }
- }
- if (!found) {
- return false;
- }
- }
- return true;
-}
-
-bool HasPositionANY(const FieldMatcher& matcher) {
- if (matcher.has_position() && matcher.position() == Position::ANY) {
- return true;
- }
- for (const auto& child : matcher.child()) {
- if (HasPositionANY(child)) {
- return true;
- }
- }
- return false;
-}
-
-bool HasPositionALL(const FieldMatcher& matcher) {
- if (matcher.has_position() && matcher.position() == Position::ALL) {
- return true;
- }
- for (const auto& child : matcher.child()) {
- if (HasPositionALL(child)) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
deleted file mode 100644
index fd86e3683970..000000000000
--- a/cmds/statsd/src/FieldValue.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "annotations.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class HashableDimensionKey;
-struct Matcher;
-struct Field;
-struct FieldValue;
-
-const int32_t kMaxLogDepth = 2;
-const int32_t kLastBitMask = 0x80;
-const int32_t kClearLastBitDeco = 0x7f;
-const int32_t kClearAllPositionMatcherMask = 0xffff00ff;
-
-enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE };
-
-int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
-
-int32_t encodeMatcherMask(int32_t mask[], int32_t depth);
-
-// Get the encoded field for a leaf with a [field] number at depth 0;
-inline int32_t getSimpleField(size_t field) {
- return ((int32_t)field << 8 * 2);
-}
-
-/**
- * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
- * proto.
- * [mTag]: the atom id.
- * [mField]: encoded path from the root (atom) to leaf.
- *
- * For example:
- * WakeLockStateChanged {
- * repeated AttributionNode = 1;
- * int state = 2;
- * string tag = 3;
- * }
- * Read from logd, the items are structured as below:
- * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
- *
- * When we read through the list, we will encode each field in a 32bit integer.
- * 8bit segments |--------|--------|--------|--------|
- * Depth field0 [L]field1 [L]field1
- *
- * The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
- * The following 3 8-bit are for the item's position at each level.
- * The first bit of each 8bits field is reserved to mark if the item is the last item at that level
- * this is to make matching easier later.
- *
- * The above wakelock event is translated into FieldValue pairs.
- * 0x02010101->1000
- * 0x02010182->tag
- * 0x02018201->2000
- * 0x02018282->tag2
- * 0x00020000->2
- * 0x00030000->"hello"
- *
- * This encoding is the building block for the later operations.
- * Please see the definition for Matcher below to see how the matching is done.
- */
-struct Field {
-private:
- int32_t mTag;
- int32_t mField;
-
-public:
- Field() {}
-
- Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
- mField = getEncodedField(pos, depth, true);
- }
-
- Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
- }
-
- Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};
-
- inline void setField(int32_t field) {
- mField = field;
- }
-
- inline void setTag(int32_t tag) {
- mTag = tag;
- }
-
- inline void decorateLastPos(int32_t depth) {
- int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
- mField |= mask;
- }
-
- inline int32_t getTag() const {
- return mTag;
- }
-
- inline int32_t getDepth() const {
- return (mField >> 24);
- }
-
- inline int32_t getPath(int32_t depth) const {
- if (depth > 2 || depth < 0) return 0;
-
- int32_t field = (mField & 0x00ffffff);
- int32_t mask = 0xffffffff;
- return (field & (mask << 8 * (kMaxLogDepth - depth)));
- }
-
- inline int32_t getPrefix(int32_t depth) const {
- if (depth == 0) return 0;
- return getPath(depth - 1);
- }
-
- inline int32_t getField() const {
- return mField;
- }
-
- inline int32_t getRawPosAtDepth(int32_t depth) const {
- int32_t field = (mField & 0x00ffffff);
- int32_t shift = 8 * (kMaxLogDepth - depth);
- int32_t mask = 0xff << shift;
-
- return (field & mask) >> shift;
- }
-
- inline int32_t getPosAtDepth(int32_t depth) const {
- return getRawPosAtDepth(depth) & kClearLastBitDeco;
- }
-
- // Check if the first bit of the 8-bit segment for depth is 1
- inline bool isLastPos(int32_t depth) const {
- int32_t field = (mField & 0x00ffffff);
- int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
- return (field & mask) != 0;
- }
-
- // if the 8-bit segment is all 0's
- inline bool isAnyPosMatcher(int32_t depth) const {
- return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
- }
- // if the 8bit is 0x80 (1000 0000)
- inline bool isLastPosMatcher(int32_t depth) const {
- return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
- }
-
- inline bool operator==(const Field& that) const {
- return mTag == that.getTag() && mField == that.getField();
- };
-
- inline bool operator!=(const Field& that) const {
- return mTag != that.getTag() || mField != that.getField();
- };
-
- bool operator<(const Field& that) const {
- if (mTag != that.getTag()) {
- return mTag < that.getTag();
- }
-
- if (mField != that.getField()) {
- return mField < that.getField();
- }
-
- return false;
- }
-
- bool matches(const Matcher& that) const;
-};
-
-/**
- * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
- *
- * It contains all information needed to match one or more leaf node.
- * All information is encoded in a Field(2 ints) and a bit mask(1 int).
- *
- * For example, to match the first/any/last uid field in attribution chain in Atom 10,
- * we have the following FieldMatcher in statsd_config
- * FieldMatcher {
- * field:10
- * FieldMatcher {
- * field:1
- * position: any/last/first
- * FieldMatcher {
- * field:1
- * }
- * }
- * }
- *
- * We translate the FieldMatcher into a Field, and mask
- * First: [Matcher Field] 0x02010101 [Mask]0xff7f7f7f
- * Last: [Matcher Field] 0x02018001 [Mask]0xff7f807f
- * Any: [Matcher Field] 0x02010001 [Mask]0xff7f007f
- * All: [Matcher Field] 0x02010001 [Mask]0xff7f7f7f
- *
- * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
- * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
- * equal. Nothing can beat the performance of this matching algorithm.
- *
- * TODO(b/110561213): ADD EXAMPLE HERE.
- */
-struct Matcher {
- Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
-
- const Field mMatcher;
- const int32_t mMask;
-
- inline const Field& getMatcher() const {
- return mMatcher;
- }
-
- inline int32_t getMask() const {
- return mMask;
- }
-
- inline int32_t getRawMaskAtDepth(int32_t depth) const {
- int32_t field = (mMask & 0x00ffffff);
- int32_t shift = 8 * (kMaxLogDepth - depth);
- int32_t mask = 0xff << shift;
-
- return (field & mask) >> shift;
- }
-
- bool hasAllPositionMatcher() const {
- return mMatcher.getDepth() == 2 && getRawMaskAtDepth(1) == 0x7f;
- }
-
- bool hasAnyPositionMatcher(int* prefix) const {
- if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(1) == 0) {
- (*prefix) = mMatcher.getPrefix(1);
- return true;
- }
- return false;
- }
-
- inline bool operator!=(const Matcher& that) const {
- return mMatcher != that.getMatcher() || mMask != that.getMask();
- }
-
- inline bool operator==(const Matcher& that) const {
- return mMatcher == that.mMatcher && mMask == that.mMask;
- }
-};
-
-inline Matcher getSimpleMatcher(int32_t tag, size_t field) {
- return Matcher(Field(tag, getSimpleField(field)), 0xff7f0000);
-}
-
-inline Matcher getFirstUidMatcher(int32_t atomId) {
- int32_t pos[] = {1, 1, 1};
- return Matcher(Field(atomId, pos, 2), 0xff7f7f7f);
-}
-
-/**
- * A wrapper for a union type to contain multiple types of values.
- *
- */
-struct Value {
- Value() : type(UNKNOWN) {}
-
- Value(int32_t v) {
- int_value = v;
- type = INT;
- }
-
- Value(int64_t v) {
- long_value = v;
- type = LONG;
- }
-
- Value(float v) {
- float_value = v;
- type = FLOAT;
- }
-
- Value(double v) {
- double_value = v;
- type = DOUBLE;
- }
-
- Value(const std::string& v) {
- str_value = v;
- type = STRING;
- }
-
- Value(const std::vector<uint8_t>& v) {
- storage_value = v;
- type = STORAGE;
- }
-
- void setInt(int32_t v) {
- int_value = v;
- type = INT;
- }
-
- void setLong(int64_t v) {
- long_value = v;
- type = LONG;
- }
-
- void setFloat(float v) {
- float_value = v;
- type = FLOAT;
- }
-
- void setDouble(double v) {
- double_value = v;
- type = DOUBLE;
- }
-
- union {
- int32_t int_value;
- int64_t long_value;
- float float_value;
- double double_value;
- };
- std::string str_value;
- std::vector<uint8_t> storage_value;
-
- Type type;
-
- std::string toString() const;
-
- bool isZero() const;
-
- Type getType() const {
- return type;
- }
-
- double getDouble() const;
-
- Value(const Value& from);
-
- bool operator==(const Value& that) const;
- bool operator!=(const Value& that) const;
-
- bool operator<(const Value& that) const;
- bool operator>(const Value& that) const;
- bool operator>=(const Value& that) const;
- Value operator-(const Value& that) const;
- Value& operator+=(const Value& that);
- Value& operator=(const Value& that);
-};
-
-class Annotations {
-public:
- Annotations() {
- setNested(true); // Nested = true by default
- }
-
- // This enum stores where particular annotations can be found in the
- // bitmask. Note that these pos do not correspond to annotation ids.
- enum {
- NESTED_POS = 0x0,
- PRIMARY_POS = 0x1,
- EXCLUSIVE_POS = 0x2,
- UID_POS = 0x3
- };
-
- inline void setNested(bool nested) { setBitmaskAtPos(NESTED_POS, nested); }
-
- inline void setPrimaryField(bool primary) { setBitmaskAtPos(PRIMARY_POS, primary); }
-
- inline void setExclusiveState(bool exclusive) { setBitmaskAtPos(EXCLUSIVE_POS, exclusive); }
-
- inline void setUidField(bool isUid) { setBitmaskAtPos(UID_POS, isUid); }
-
- // Default value = false
- inline bool isNested() const { return getValueFromBitmask(NESTED_POS); }
-
- // Default value = false
- inline bool isPrimaryField() const { return getValueFromBitmask(PRIMARY_POS); }
-
- // Default value = false
- inline bool isExclusiveState() const { return getValueFromBitmask(EXCLUSIVE_POS); }
-
- // Default value = false
- inline bool isUidField() const { return getValueFromBitmask(UID_POS); }
-
-private:
- inline void setBitmaskAtPos(int pos, bool value) {
- mBooleanBitmask &= ~(1 << pos); // clear
- mBooleanBitmask |= (value << pos); // set
- }
-
- inline bool getValueFromBitmask(int pos) const {
- return (mBooleanBitmask >> pos) & 0x1;
- }
-
- // This is a bitmask over all annotations stored in boolean form. Because
- // there are only 4 booleans, just one byte is required.
- uint8_t mBooleanBitmask = 0;
-};
-
-/**
- * Represents a log item, or a dimension item (They are essentially the same).
- */
-struct FieldValue {
- FieldValue() {}
- FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
- }
- bool operator==(const FieldValue& that) const {
- return mField == that.mField && mValue == that.mValue;
- }
- bool operator!=(const FieldValue& that) const {
- return mField != that.mField || mValue != that.mValue;
- }
- bool operator<(const FieldValue& that) const {
- if (mField != that.mField) {
- return mField < that.mField;
- }
-
- if (mValue != that.mValue) {
- return mValue < that.mValue;
- }
-
- return false;
- }
-
- Field mField;
- Value mValue;
- Annotations mAnnotations;
-};
-
-bool HasPositionANY(const FieldMatcher& matcher);
-bool HasPositionALL(const FieldMatcher& matcher);
-
-bool isAttributionUidField(const FieldValue& value);
-
-/* returns uid if the field is uid field, or -1 if the field is not a uid field */
-int getUidIfExists(const FieldValue& value);
-
-void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
-
-bool isAttributionUidField(const Field& field, const Value& value);
-bool isUidField(const FieldValue& fieldValue);
-
-bool equalDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b);
-
-// Returns true if dimension_a is a subset of dimension_b.
-bool subsetDimensions(const std::vector<Matcher>& dimension_a,
- const std::vector<Matcher>& dimension_b);
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
deleted file mode 100644
index eba66e0cb7b0..000000000000
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "HashableDimensionKey.h"
-#include "FieldValue.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::string;
-using std::vector;
-using android::base::StringPrintf;
-
-// These constants must be kept in sync with those in StatsDimensionsValue.java
-const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
-const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
-const static int STATS_DIMENSIONS_VALUE_LONG_TYPE = 4;
-// const static int STATS_DIMENSIONS_VALUE_BOOL_TYPE = 5; (commented out because
-// unused -- statsd does not correctly support bool types)
-const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
-const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
-
-/**
- * Recursive helper function that populates a parent StatsDimensionsValueParcel
- * with children StatsDimensionsValueParcels.
- *
- * \param parent parcel that will be populated with children
- * \param childDepth depth of children FieldValues
- * \param childPrefix expected FieldValue prefix of children
- * \param dims vector of FieldValues stored by HashableDimensionKey
- * \param index position in dims to start reading children from
- */
-static void populateStatsDimensionsValueParcelChildren(StatsDimensionsValueParcel& parent,
- int childDepth, int childPrefix,
- const vector<FieldValue>& dims,
- size_t& index) {
- if (childDepth > 2) {
- ALOGE("Depth > 2 not supported by StatsDimensionsValueParcel.");
- return;
- }
-
- while (index < dims.size()) {
- const FieldValue& dim = dims[index];
- int fieldDepth = dim.mField.getDepth();
- int fieldPrefix = dim.mField.getPrefix(childDepth);
-
- StatsDimensionsValueParcel child;
- child.field = dim.mField.getPosAtDepth(childDepth);
-
- if (fieldDepth == childDepth && fieldPrefix == childPrefix) {
- switch (dim.mValue.getType()) {
- case INT:
- child.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
- child.intValue = dim.mValue.int_value;
- break;
- case LONG:
- child.valueType = STATS_DIMENSIONS_VALUE_LONG_TYPE;
- child.longValue = dim.mValue.long_value;
- break;
- case FLOAT:
- child.valueType = STATS_DIMENSIONS_VALUE_FLOAT_TYPE;
- child.floatValue = dim.mValue.float_value;
- break;
- case STRING:
- child.valueType = STATS_DIMENSIONS_VALUE_STRING_TYPE;
- child.stringValue = dim.mValue.str_value;
- break;
- default:
- ALOGE("Encountered FieldValue with unsupported value type.");
- break;
- }
- index++;
- parent.tupleValue.push_back(child);
- } else if (fieldDepth > childDepth && fieldPrefix == childPrefix) {
- // This FieldValue is not a child of the current parent, but it is
- // an indirect descendant. Thus, create a direct child of TUPLE_TYPE
- // and recurse to parcel the indirect descendants.
- child.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
- populateStatsDimensionsValueParcelChildren(child, childDepth + 1,
- dim.mField.getPrefix(childDepth + 1), dims,
- index);
- parent.tupleValue.push_back(child);
- } else {
- return;
- }
- }
-}
-
-StatsDimensionsValueParcel HashableDimensionKey::toStatsDimensionsValueParcel() const {
- StatsDimensionsValueParcel root;
- if (mValues.size() == 0) {
- return root;
- }
-
- root.field = mValues[0].mField.getTag();
- root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
-
- // Children of the root correspond to top-level (depth = 0) FieldValues.
- int childDepth = 0;
- int childPrefix = 0;
- size_t index = 0;
- populateStatsDimensionsValueParcelChildren(root, childDepth, childPrefix, mValues, index);
-
- return root;
-}
-
-android::hash_t hashDimension(const HashableDimensionKey& value) {
- android::hash_t hash = 0;
- for (const auto& fieldValue : value.getValues()) {
- hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getField()));
- hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getTag()));
- hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mValue.getType()));
- switch (fieldValue.mValue.getType()) {
- case INT:
- hash = android::JenkinsHashMix(hash,
- android::hash_type(fieldValue.mValue.int_value));
- break;
- case LONG:
- hash = android::JenkinsHashMix(hash,
- android::hash_type(fieldValue.mValue.long_value));
- break;
- case STRING:
- hash = android::JenkinsHashMix(hash, static_cast<uint32_t>(std::hash<std::string>()(
- fieldValue.mValue.str_value)));
- break;
- case FLOAT: {
- hash = android::JenkinsHashMix(hash,
- android::hash_type(fieldValue.mValue.float_value));
- break;
- }
- default:
- break;
- }
- }
- return JenkinsHashWhiten(hash);
-}
-
-bool filterValues(const Matcher& matcherField, const vector<FieldValue>& values,
- FieldValue* output) {
- for (const auto& value : values) {
- if (value.mField.matches(matcherField)) {
- (*output) = value;
- return true;
- }
- }
- return false;
-}
-
-bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue>& values,
- HashableDimensionKey* output) {
- size_t num_matches = 0;
- for (const auto& value : values) {
- for (size_t i = 0; i < matcherFields.size(); ++i) {
- const auto& matcher = matcherFields[i];
- if (value.mField.matches(matcher)) {
- output->addValue(value);
- output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
- output->mutableValue(num_matches)->mField.setField(
- value.mField.getField() & matcher.mMask);
- num_matches++;
- }
- }
- }
- return num_matches > 0;
-}
-
-bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output) {
- size_t num_matches = 0;
- const int32_t simpleFieldMask = 0xff7f0000;
- const int32_t attributionUidFieldMask = 0xff7f7f7f;
- for (const auto& value : values) {
- if (value.mAnnotations.isPrimaryField()) {
- output->addValue(value);
- output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
- const int32_t mask =
- isAttributionUidField(value) ? attributionUidFieldMask : simpleFieldMask;
- output->mutableValue(num_matches)->mField.setField(value.mField.getField() & mask);
- num_matches++;
- }
- }
- return num_matches > 0;
-}
-
-void filterGaugeValues(const std::vector<Matcher>& matcherFields,
- const std::vector<FieldValue>& values, std::vector<FieldValue>* output) {
- for (const auto& field : matcherFields) {
- for (const auto& value : values) {
- if (value.mField.matches(field)) {
- output->push_back(value);
- }
- }
- }
-}
-
-void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
- const Metric2Condition& links,
- HashableDimensionKey* conditionDimension) {
- // Get the dimension first by using dimension from what.
- filterValues(links.metricFields, eventValues, conditionDimension);
-
- size_t count = conditionDimension->getValues().size();
- if (count != links.conditionFields.size()) {
- return;
- }
-
- for (size_t i = 0; i < count; i++) {
- conditionDimension->mutableValue(i)->mField.setField(
- links.conditionFields[i].mMatcher.getField());
- conditionDimension->mutableValue(i)->mField.setTag(
- links.conditionFields[i].mMatcher.getTag());
- }
-}
-
-void getDimensionForState(const std::vector<FieldValue>& eventValues, const Metric2State& link,
- HashableDimensionKey* statePrimaryKey) {
- // First, get the dimension from the event using the "what" fields from the
- // MetricStateLinks.
- filterValues(link.metricFields, eventValues, statePrimaryKey);
-
- // Then check that the statePrimaryKey size equals the number of state fields
- size_t count = statePrimaryKey->getValues().size();
- if (count != link.stateFields.size()) {
- return;
- }
-
- // For each dimension Value in the statePrimaryKey, set the field and tag
- // using the state atom fields from MetricStateLinks.
- for (size_t i = 0; i < count; i++) {
- statePrimaryKey->mutableValue(i)->mField.setField(link.stateFields[i].mMatcher.getField());
- statePrimaryKey->mutableValue(i)->mField.setTag(link.stateFields[i].mMatcher.getTag());
- }
-}
-
-bool containsLinkedStateValues(const HashableDimensionKey& whatKey,
- const HashableDimensionKey& primaryKey,
- const vector<Metric2State>& stateLinks, const int32_t stateAtomId) {
- if (whatKey.getValues().size() < primaryKey.getValues().size()) {
- ALOGE("Contains linked values false: whatKey is too small");
- return false;
- }
-
- for (const auto& primaryValue : primaryKey.getValues()) {
- bool found = false;
- for (const auto& whatValue : whatKey.getValues()) {
- if (linked(stateLinks, stateAtomId, primaryValue.mField, whatValue.mField) &&
- primaryValue.mValue == whatValue.mValue) {
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
- return true;
-}
-
-bool linked(const vector<Metric2State>& stateLinks, const int32_t stateAtomId,
- const Field& stateField, const Field& metricField) {
- for (auto stateLink : stateLinks) {
- if (stateLink.stateAtomId != stateAtomId) {
- continue;
- }
-
- for (size_t i = 0; i < stateLink.stateFields.size(); i++) {
- if (stateLink.stateFields[i].mMatcher == stateField &&
- stateLink.metricFields[i].mMatcher == metricField) {
- return true;
- }
- }
- }
- return false;
-}
-
-bool LessThan(const vector<FieldValue>& s1, const vector<FieldValue>& s2) {
- if (s1.size() != s2.size()) {
- return s1.size() < s2.size();
- }
-
- size_t count = s1.size();
- for (size_t i = 0; i < count; i++) {
- if (s1[i] != s2[i]) {
- return s1[i] < s2[i];
- }
- }
- return false;
-}
-
-bool HashableDimensionKey::operator!=(const HashableDimensionKey& that) const {
- return !((*this) == that);
-}
-
-bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
- if (mValues.size() != that.getValues().size()) {
- return false;
- }
- size_t count = mValues.size();
- for (size_t i = 0; i < count; i++) {
- if (mValues[i] != (that.getValues())[i]) {
- return false;
- }
- }
- return true;
-};
-
-bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
- return LessThan(getValues(), that.getValues());
-};
-
-bool HashableDimensionKey::contains(const HashableDimensionKey& that) const {
- if (mValues.size() < that.getValues().size()) {
- return false;
- }
-
- if (mValues.size() == that.getValues().size()) {
- return (*this) == that;
- }
-
- for (const auto& value : that.getValues()) {
- bool found = false;
- for (const auto& myValue : mValues) {
- if (value.mField == myValue.mField && value.mValue == myValue.mValue) {
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
-
- return true;
-}
-
-string HashableDimensionKey::toString() const {
- std::string output;
- for (const auto& value : mValues) {
- output += StringPrintf("(%d)%#x->%s ", value.mField.getTag(), value.mField.getField(),
- value.mValue.toString().c_str());
- }
- return output;
-}
-
-bool MetricDimensionKey::operator==(const MetricDimensionKey& that) const {
- return mDimensionKeyInWhat == that.getDimensionKeyInWhat() &&
- mStateValuesKey == that.getStateValuesKey();
-};
-
-string MetricDimensionKey::toString() const {
- return mDimensionKeyInWhat.toString() + mStateValuesKey.toString();
-}
-
-bool MetricDimensionKey::operator<(const MetricDimensionKey& that) const {
- if (mDimensionKeyInWhat < that.getDimensionKeyInWhat()) {
- return true;
- } else if (that.getDimensionKeyInWhat() < mDimensionKeyInWhat) {
- return false;
- }
-
- return mStateValuesKey < that.getStateValuesKey();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
deleted file mode 100644
index bd011005a301..000000000000
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/StatsDimensionsValueParcel.h>
-#include <utils/JenkinsHash.h>
-#include <vector>
-#include "android-base/stringprintf.h"
-#include "FieldValue.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using ::aidl::android::os::StatsDimensionsValueParcel;
-
-struct Metric2Condition {
- int64_t conditionId;
- std::vector<Matcher> metricFields;
- std::vector<Matcher> conditionFields;
-};
-
-struct Metric2State {
- int32_t stateAtomId;
- std::vector<Matcher> metricFields;
- std::vector<Matcher> stateFields;
-};
-
-class HashableDimensionKey {
-public:
- explicit HashableDimensionKey(const std::vector<FieldValue>& values) {
- mValues = values;
- }
-
- HashableDimensionKey() {};
-
- HashableDimensionKey(const HashableDimensionKey& that) : mValues(that.getValues()){};
-
- inline void addValue(const FieldValue& value) {
- mValues.push_back(value);
- }
-
- inline const std::vector<FieldValue>& getValues() const {
- return mValues;
- }
-
- inline std::vector<FieldValue>* mutableValues() {
- return &mValues;
- }
-
- inline FieldValue* mutableValue(size_t i) {
- if (i >= 0 && i < mValues.size()) {
- return &(mValues[i]);
- }
- return nullptr;
- }
-
- StatsDimensionsValueParcel toStatsDimensionsValueParcel() const;
-
- std::string toString() const;
-
- bool operator!=(const HashableDimensionKey& that) const;
-
- bool operator==(const HashableDimensionKey& that) const;
-
- bool operator<(const HashableDimensionKey& that) const;
-
- bool contains(const HashableDimensionKey& that) const;
-
-private:
- std::vector<FieldValue> mValues;
-};
-
-class MetricDimensionKey {
-public:
- explicit MetricDimensionKey(const HashableDimensionKey& dimensionKeyInWhat,
- const HashableDimensionKey& stateValuesKey)
- : mDimensionKeyInWhat(dimensionKeyInWhat), mStateValuesKey(stateValuesKey){};
-
- MetricDimensionKey(){};
-
- MetricDimensionKey(const MetricDimensionKey& that)
- : mDimensionKeyInWhat(that.getDimensionKeyInWhat()),
- mStateValuesKey(that.getStateValuesKey()){};
-
- MetricDimensionKey& operator=(const MetricDimensionKey& from) = default;
-
- std::string toString() const;
-
- inline const HashableDimensionKey& getDimensionKeyInWhat() const {
- return mDimensionKeyInWhat;
- }
-
- inline const HashableDimensionKey& getStateValuesKey() const {
- return mStateValuesKey;
- }
-
- inline HashableDimensionKey* getMutableStateValuesKey() {
- return &mStateValuesKey;
- }
-
- inline void setStateValuesKey(const HashableDimensionKey& key) {
- mStateValuesKey = key;
- }
-
- bool hasStateValuesKey() const {
- return mStateValuesKey.getValues().size() > 0;
- }
-
- bool operator==(const MetricDimensionKey& that) const;
-
- bool operator<(const MetricDimensionKey& that) const;
-
-private:
- HashableDimensionKey mDimensionKeyInWhat;
- HashableDimensionKey mStateValuesKey;
-};
-
-android::hash_t hashDimension(const HashableDimensionKey& key);
-
-/**
- * Returns true if a FieldValue field matches the matcher field.
- * The value of the FieldValue is output.
- */
-bool filterValues(const Matcher& matcherField, const std::vector<FieldValue>& values,
- FieldValue* output);
-
-/**
- * Creating HashableDimensionKeys from FieldValues using matcher.
- *
- * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
- * in it. This is because: for example, when we create dimension from last uid in attribution chain,
- * In one event, uid 1000 is at position 5 and it's the last
- * In another event, uid 1000 is at position 6, and it's the last
- * these 2 events should be mapped to the same dimension. So we will remove the original position
- * from the dimension key for the uid field (by applying 0x80 bit mask).
- */
-bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values,
- HashableDimensionKey* output);
-
-/**
- * Creating HashableDimensionKeys from State Primary Keys in FieldValues.
- *
- * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
- * in it. This is because: for example, when we create dimension from last uid in attribution chain,
- * In one event, uid 1000 is at position 5 and it's the last
- * In another event, uid 1000 is at position 6, and it's the last
- * these 2 events should be mapped to the same dimension. So we will remove the original position
- * from the dimension key for the uid field (by applying 0x80 bit mask).
- */
-bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output);
-
-/**
- * Filter the values from FieldValues using the matchers.
- *
- * In contrast to the above function, this function will not do any modification to the original
- * data. Considering it as taking a snapshot on the atom event.
- */
-void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values,
- std::vector<FieldValue>* output);
-
-void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
- const Metric2Condition& links,
- HashableDimensionKey* conditionDimension);
-
-/**
- * Get dimension values using metric's "what" fields and fill statePrimaryKey's
- * mField information using "state" fields.
- */
-void getDimensionForState(const std::vector<FieldValue>& eventValues, const Metric2State& link,
- HashableDimensionKey* statePrimaryKey);
-
-/**
- * Returns true if the primaryKey values are a subset of the whatKey values.
- * The values from the primaryKey come from the state atom, so we need to
- * check that a link exists between the state atom field and what atom field.
- *
- * Example:
- * whatKey = [Atom: 10, {uid: 1005, wakelock_name: "compose"}]
- * statePrimaryKey = [Atom: 27, {uid: 1005}]
- * Returns true IF one of the Metric2State links Atom 10's uid to Atom 27's uid
- *
- * Example:
- * whatKey = [Atom: 10, {uid: 1005, wakelock_name: "compose"}]
- * statePrimaryKey = [Atom: 59, {uid: 1005, package_name: "system"}]
- * Returns false
- */
-bool containsLinkedStateValues(const HashableDimensionKey& whatKey,
- const HashableDimensionKey& primaryKey,
- const std::vector<Metric2State>& stateLinks,
- const int32_t stateAtomId);
-
-/**
- * Returns true if there is a Metric2State link that links the stateField and
- * the metricField (they are equal fields from different atoms).
- */
-bool linked(const std::vector<Metric2State>& stateLinks, const int32_t stateAtomId,
- const Field& stateField, const Field& metricField);
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-namespace std {
-
-using android::os::statsd::HashableDimensionKey;
-using android::os::statsd::MetricDimensionKey;
-
-template <>
-struct hash<HashableDimensionKey> {
- std::size_t operator()(const HashableDimensionKey& key) const {
- return hashDimension(key);
- }
-};
-
-template <>
-struct hash<MetricDimensionKey> {
- std::size_t operator()(const MetricDimensionKey& key) const {
- android::hash_t hash = hashDimension(key.getDimensionKeyInWhat());
- hash = android::JenkinsHashMix(hash, hashDimension(key.getStateValuesKey()));
- return android::JenkinsHashWhiten(hash);
- }
-};
-} // namespace std
diff --git a/cmds/statsd/src/Log.h b/cmds/statsd/src/Log.h
deleted file mode 100644
index 87f4cbaf02f6..000000000000
--- a/cmds/statsd/src/Log.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file must be included at the top of the file. Other header files
- * occasionally include log.h, and if LOG_TAG isn't set when that happens
- * we'll get a preprocesser error when we try to define it here.
- */
-
-#pragma once
-
-#define LOG_TAG "statsd"
-
-#include <log/log.h>
-
-// Use the local value to turn on/off debug logs instead of using log.tag. properties.
-// The advantage is that in production compiler can remove the logging code if the local
-// DEBUG/VERBOSE is false.
-#define VLOG(...) \
- if (DEBUG) ALOGD(__VA_ARGS__);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
deleted file mode 100644
index b7f23a605142..000000000000
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ /dev/null
@@ -1,1130 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsLogProcessor.h"
-
-#include <android-base/file.h>
-#include <cutils/multiuser.h>
-#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
-#include <frameworks/base/cmds/statsd/src/experiment_ids.pb.h>
-
-#include "android-base/stringprintf.h"
-#include "external/StatsPullerManager.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "metrics/CountMetricProducer.h"
-#include "StatsService.h"
-#include "state/StateManager.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-using namespace android;
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for ConfigMetricsReportList
-const int FIELD_ID_CONFIG_KEY = 1;
-const int FIELD_ID_REPORTS = 2;
-// for ConfigKey
-const int FIELD_ID_UID = 1;
-const int FIELD_ID_ID = 2;
-// for ConfigMetricsReport
-// const int FIELD_ID_METRICS = 1; // written in MetricsManager.cpp
-const int FIELD_ID_UID_MAP = 2;
-const int FIELD_ID_LAST_REPORT_ELAPSED_NANOS = 3;
-const int FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS = 4;
-const int FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS = 5;
-const int FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS = 6;
-const int FIELD_ID_DUMP_REPORT_REASON = 8;
-const int FIELD_ID_STRINGS = 9;
-
-// for ActiveConfigList
-const int FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG = 1;
-
-// for permissions checks
-constexpr const char* kPermissionDump = "android.permission.DUMP";
-constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS";
-
-#define NS_PER_HOUR 3600 * NS_PER_SEC
-
-#define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
-#define STATS_METADATA_DIR "/data/misc/stats-metadata"
-
-// Cool down period for writing data to disk to avoid overwriting files.
-#define WRITE_DATA_COOL_DOWN_SEC 5
-
-StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor,
- const int64_t timeBaseNs,
- const std::function<bool(const ConfigKey&)>& sendBroadcast,
- const std::function<bool(
- const int&, const vector<int64_t>&)>& activateBroadcast)
- : mUidMap(uidMap),
- mPullerManager(pullerManager),
- mAnomalyAlarmMonitor(anomalyAlarmMonitor),
- mPeriodicAlarmMonitor(periodicAlarmMonitor),
- mSendBroadcast(sendBroadcast),
- mSendActivationBroadcast(activateBroadcast),
- mTimeBaseNs(timeBaseNs),
- mLargestTimestampSeen(0),
- mLastTimestampSeen(0) {
- mPullerManager->ForceClearPullerCache();
- StateManager::getInstance().updateLogSources(uidMap);
-}
-
-StatsLogProcessor::~StatsLogProcessor() {
-}
-
-static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outData) {
- outData->clear();
- outData->resize(proto.size());
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*outData)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-
-void StatsLogProcessor::processFiredAnomalyAlarmsLocked(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
- for (const auto& itr : mMetricsManagers) {
- itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
- }
-}
-void StatsLogProcessor::onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
-
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- for (const auto& itr : mMetricsManagers) {
- itr.second->onPeriodicAlarmFired(timestampNs, alarmSet);
- }
-}
-
-void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- if (std::pair<int, int> indexRange; event->hasAttributionChain(&indexRange)) {
- vector<FieldValue>* const fieldValues = event->getMutableValues();
- for (int i = indexRange.first; i <= indexRange.second; i++) {
- FieldValue& fieldValue = fieldValues->at(i);
- if (isAttributionUidField(fieldValue)) {
- const int hostUid = mUidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
- fieldValue.mValue.setInt(hostUid);
- }
- }
- } else {
- int uidFieldIndex = event->getUidFieldIndex();
- if (uidFieldIndex != -1) {
- Value& value = (*event->getMutableValues())[uidFieldIndex].mValue;
- const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
- value.setInt(hostUid);
- }
- }
-}
-
-void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) {
- status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR;
- bool is_create = event.GetBool(3, &err);
- auto parent_uid = int(event.GetLong(1, &err2));
- auto isolated_uid = int(event.GetLong(2, &err3));
- if (err == NO_ERROR && err2 == NO_ERROR && err3 == NO_ERROR) {
- if (is_create) {
- mUidMap->assignIsolatedUid(isolated_uid, parent_uid);
- } else {
- mUidMap->removeIsolatedUid(isolated_uid);
- }
- } else {
- ALOGE("Failed to parse uid in the isolated uid change event.");
- }
-}
-
-void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) {
- pid_t pid = event->GetPid();
- uid_t uid = event->GetUid();
- if (!checkPermissionForIds(kPermissionDump, pid, uid) ||
- !checkPermissionForIds(kPermissionUsage, pid, uid)) {
- return;
- }
- // The Get* functions don't modify the status on success, they only write in
- // failure statuses, so we can use one status variable for all calls then
- // check if it is no longer NO_ERROR.
- status_t err = NO_ERROR;
- InstallTrainInfo trainInfo;
- trainInfo.trainName = string(event->GetString(1 /*train name field id*/, &err));
- trainInfo.trainVersionCode = event->GetLong(2 /*train version field id*/, &err);
- trainInfo.requiresStaging = event->GetBool(3 /*requires staging field id*/, &err);
- trainInfo.rollbackEnabled = event->GetBool(4 /*rollback enabled field id*/, &err);
- trainInfo.requiresLowLatencyMonitor =
- event->GetBool(5 /*requires low latency monitor field id*/, &err);
- trainInfo.status = int32_t(event->GetLong(6 /*state field id*/, &err));
- std::vector<uint8_t> trainExperimentIdBytes =
- event->GetStorage(7 /*experiment ids field id*/, &err);
- bool is_rollback = event->GetBool(10 /*is rollback field id*/, &err);
-
- if (err != NO_ERROR) {
- ALOGE("Failed to parse fields in binary push state changed log event");
- return;
- }
- ExperimentIds trainExperimentIds;
- if (!trainExperimentIds.ParseFromArray(trainExperimentIdBytes.data(),
- trainExperimentIdBytes.size())) {
- ALOGE("Failed to parse experimentids in binary push state changed.");
- return;
- }
- trainInfo.experimentIds = {trainExperimentIds.experiment_id().begin(),
- trainExperimentIds.experiment_id().end()};
-
- // Update the train info on disk and get any data the logevent is missing.
- getAndUpdateTrainInfoOnDisk(is_rollback, &trainInfo);
-
- std::vector<uint8_t> trainExperimentIdProto;
- writeExperimentIdsToProto(trainInfo.experimentIds, &trainExperimentIdProto);
- int32_t userId = multiuser_get_user_id(uid);
-
- event->updateValue(2 /*train version field id*/, trainInfo.trainVersionCode, LONG);
- event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STORAGE);
- event->updateValue(8 /*user id field id*/, userId, INT);
-
- // If this event is a rollback event, then the following bits in the event
- // are invalid and we will need to update them with the values we pulled
- // from disk.
- if (is_rollback) {
- int bit = trainInfo.requiresStaging ? 1 : 0;
- event->updateValue(3 /*requires staging field id*/, bit, INT);
- bit = trainInfo.rollbackEnabled ? 1 : 0;
- event->updateValue(4 /*rollback enabled field id*/, bit, INT);
- bit = trainInfo.requiresLowLatencyMonitor ? 1 : 0;
- event->updateValue(5 /*requires low latency monitor field id*/, bit, INT);
- }
-}
-
-void StatsLogProcessor::getAndUpdateTrainInfoOnDisk(bool is_rollback,
- InstallTrainInfo* trainInfo) {
- // If the train name is empty, we don't know which train to attribute the
- // event to, so return early.
- if (trainInfo->trainName.empty()) {
- return;
- }
- bool readTrainInfoSuccess = false;
- InstallTrainInfo trainInfoOnDisk;
- readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfo->trainName, trainInfoOnDisk);
-
- bool resetExperimentIds = false;
- if (readTrainInfoSuccess) {
- // Keep the old train version if we received an empty version.
- if (trainInfo->trainVersionCode == -1) {
- trainInfo->trainVersionCode = trainInfoOnDisk.trainVersionCode;
- } else if (trainInfo->trainVersionCode != trainInfoOnDisk.trainVersionCode) {
- // Reset experiment ids if we receive a new non-empty train version.
- resetExperimentIds = true;
- }
-
- // Reset if we received a different experiment id.
- if (!trainInfo->experimentIds.empty() &&
- (trainInfoOnDisk.experimentIds.empty() ||
- trainInfo->experimentIds.at(0) != trainInfoOnDisk.experimentIds[0])) {
- resetExperimentIds = true;
- }
- }
-
- // Find the right experiment IDs
- if ((!resetExperimentIds || is_rollback) && readTrainInfoSuccess) {
- trainInfo->experimentIds = trainInfoOnDisk.experimentIds;
- }
-
- if (!trainInfo->experimentIds.empty()) {
- int64_t firstId = trainInfo->experimentIds.at(0);
- auto& ids = trainInfo->experimentIds;
- switch (trainInfo->status) {
- case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALL_SUCCESS:
- if (find(ids.begin(), ids.end(), firstId + 1) == ids.end()) {
- ids.push_back(firstId + 1);
- }
- break;
- case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_INITIATED:
- if (find(ids.begin(), ids.end(), firstId + 2) == ids.end()) {
- ids.push_back(firstId + 2);
- }
- break;
- case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_SUCCESS:
- if (find(ids.begin(), ids.end(), firstId + 3) == ids.end()) {
- ids.push_back(firstId + 3);
- }
- break;
- }
- }
-
- // If this event is a rollback event, the following fields are invalid and
- // need to be replaced by the fields stored to disk.
- if (is_rollback) {
- trainInfo->requiresStaging = trainInfoOnDisk.requiresStaging;
- trainInfo->rollbackEnabled = trainInfoOnDisk.rollbackEnabled;
- trainInfo->requiresLowLatencyMonitor = trainInfoOnDisk.requiresLowLatencyMonitor;
- }
-
- StorageManager::writeTrainInfo(*trainInfo);
-}
-
-void StatsLogProcessor::onWatchdogRollbackOccurredLocked(LogEvent* event) {
- pid_t pid = event->GetPid();
- uid_t uid = event->GetUid();
- if (!checkPermissionForIds(kPermissionDump, pid, uid) ||
- !checkPermissionForIds(kPermissionUsage, pid, uid)) {
- return;
- }
- // The Get* functions don't modify the status on success, they only write in
- // failure statuses, so we can use one status variable for all calls then
- // check if it is no longer NO_ERROR.
- status_t err = NO_ERROR;
- int32_t rollbackType = int32_t(event->GetInt(1 /*rollback type field id*/, &err));
- string packageName = string(event->GetString(2 /*package name field id*/, &err));
-
- if (err != NO_ERROR) {
- ALOGE("Failed to parse fields in watchdog rollback occurred log event");
- return;
- }
-
- vector<int64_t> experimentIds =
- processWatchdogRollbackOccurred(rollbackType, packageName);
- vector<uint8_t> experimentIdProto;
- writeExperimentIdsToProto(experimentIds, &experimentIdProto);
-
- event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STORAGE);
-}
-
-vector<int64_t> StatsLogProcessor::processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
- const string& packageNameIn) {
- // If the package name is empty, we can't attribute it to any train, so
- // return early.
- if (packageNameIn.empty()) {
- return vector<int64_t>();
- }
- bool readTrainInfoSuccess = false;
- InstallTrainInfo trainInfoOnDisk;
- // We use the package name of the event as the train name.
- readTrainInfoSuccess = StorageManager::readTrainInfo(packageNameIn, trainInfoOnDisk);
-
- if (!readTrainInfoSuccess) {
- return vector<int64_t>();
- }
-
- if (trainInfoOnDisk.experimentIds.empty()) {
- return vector<int64_t>();
- }
-
- int64_t firstId = trainInfoOnDisk.experimentIds[0];
- auto& ids = trainInfoOnDisk.experimentIds;
- switch (rollbackTypeIn) {
- case android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE:
- if (find(ids.begin(), ids.end(), firstId + 4) == ids.end()) {
- ids.push_back(firstId + 4);
- }
- StorageManager::writeTrainInfo(trainInfoOnDisk);
- break;
- case android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS:
- if (find(ids.begin(), ids.end(), firstId + 5) == ids.end()) {
- ids.push_back(firstId + 5);
- }
- StorageManager::writeTrainInfo(trainInfoOnDisk);
- break;
- }
-
- return trainInfoOnDisk.experimentIds;
-}
-
-void StatsLogProcessor::resetConfigs() {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- resetConfigsLocked(getElapsedRealtimeNs());
-}
-
-void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) {
- std::vector<ConfigKey> configKeys;
- for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
- configKeys.push_back(it->first);
- }
- resetConfigsLocked(timestampNs, configKeys);
-}
-
-void StatsLogProcessor::OnLogEvent(LogEvent* event) {
- OnLogEvent(event, getElapsedRealtimeNs());
-}
-
-void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
-
- // Tell StatsdStats about new event
- const int64_t eventElapsedTimeNs = event->GetElapsedTimestampNs();
- int atomId = event->GetTagId();
- StatsdStats::getInstance().noteAtomLogged(atomId, eventElapsedTimeNs / NS_PER_SEC);
- if (!event->isValid()) {
- StatsdStats::getInstance().noteAtomError(atomId);
- return;
- }
-
- // Hard-coded logic to update train info on disk and fill in any information
- // this log event may be missing.
- if (atomId == android::os::statsd::util::BINARY_PUSH_STATE_CHANGED) {
- onBinaryPushStateChangedEventLocked(event);
- }
-
- // Hard-coded logic to update experiment ids on disk for certain rollback
- // types and fill the rollback atom with experiment ids
- if (atomId == android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED) {
- onWatchdogRollbackOccurredLocked(event);
- }
-
- if (mPrintAllLogs) {
- ALOGI("%s", event->ToString().c_str());
- }
- resetIfConfigTtlExpiredLocked(eventElapsedTimeNs);
-
- // Hard-coded logic to update the isolated uid's in the uid-map.
- // The field numbers need to be currently updated by hand with atoms.proto
- if (atomId == android::os::statsd::util::ISOLATED_UID_CHANGED) {
- onIsolatedUidChangedEventLocked(*event);
- } else {
- // Map the isolated uid to host uid if necessary.
- mapIsolatedUidToHostUidIfNecessaryLocked(event);
- }
-
- StateManager::getInstance().onLogEvent(*event);
-
- if (mMetricsManagers.empty()) {
- return;
- }
-
- bool fireAlarm = false;
- {
- std::lock_guard<std::mutex> anomalyLock(mAnomalyAlarmMutex);
- if (mNextAnomalyAlarmTime != 0 &&
- MillisToNano(mNextAnomalyAlarmTime) <= elapsedRealtimeNs) {
- mNextAnomalyAlarmTime = 0;
- VLOG("informing anomaly alarm at time %lld", (long long)elapsedRealtimeNs);
- fireAlarm = true;
- }
- }
- if (fireAlarm) {
- informAnomalyAlarmFiredLocked(NanoToMillis(elapsedRealtimeNs));
- }
-
- int64_t curTimeSec = getElapsedRealtimeSec();
- if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
- mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
- mLastPullerCacheClearTimeSec = curTimeSec;
- }
-
- std::unordered_set<int> uidsWithActiveConfigsChanged;
- std::unordered_map<int, std::vector<int64_t>> activeConfigsPerUid;
- // pass the event to metrics managers.
- for (auto& pair : mMetricsManagers) {
- int uid = pair.first.GetUid();
- int64_t configId = pair.first.GetId();
- bool isPrevActive = pair.second->isActive();
- pair.second->onLogEvent(*event);
- bool isCurActive = pair.second->isActive();
- // Map all active configs by uid.
- if (isCurActive) {
- auto activeConfigs = activeConfigsPerUid.find(uid);
- if (activeConfigs != activeConfigsPerUid.end()) {
- activeConfigs->second.push_back(configId);
- } else {
- vector<int64_t> newActiveConfigs;
- newActiveConfigs.push_back(configId);
- activeConfigsPerUid[uid] = newActiveConfigs;
- }
- }
- // The activation state of this config changed.
- if (isPrevActive != isCurActive) {
- VLOG("Active status changed for uid %d", uid);
- uidsWithActiveConfigsChanged.insert(uid);
- StatsdStats::getInstance().noteActiveStatusChanged(pair.first, isCurActive);
- }
- flushIfNecessaryLocked(pair.first, *(pair.second));
- }
-
- // Don't use the event timestamp for the guardrail.
- for (int uid : uidsWithActiveConfigsChanged) {
- // Send broadcast so that receivers can pull data.
- auto lastBroadcastTime = mLastActivationBroadcastTimes.find(uid);
- if (lastBroadcastTime != mLastActivationBroadcastTimes.end()) {
- if (elapsedRealtimeNs - lastBroadcastTime->second <
- StatsdStats::kMinActivationBroadcastPeriodNs) {
- StatsdStats::getInstance().noteActivationBroadcastGuardrailHit(uid);
- VLOG("StatsD would've sent an activation broadcast but the rate limit stopped us.");
- return;
- }
- }
- auto activeConfigs = activeConfigsPerUid.find(uid);
- if (activeConfigs != activeConfigsPerUid.end()) {
- if (mSendActivationBroadcast(uid, activeConfigs->second)) {
- VLOG("StatsD sent activation notice for uid %d", uid);
- mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
- }
- } else {
- std::vector<int64_t> emptyActiveConfigs;
- if (mSendActivationBroadcast(uid, emptyActiveConfigs)) {
- VLOG("StatsD sent EMPTY activation notice for uid %d", uid);
- mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
- }
- }
- }
-}
-
-void StatsLogProcessor::GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- GetActiveConfigsLocked(uid, outActiveConfigs);
-}
-
-void StatsLogProcessor::GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs) {
- outActiveConfigs.clear();
- for (auto& pair : mMetricsManagers) {
- if (pair.first.GetUid() == uid && pair.second->isActive()) {
- outActiveConfigs.push_back(pair.first.GetId());
- }
- }
-}
-
-void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED, NO_TIME_CONSTRAINTS);
- OnConfigUpdatedLocked(timestampNs, key, config);
-}
-
-void StatsLogProcessor::OnConfigUpdatedLocked(
- const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
- VLOG("Updated configuration for key %s", key.ToString().c_str());
- sp<MetricsManager> newMetricsManager =
- new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
- mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
- if (newMetricsManager->isConfigValid()) {
- newMetricsManager->init();
- mUidMap->OnConfigUpdated(key);
- newMetricsManager->refreshTtl(timestampNs);
- mMetricsManagers[key] = newMetricsManager;
- VLOG("StatsdConfig valid");
- } else {
- // If there is any error in the config, don't use it.
- // Remove any existing config with the same key.
- ALOGE("StatsdConfig NOT valid");
- mMetricsManagers.erase(key);
- }
-}
-
-size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) const {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGW("Config source %s does not exist", key.ToString().c_str());
- return 0;
- }
- return it->second->byteSize();
-}
-
-void StatsLogProcessor::dumpStates(int out, bool verbose) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- FILE* fout = fdopen(out, "w");
- if (fout == NULL) {
- return;
- }
- fprintf(fout, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
- for (auto metricsManager : mMetricsManagers) {
- metricsManager.second->dumpStates(fout, verbose);
- }
-
- fclose(fout);
-}
-
-/*
- * onDumpReport dumps serialized ConfigMetricsReportList into proto.
- */
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- ProtoOutputStream* proto) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
-
- // Start of ConfigKey.
- uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
- proto->end(configKeyToken);
- // End of ConfigKey.
-
- bool keepFile = false;
- auto it = mMetricsManagers.find(key);
- if (it != mMetricsManagers.end() && it->second->shouldPersistLocalHistory()) {
- keepFile = true;
- }
-
- // Then, check stats-data directory to see there's any file containing
- // ConfigMetricsReport from previous shutdowns to concatenate to reports.
- StorageManager::appendConfigMetricsReport(
- key, proto, erase_data && !keepFile /* should remove file after appending it */,
- dumpReportReason == ADB_DUMP /*if caller is adb*/);
-
- if (it != mMetricsManagers.end()) {
- // This allows another broadcast to be sent within the rate-limit period if we get close to
- // filling the buffer again soon.
- mLastBroadcastTimes.erase(key);
-
- vector<uint8_t> buffer;
- onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
- erase_data, dumpReportReason, dumpLatency,
- false /* is this data going to be saved on disk */, &buffer);
- proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
- reinterpret_cast<char*>(buffer.data()), buffer.size());
- } else {
- ALOGW("Config source %s does not exist", key.ToString().c_str());
- }
-}
-
-/*
- * onDumpReport dumps serialized ConfigMetricsReportList into outData.
- */
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- vector<uint8_t>* outData) {
- ProtoOutputStream proto;
- onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpReportReason, dumpLatency, &proto);
-
- if (outData != nullptr) {
- flushProtoToBuffer(proto, outData);
- VLOG("output data size %zu", outData->size());
- }
-
- StatsdStats::getInstance().noteMetricsReportSent(key, proto.size());
-}
-
-/*
- * onConfigMetricsReportLocked dumps serialized ConfigMetricsReport into outData.
- */
-void StatsLogProcessor::onConfigMetricsReportLocked(
- const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
- const bool dataSavedOnDisk, vector<uint8_t>* buffer) {
- // We already checked whether key exists in mMetricsManagers in
- // WriteDataToDisk.
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- return;
- }
- int64_t lastReportTimeNs = it->second->getLastReportTimeNs();
- int64_t lastReportWallClockNs = it->second->getLastReportWallClockNs();
-
- std::set<string> str_set;
-
- ProtoOutputStream tempProto;
- // First, fill in ConfigMetricsReport using current data on memory, which
- // starts from filling in StatsLogReport's.
- it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpLatency, &str_set, &tempProto);
-
- // Fill in UidMap if there is at least one metric to report.
- // This skips the uid map if it's an empty config.
- if (it->second->getNumMetrics() > 0) {
- uint64_t uidMapToken = tempProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP);
- mUidMap->appendUidMap(
- dumpTimeStampNs, key, it->second->hashStringInReport() ? &str_set : nullptr,
- it->second->versionStringsInReport(), it->second->installerInReport(), &tempProto);
- tempProto.end(uidMapToken);
- }
-
- // Fill in the timestamps.
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_ELAPSED_NANOS,
- (long long)lastReportTimeNs);
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS,
- (long long)dumpTimeStampNs);
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS,
- (long long)lastReportWallClockNs);
- tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS,
- (long long)getWallClockNs());
- // Dump report reason
- tempProto.write(FIELD_TYPE_INT32 | FIELD_ID_DUMP_REPORT_REASON, dumpReportReason);
-
- for (const auto& str : str_set) {
- tempProto.write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | FIELD_ID_STRINGS, str);
- }
-
- flushProtoToBuffer(tempProto, buffer);
-
- // save buffer to disk if needed
- if (erase_data && !dataSavedOnDisk && it->second->shouldPersistLocalHistory()) {
- VLOG("save history to disk");
- string file_name = StorageManager::getDataHistoryFileName((long)getWallClockSec(),
- key.GetUid(), key.GetId());
- StorageManager::writeFile(file_name.c_str(), buffer->data(), buffer->size());
- }
-}
-
-void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs,
- const std::vector<ConfigKey>& configs) {
- for (const auto& key : configs) {
- StatsdConfig config;
- if (StorageManager::readConfigFromDisk(key, &config)) {
- OnConfigUpdatedLocked(timestampNs, key, config);
- StatsdStats::getInstance().noteConfigReset(key);
- } else {
- ALOGE("Failed to read backup config from disk for : %s", key.ToString().c_str());
- auto it = mMetricsManagers.find(key);
- if (it != mMetricsManagers.end()) {
- it->second->refreshTtl(timestampNs);
- }
- }
- }
-}
-
-void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) {
- std::vector<ConfigKey> configKeysTtlExpired;
- for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
- if (it->second != nullptr && !it->second->isInTtl(timestampNs)) {
- configKeysTtlExpired.push_back(it->first);
- }
- }
- if (configKeysTtlExpired.size() > 0) {
- WriteDataToDiskLocked(CONFIG_RESET, NO_TIME_CONSTRAINTS);
- resetConfigsLocked(timestampNs, configKeysTtlExpired);
- }
-}
-
-void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- auto it = mMetricsManagers.find(key);
- if (it != mMetricsManagers.end()) {
- WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED,
- NO_TIME_CONSTRAINTS);
- mMetricsManagers.erase(it);
- mUidMap->OnConfigRemoved(key);
- }
- StatsdStats::getInstance().noteConfigRemoved(key);
-
- mLastBroadcastTimes.erase(key);
-
- int uid = key.GetUid();
- bool lastConfigForUid = true;
- for (auto it : mMetricsManagers) {
- if (it.first.GetUid() == uid) {
- lastConfigForUid = false;
- break;
- }
- }
- if (lastConfigForUid) {
- mLastActivationBroadcastTimes.erase(uid);
- }
-
- if (mMetricsManagers.empty()) {
- mPullerManager->ForceClearPullerCache();
- }
-}
-
-void StatsLogProcessor::flushIfNecessaryLocked(const ConfigKey& key,
- MetricsManager& metricsManager) {
- int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
- auto lastCheckTime = mLastByteSizeTimes.find(key);
- if (lastCheckTime != mLastByteSizeTimes.end()) {
- if (elapsedRealtimeNs - lastCheckTime->second < StatsdStats::kMinByteSizeCheckPeriodNs) {
- return;
- }
- }
-
- // We suspect that the byteSize() computation is expensive, so we set a rate limit.
- size_t totalBytes = metricsManager.byteSize();
- mLastByteSizeTimes[key] = elapsedRealtimeNs;
- bool requestDump = false;
- if (totalBytes > StatsdStats::kMaxMetricsBytesPerConfig) {
- // Too late. We need to start clearing data.
- metricsManager.dropData(elapsedRealtimeNs);
- StatsdStats::getInstance().noteDataDropped(key, totalBytes);
- VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
- } else if ((totalBytes > StatsdStats::kBytesPerConfigTriggerGetData) ||
- (mOnDiskDataConfigs.find(key) != mOnDiskDataConfigs.end())) {
- // Request to send a broadcast if:
- // 1. in memory data > threshold OR
- // 2. config has old data report on disk.
- requestDump = true;
- }
-
- if (requestDump) {
- // Send broadcast so that receivers can pull data.
- auto lastBroadcastTime = mLastBroadcastTimes.find(key);
- if (lastBroadcastTime != mLastBroadcastTimes.end()) {
- if (elapsedRealtimeNs - lastBroadcastTime->second <
- StatsdStats::kMinBroadcastPeriodNs) {
- VLOG("StatsD would've sent a broadcast but the rate limit stopped us.");
- return;
- }
- }
- if (mSendBroadcast(key)) {
- mOnDiskDataConfigs.erase(key);
- VLOG("StatsD triggered data fetch for %s", key.ToString().c_str());
- mLastBroadcastTimes[key] = elapsedRealtimeNs;
- StatsdStats::getInstance().noteBroadcastSent(key);
- }
- }
-}
-
-void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
- const int64_t timestampNs,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency) {
- if (mMetricsManagers.find(key) == mMetricsManagers.end() ||
- !mMetricsManagers.find(key)->second->shouldWriteToDisk()) {
- return;
- }
- vector<uint8_t> buffer;
- onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
- true /* erase_data */, dumpReportReason, dumpLatency, true,
- &buffer);
- string file_name =
- StorageManager::getDataFileName((long)getWallClockSec(), key.GetUid(), key.GetId());
- StorageManager::writeFile(file_name.c_str(), buffer.data(), buffer.size());
-
- // We were able to write the ConfigMetricsReport to disk, so we should trigger collection ASAP.
- mOnDiskDataConfigs.insert(key);
-}
-
-void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- const int64_t timeNs = getElapsedRealtimeNs();
- // Do not write to disk if we already have in the last few seconds.
- if (static_cast<unsigned long long> (timeNs) <
- mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
- ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds",
- WRITE_DATA_COOL_DOWN_SEC);
- return;
- }
- mLastActiveMetricsWriteNs = timeNs;
-
- ProtoOutputStream proto;
- WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, DEVICE_SHUTDOWN, &proto);
-
- string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
- StorageManager::deleteFile(file_name.c_str());
- android::base::unique_fd fd(
- open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR));
- if (fd == -1) {
- ALOGE("Attempt to write %s but failed", file_name.c_str());
- return;
- }
- proto.flush(fd.get());
-}
-
-void StatsLogProcessor::SaveMetadataToDisk(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- // Do not write to disk if we already have in the last few seconds.
- if (static_cast<unsigned long long> (systemElapsedTimeNs) <
- mLastMetadataWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
- ALOGI("Statsd skipping writing metadata to disk. Already wrote data in last %d seconds",
- WRITE_DATA_COOL_DOWN_SEC);
- return;
- }
- mLastMetadataWriteNs = systemElapsedTimeNs;
-
- metadata::StatsMetadataList metadataList;
- WriteMetadataToProtoLocked(
- currentWallClockTimeNs, systemElapsedTimeNs, &metadataList);
-
- string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
- StorageManager::deleteFile(file_name.c_str());
-
- if (metadataList.stats_metadata_size() == 0) {
- // Skip the write if we have nothing to write.
- return;
- }
-
- std::string data;
- metadataList.SerializeToString(&data);
- StorageManager::writeFile(file_name.c_str(), data.c_str(), data.size());
-}
-
-void StatsLogProcessor::WriteMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteMetadataToProtoLocked(currentWallClockTimeNs, systemElapsedTimeNs, metadataList);
-}
-
-void StatsLogProcessor::WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList) {
- for (const auto& pair : mMetricsManagers) {
- const sp<MetricsManager>& metricsManager = pair.second;
- metadata::StatsMetadata* statsMetadata = metadataList->add_stats_metadata();
- bool metadataWritten = metricsManager->writeMetadataToProto(currentWallClockTimeNs,
- systemElapsedTimeNs, statsMetadata);
- if (!metadataWritten) {
- metadataList->mutable_stats_metadata()->RemoveLast();
- }
- }
-}
-
-void StatsLogProcessor::LoadMetadataFromDisk(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (-1 == fd) {
- VLOG("Attempt to read %s but failed", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- string content;
- if (!android::base::ReadFdToString(fd, &content)) {
- ALOGE("Attempt to read %s but failed", file_name.c_str());
- close(fd);
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
-
- close(fd);
-
- metadata::StatsMetadataList statsMetadataList;
- if (!statsMetadataList.ParseFromString(content)) {
- ALOGE("Attempt to read %s but failed; failed to metadata", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs);
- StorageManager::deleteFile(file_name.c_str());
-}
-
-void StatsLogProcessor::SetMetadataState(const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs);
-}
-
-void StatsLogProcessor::SetMetadataStateLocked(
- const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- for (const metadata::StatsMetadata& metadata : statsMetadataList.stats_metadata()) {
- ConfigKey key(metadata.config_key().uid(), metadata.config_key().config_id());
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGE("No config found for configKey %s", key.ToString().c_str());
- continue;
- }
- VLOG("Setting metadata %s", key.ToString().c_str());
- it->second->loadMetadata(metadata, currentWallClockTimeNs, systemElapsedTimeNs);
- }
- VLOG("Successfully loaded %d metadata.", statsMetadataList.stats_metadata_size());
-}
-
-void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, reason, proto);
-}
-
-void StatsLogProcessor::WriteActiveConfigsToProtoOutputStreamLocked(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- for (const auto& pair : mMetricsManagers) {
- const sp<MetricsManager>& metricsManager = pair.second;
- uint64_t configToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
- metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, reason, proto);
- proto->end(configToken);
- }
-}
-void StatsLogProcessor::LoadActiveConfigsFromDisk() {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (-1 == fd) {
- VLOG("Attempt to read %s but failed", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- string content;
- if (!android::base::ReadFdToString(fd, &content)) {
- ALOGE("Attempt to read %s but failed", file_name.c_str());
- close(fd);
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
-
- close(fd);
-
- ActiveConfigList activeConfigList;
- if (!activeConfigList.ParseFromString(content)) {
- ALOGE("Attempt to read %s but failed; failed to load active configs", file_name.c_str());
- StorageManager::deleteFile(file_name.c_str());
- return;
- }
- // Passing in mTimeBaseNs only works as long as we only load from disk is when statsd starts.
- SetConfigsActiveStateLocked(activeConfigList, mTimeBaseNs);
- StorageManager::deleteFile(file_name.c_str());
-}
-
-void StatsLogProcessor::SetConfigsActiveState(const ActiveConfigList& activeConfigList,
- int64_t currentTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- SetConfigsActiveStateLocked(activeConfigList, currentTimeNs);
-}
-
-void StatsLogProcessor::SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
- int64_t currentTimeNs) {
- for (int i = 0; i < activeConfigList.config_size(); i++) {
- const auto& config = activeConfigList.config(i);
- ConfigKey key(config.uid(), config.id());
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- ALOGE("No config found for config %s", key.ToString().c_str());
- continue;
- }
- VLOG("Setting active config %s", key.ToString().c_str());
- it->second->loadActiveConfig(config, currentTimeNs);
- }
- VLOG("Successfully loaded %d active configs.", activeConfigList.config_size());
-}
-
-void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency) {
- const int64_t timeNs = getElapsedRealtimeNs();
- // Do not write to disk if we already have in the last few seconds.
- // This is to avoid overwriting files that would have the same name if we
- // write twice in the same second.
- if (static_cast<unsigned long long> (timeNs) <
- mLastWriteTimeNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
- ALOGI("Statsd skipping writing data to disk. Already wrote data in last %d seconds",
- WRITE_DATA_COOL_DOWN_SEC);
- return;
- }
- mLastWriteTimeNs = timeNs;
- for (auto& pair : mMetricsManagers) {
- WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason, dumpLatency);
- }
-}
-
-void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- WriteDataToDiskLocked(dumpReportReason, dumpLatency);
-}
-
-void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- mPullerManager->OnAlarmFired(timestampNs);
-}
-
-int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) {
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end()) {
- return 0;
- } else {
- return it->second->getLastReportTimeNs();
- }
-}
-
-void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk,
- const int uid, const int64_t version) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received app upgrade");
- StateManager::getInstance().notifyAppChanged(apk, mUidMap);
- for (const auto& it : mMetricsManagers) {
- it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version);
- }
-}
-
-void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
- const int uid) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received app removed");
- StateManager::getInstance().notifyAppChanged(apk, mUidMap);
- for (const auto& it : mMetricsManagers) {
- it.second->notifyAppRemoved(eventTimeNs, apk, uid);
- }
-}
-
-void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received uid map");
- StateManager::getInstance().updateLogSources(mUidMap);
- for (const auto& it : mMetricsManagers) {
- it.second->onUidMapReceived(eventTimeNs);
- }
-}
-
-void StatsLogProcessor::onStatsdInitCompleted(const int64_t& elapsedTimeNs) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- VLOG("Received boot completed signal");
- for (const auto& it : mMetricsManagers) {
- it.second->onStatsdInitCompleted(elapsedTimeNs);
- }
-}
-
-void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- mOnDiskDataConfigs.insert(key);
-}
-
-void StatsLogProcessor::setAnomalyAlarm(const int64_t elapsedTimeMillis) {
- std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
- mNextAnomalyAlarmTime = elapsedTimeMillis;
-}
-
-void StatsLogProcessor::cancelAnomalyAlarm() {
- std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
- mNextAnomalyAlarmTime = 0;
-}
-
-void StatsLogProcessor::informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis) {
- VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
- mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(elapsedTimeMillis / 1000));
- if (alarmSet.size() > 0) {
- VLOG("Found periodic alarm fired.");
- processFiredAnomalyAlarmsLocked(MillisToNano(elapsedTimeMillis), alarmSet);
- } else {
- ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
deleted file mode 100644
index 2384ed8f8ca8..000000000000
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include "config/ConfigListener.h"
-#include "logd/LogEvent.h"
-#include "metrics/MetricsManager.h"
-#include "packages/UidMap.h"
-#include "external/StatsPullerManager.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-
-#include <stdio.h>
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-class StatsLogProcessor : public ConfigListener, public virtual PackageInfoListener {
-public:
- StatsLogProcessor(const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor,
- const int64_t timeBaseNs,
- const std::function<bool(const ConfigKey&)>& sendBroadcast,
- const std::function<bool(const int&,
- const vector<int64_t>&)>& sendActivationBroadcast);
- virtual ~StatsLogProcessor();
-
- void OnLogEvent(LogEvent* event);
-
- void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config);
- void OnConfigRemoved(const ConfigKey& key);
-
- size_t GetMetricsSize(const ConfigKey& key) const;
-
- void GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs);
-
- void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- vector<uint8_t>* outData);
- void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency,
- ProtoOutputStream* proto);
-
- /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
- void onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
- /* Flushes data to disk. Data on memory will be gone after written to disk. */
- void WriteDataToDisk(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency);
-
- /* Persist configs containing metrics with active activations to disk. */
- void SaveActiveConfigsToDisk(int64_t currentTimeNs);
-
- /* Writes the current active status/ttl for all configs and metrics to ProtoOutputStream. */
- void WriteActiveConfigsToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- /* Load configs containing metrics with active activations from disk. */
- void LoadActiveConfigsFromDisk();
-
- /* Persist metadata for configs and metrics to disk. */
- void SaveMetadataToDisk(int64_t currentWallClockTimeNs, int64_t systemElapsedTimeNs);
-
- /* Writes the statsd metadata for all configs and metrics to StatsMetadataList. */
- void WriteMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList);
-
- /* Load stats metadata for configs and metrics from disk. */
- void LoadMetadataFromDisk(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
- /* Sets the metadata for all configs and metrics */
- void SetMetadataState(const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
- /* Sets the active status/ttl for all configs and metrics to the status in ActiveConfigList. */
- void SetConfigsActiveState(const ActiveConfigList& activeConfigList, int64_t currentTimeNs);
-
- /* Notify all MetricsManagers of app upgrades */
- void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
- const int64_t version) override;
-
- /* Notify all MetricsManagers of app removals */
- void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) override;
-
- /* Notify all MetricsManagers of uid map snapshots received */
- void onUidMapReceived(const int64_t& eventTimeNs) override;
-
- /* Notify all metrics managers of boot completed
- * This will force a bucket split when the boot is finished.
- */
- void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
-
- // Reset all configs.
- void resetConfigs();
-
- inline sp<UidMap> getUidMap() {
- return mUidMap;
- }
-
- void dumpStates(int outFd, bool verbose);
-
- void informPullAlarmFired(const int64_t timestampNs);
-
- int64_t getLastReportTimeNs(const ConfigKey& key);
-
- inline void setPrintLogs(bool enabled) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
- mPrintAllLogs = enabled;
- }
-
- // Add a specific config key to the possible configs to dump ASAP.
- void noteOnDiskData(const ConfigKey& key);
-
- void setAnomalyAlarm(const int64_t timeMillis);
-
- void cancelAnomalyAlarm();
-
-private:
- // For testing only.
- inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
- return mAnomalyAlarmMonitor;
- }
-
- inline sp<AlarmMonitor> getPeriodicAlarmMonitor() const {
- return mPeriodicAlarmMonitor;
- }
-
- mutable mutex mMetricsMutex;
-
- // Guards mNextAnomalyAlarmTime. A separate mutex is needed because alarms are set/cancelled
- // in the onLogEvent code path, which is locked by mMetricsMutex.
- // DO NOT acquire mMetricsMutex while holding mAnomalyAlarmMutex. This can lead to a deadlock.
- mutable mutex mAnomalyAlarmMutex;
-
- std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
-
- std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes;
-
- // Last time we sent a broadcast to this uid that the active configs had changed.
- std::unordered_map<int, int64_t> mLastActivationBroadcastTimes;
-
- // Tracks when we last checked the bytes consumed for each config key.
- std::unordered_map<ConfigKey, int64_t> mLastByteSizeTimes;
-
- // Tracks which config keys has metric reports on disk
- std::set<ConfigKey> mOnDiskDataConfigs;
-
- sp<UidMap> mUidMap; // Reference to the UidMap to lookup app name and version for each uid.
-
- sp<StatsPullerManager> mPullerManager; // Reference to StatsPullerManager
-
- sp<AlarmMonitor> mAnomalyAlarmMonitor;
-
- sp<AlarmMonitor> mPeriodicAlarmMonitor;
-
- void OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs);
-
- void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
-
- void OnConfigUpdatedLocked(
- const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
-
- void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
-
- void WriteActiveConfigsToProtoOutputStreamLocked(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- void SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
- int64_t currentTimeNs);
-
- void SetMetadataStateLocked(const metadata::StatsMetadataList& statsMetadataList,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
- void WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadataList* metadataList);
-
- void WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency);
-
- void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
- const DumpReportReason dumpReportReason,
- const DumpLatency dumpLatency);
-
- void onConfigMetricsReportLocked(
- const ConfigKey& key, const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket, const bool erase_data,
- const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
- /*if dataSavedToDisk is true, it indicates the caller will write the data to disk
- (e.g., before reboot). So no need to further persist local history.*/
- const bool dataSavedToDisk, vector<uint8_t>* proto);
-
- /* Check if we should send a broadcast if approaching memory limits and if we're over, we
- * actually delete the data. */
- void flushIfNecessaryLocked(const ConfigKey& key, MetricsManager& metricsManager);
-
- // Maps the isolated uid in the log event to host uid if the log event contains uid fields.
- void mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const;
-
- // Handler over the isolated uid change event.
- void onIsolatedUidChangedEventLocked(const LogEvent& event);
-
- // Handler over the binary push state changed event.
- void onBinaryPushStateChangedEventLocked(LogEvent* event);
-
- // Handler over the watchdog rollback occurred event.
- void onWatchdogRollbackOccurredLocked(LogEvent* event);
-
- // Updates train info on disk based on binary push state changed info and
- // write disk info into parameters.
- void getAndUpdateTrainInfoOnDisk(bool is_rollback, InstallTrainInfo* trainInfoIn);
-
- // Gets experiment ids on disk for associated train and updates them
- // depending on rollback type. Then writes them back to disk and returns
- // them.
- std::vector<int64_t> processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
- const string& packageName);
-
- // Reset all configs.
- void resetConfigsLocked(const int64_t timestampNs);
- // Reset the specified configs.
- void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
-
- // An anomaly alarm should have fired.
- // Check with anomaly alarm manager to find the alarms and process the result.
- void informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis);
-
- /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
- void processFiredAnomalyAlarmsLocked(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
- // Function used to send a broadcast so that receiver for the config key can call getData
- // to retrieve the stored data.
- std::function<bool(const ConfigKey& key)> mSendBroadcast;
-
- // Function used to send a broadcast so that receiver can be notified of which configs
- // are currently active.
- std::function<bool(const int& uid, const vector<int64_t>& configIds)> mSendActivationBroadcast;
-
- const int64_t mTimeBaseNs;
-
- // Largest timestamp of the events that we have processed.
- int64_t mLargestTimestampSeen = 0;
-
- int64_t mLastTimestampSeen = 0;
-
- int64_t mLastPullerCacheClearTimeSec = 0;
-
- // Last time we wrote data to disk.
- int64_t mLastWriteTimeNs = 0;
-
- // Last time we wrote active metrics to disk.
- int64_t mLastActiveMetricsWriteNs = 0;
-
- //Last time we wrote metadata to disk.
- int64_t mLastMetadataWriteNs = 0;
-
- // The time for the next anomaly alarm for alerts.
- int64_t mNextAnomalyAlarmTime = 0;
-
- bool mPrintAllLogs = false;
-
- FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
- FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
- FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
- FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
- FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
- FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
- FRIEND_TEST(StatsLogProcessorTest,
- TestActivationOnBootMultipleActivationsDifferentActivationTypes);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
- FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
- FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
-
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
- FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
- FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
- FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
- FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-
- FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
- FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
- FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
- FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
- FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
deleted file mode 100644
index fa5b4d1810d2..000000000000
--- a/cmds/statsd/src/StatsService.cpp
+++ /dev/null
@@ -1,1322 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsService.h"
-#include "stats_log_util.h"
-#include "android-base/stringprintf.h"
-#include "config/ConfigKey.h"
-#include "config/ConfigManager.h"
-#include "guardrail/StatsdStats.h"
-#include "storage/StorageManager.h"
-#include "subscriber/SubscriberReporter.h"
-
-#include <android-base/file.h>
-#include <android-base/strings.h>
-#include <cutils/multiuser.h>
-#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
-#include <frameworks/base/cmds/statsd/src/uid_data.pb.h>
-#include <private/android_filesystem_config.h>
-#include <statslog_statsd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/system_properties.h>
-#include <unistd.h>
-#include <utils/String16.h>
-
-using namespace android;
-
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_MESSAGE;
-
-using Status = ::ndk::ScopedAStatus;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-constexpr const char* kPermissionDump = "android.permission.DUMP";
-
-constexpr const char* kPermissionRegisterPullAtom = "android.permission.REGISTER_STATS_PULL_ATOM";
-
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-
-// for StatsDataDumpProto
-const int FIELD_ID_REPORTS_LIST = 1;
-
-static Status exception(int32_t code, const std::string& msg) {
- ALOGE("%s (%d)", msg.c_str(), code);
- return Status::fromExceptionCodeWithMessage(code, msg.c_str());
-}
-
-static bool checkPermission(const char* permission) {
- pid_t pid = AIBinder_getCallingPid();
- uid_t uid = AIBinder_getCallingUid();
- return checkPermissionForIds(permission, pid, uid);
-}
-
-Status checkUid(uid_t expectedUid) {
- uid_t uid = AIBinder_getCallingUid();
- if (uid == expectedUid || uid == AID_ROOT) {
- return Status::ok();
- } else {
- return exception(EX_SECURITY,
- StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
- }
-}
-
-#define ENFORCE_UID(uid) { \
- Status status = checkUid((uid)); \
- if (!status.isOk()) { \
- return status; \
- } \
-}
-
-StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
- : mAnomalyAlarmMonitor(new AlarmMonitor(
- MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
- [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) {
- mProcessor->setAnomalyAlarm(timeMillis);
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- },
- [this](const shared_ptr<IStatsCompanionService>& /*sc*/) {
- mProcessor->cancelAnomalyAlarm();
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- })),
- mPeriodicAlarmMonitor(new AlarmMonitor(
- MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
- [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
- if (sc != nullptr) {
- sc->setAlarmForSubscriberTriggering(timeMillis);
- StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
- }
- },
- [](const shared_ptr<IStatsCompanionService>& sc) {
- if (sc != nullptr) {
- sc->cancelAlarmForSubscriberTriggering();
- StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
- }
- })),
- mEventQueue(queue),
- mBootCompleteTrigger({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag},
- [this]() { mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); }),
- mStatsCompanionServiceDeathRecipient(
- AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) {
- mUidMap = UidMap::getInstance();
- mPullerManager = new StatsPullerManager();
- StatsPuller::SetUidMap(mUidMap);
- mConfigManager = new ConfigManager();
- mProcessor = new StatsLogProcessor(
- mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
- getElapsedRealtimeNs(),
- [this](const ConfigKey& key) {
- shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
- if (receiver == nullptr) {
- VLOG("Could not find a broadcast receiver for %s", key.ToString().c_str());
- return false;
- } else if (receiver->sendDataBroadcast(
- mProcessor->getLastReportTimeNs(key)).isOk()) {
- return true;
- } else {
- VLOG("Failed to send a broadcast for receiver %s", key.ToString().c_str());
- return false;
- }
- },
- [this](const int& uid, const vector<int64_t>& activeConfigs) {
- shared_ptr<IPendingIntentRef> receiver =
- mConfigManager->GetActiveConfigsChangedReceiver(uid);
- if (receiver == nullptr) {
- VLOG("Could not find receiver for uid %d", uid);
- return false;
- } else if (receiver->sendActiveConfigsChangedBroadcast(activeConfigs).isOk()) {
- VLOG("StatsService::active configs broadcast succeeded for uid %d" , uid);
- return true;
- } else {
- VLOG("StatsService::active configs broadcast failed for uid %d" , uid);
- return false;
- }
- });
-
- mUidMap->setListener(mProcessor);
- mConfigManager->AddListener(mProcessor);
-
- init_system_properties();
-
- if (mEventQueue != nullptr) {
- std::thread pushedEventThread([this] { readLogs(); });
- pushedEventThread.detach();
- }
-}
-
-StatsService::~StatsService() {
-}
-
-/* Runs on a dedicated thread to process pushed events. */
-void StatsService::readLogs() {
- // Read forever..... long live statsd
- while (1) {
- // Block until an event is available.
- auto event = mEventQueue->waitPop();
- // Pass it to StatsLogProcess to all configs/metrics
- // At this point, the LogEventQueue is not blocked, so that the socketListener
- // can read events from the socket and write to buffer to avoid data drop.
- mProcessor->OnLogEvent(event.get());
- // The ShellSubscriber is only used by shell for local debugging.
- if (mShellSubscriber != nullptr) {
- mShellSubscriber->onLogEvent(*event);
- }
- }
-}
-
-void StatsService::init_system_properties() {
- mEngBuild = false;
- const prop_info* buildType = __system_property_find("ro.build.type");
- if (buildType != NULL) {
- __system_property_read_callback(buildType, init_build_type_callback, this);
- }
-}
-
-void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
- uint32_t serial) {
- if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
- reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
- }
-}
-
-/**
- * Write data from statsd.
- * Format for statsdStats: adb shell dumpsys stats --metadata [-v] [--proto]
- * Format for data report: adb shell dumpsys stats [anything other than --metadata] [--proto]
- * Anything ending in --proto will be in proto format.
- * Anything without --metadata as the first argument will be report information.
- * (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
- * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
- */
-status_t StatsService::dump(int fd, const char** args, uint32_t numArgs) {
- if (!checkPermission(kPermissionDump)) {
- return PERMISSION_DENIED;
- }
-
- int lastArg = numArgs - 1;
- bool asProto = false;
- if (lastArg >= 0 && string(args[lastArg]) == "--proto") { // last argument
- asProto = true;
- lastArg--;
- }
- if (numArgs > 0 && string(args[0]) == "--metadata") { // first argument
- // Request is to dump statsd stats.
- bool verbose = false;
- if (lastArg >= 0 && string(args[lastArg]) == "-v") {
- verbose = true;
- lastArg--;
- }
- dumpStatsdStats(fd, verbose, asProto);
- } else {
- // Request is to dump statsd report data.
- if (asProto) {
- dumpIncidentSection(fd);
- } else {
- dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n");
- }
- }
-
- return NO_ERROR;
-}
-
-/**
- * Write debugging data about statsd in text or proto format.
- */
-void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) {
- if (proto) {
- vector<uint8_t> data;
- StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
- for (size_t i = 0; i < data.size(); i ++) {
- dprintf(out, "%c", data[i]);
- }
- } else {
- StatsdStats::getInstance().dumpStats(out);
- mProcessor->dumpStates(out, verbose);
- }
-}
-
-/**
- * Write stats report data in StatsDataDumpProto incident section format.
- */
-void StatsService::dumpIncidentSection(int out) {
- ProtoOutputStream proto;
- for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) {
- uint64_t reportsListToken =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST);
- // Don't include the current bucket to avoid skipping buckets.
- // If we need to include the current bucket later, consider changing to NO_TIME_CONSTRAINTS
- // or other alternatives to avoid skipping buckets for pulled metrics.
- mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
- false /* includeCurrentBucket */, false /* erase_data */,
- ADB_DUMP,
- FAST,
- &proto);
- proto.end(reportsListToken);
- proto.flush(out);
- proto.clear();
- }
-}
-
-/**
- * Implementation of the adb shell cmd stats command.
- */
-status_t StatsService::handleShellCommand(int in, int out, int err, const char** argv,
- uint32_t argc) {
- uid_t uid = AIBinder_getCallingUid();
- if (uid != AID_ROOT && uid != AID_SHELL) {
- return PERMISSION_DENIED;
- }
-
- Vector<String8> utf8Args;
- utf8Args.setCapacity(argc);
- for (uint32_t i = 0; i < argc; i++) {
- utf8Args.push(String8(argv[i]));
- }
-
- if (argc >= 1) {
- // adb shell cmd stats config ...
- if (!utf8Args[0].compare(String8("config"))) {
- return cmd_config(in, out, err, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("print-uid-map"))) {
- return cmd_print_uid_map(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("dump-report"))) {
- return cmd_dump_report(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("pull-source")) && argc > 1) {
- return cmd_print_pulled_metrics(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("send-broadcast"))) {
- return cmd_trigger_broadcast(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("print-stats"))) {
- return cmd_print_stats(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("meminfo"))) {
- return cmd_dump_memory_info(out);
- }
-
- if (!utf8Args[0].compare(String8("write-to-disk"))) {
- return cmd_write_data_to_disk(out);
- }
-
- if (!utf8Args[0].compare(String8("log-app-breadcrumb"))) {
- return cmd_log_app_breadcrumb(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("log-binary-push"))) {
- return cmd_log_binary_push(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("clear-puller-cache"))) {
- return cmd_clear_puller_cache(out);
- }
-
- if (!utf8Args[0].compare(String8("print-logs"))) {
- return cmd_print_logs(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("send-active-configs"))) {
- return cmd_trigger_active_config_broadcast(out, utf8Args);
- }
-
- if (!utf8Args[0].compare(String8("data-subscribe"))) {
- {
- std::lock_guard<std::mutex> lock(mShellSubscriberMutex);
- if (mShellSubscriber == nullptr) {
- mShellSubscriber = new ShellSubscriber(mUidMap, mPullerManager);
- }
- }
- int timeoutSec = -1;
- if (argc >= 2) {
- timeoutSec = atoi(utf8Args[1].c_str());
- }
- mShellSubscriber->startNewSubscription(in, out, timeoutSec);
- return NO_ERROR;
- }
- }
-
- print_cmd_help(out);
- return NO_ERROR;
-}
-
-void StatsService::print_cmd_help(int out) {
- dprintf(out,
- "usage: adb shell cmd stats print-stats-log [tag_required] "
- "[timestamp_nsec_optional]\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats meminfo\n");
- dprintf(out, "\n");
- dprintf(out, " Prints the malloc debug information. You need to run the following first: \n");
- dprintf(out, " # adb shell stop\n");
- dprintf(out, " # adb shell setprop libc.debug.malloc.program statsd \n");
- dprintf(out, " # adb shell setprop libc.debug.malloc.options backtrace \n");
- dprintf(out, " # adb shell start\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
- dprintf(out, "\n");
- dprintf(out, " Prints the UID, app name, version mapping.\n");
- dprintf(out, " PKG Optional package name to print the uids of the package\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats pull-source ATOM_TAG [PACKAGE] \n");
- dprintf(out, "\n");
- dprintf(out, " Prints the output of a pulled atom\n");
- dprintf(out, " UID The atom to pull\n");
- dprintf(out, " PACKAGE The package to pull from. Default is AID_SYSTEM\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats write-to-disk \n");
- dprintf(out, "\n");
- dprintf(out, " Flushes all data on memory to disk.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
- dprintf(out, " Writes an AppBreadcrumbReported event to the statslog buffer.\n");
- dprintf(out, " UID The uid to use. It is only possible to pass a UID\n");
- dprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
- dprintf(out, " uid is used.\n");
- dprintf(out, " LABEL Integer in [0, 15], as per atoms.proto.\n");
- dprintf(out, " STATE Integer in [0, 3], as per atoms.proto.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out,
- "usage: adb shell cmd stats log-binary-push NAME VERSION STAGING ROLLBACK_ENABLED "
- "LOW_LATENCY STATE EXPERIMENT_IDS\n");
- dprintf(out, " Log a binary push state changed event.\n");
- dprintf(out, " NAME The train name.\n");
- dprintf(out, " VERSION The train version code.\n");
- dprintf(out, " STAGING If this train requires a restart.\n");
- dprintf(out, " ROLLBACK_ENABLED If rollback should be enabled for this install.\n");
- dprintf(out, " LOW_LATENCY If the train requires low latency monitoring.\n");
- dprintf(out, " STATE The status of the train push.\n");
- dprintf(out, " Integer value of the enum in atoms.proto.\n");
- dprintf(out, " EXPERIMENT_IDS Comma separated list of experiment ids.\n");
- dprintf(out, " Leave blank for none.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
- dprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
- dprintf(out, "\n");
- dprintf(out, " Adds, updates or removes a configuration. The proto should be in\n");
- dprintf(out, " wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
- dprintf(out, " provided, then all configs will be removed from memory and disk.\n");
- dprintf(out, "\n");
- dprintf(out, " UID The uid to use. It is only possible to pass the UID\n");
- dprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
- dprintf(out, " uid is used.\n");
- dprintf(out, " NAME The per-uid name to use\n");
- dprintf(out, "\n");
- dprintf(out, "\n *Note: If both UID and NAME are omitted then all configs will\n");
- dprintf(out, "\n be removed from memory and disk!\n");
- dprintf(out, "\n");
- dprintf(out,
- "usage: adb shell cmd stats dump-report [UID] NAME [--keep_data] "
- "[--include_current_bucket] [--proto]\n");
- dprintf(out, " Dump all metric data for a configuration.\n");
- dprintf(out, " UID The uid of the configuration. It is only possible to pass\n");
- dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
- dprintf(out, " calling uid is used.\n");
- dprintf(out, " NAME The name of the configuration\n");
- dprintf(out, " --keep_data Do NOT erase the data upon dumping it.\n");
- dprintf(out, " --proto Print proto binary.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
- dprintf(out, " Send a broadcast that triggers the subscriber to fetch metrics.\n");
- dprintf(out, " UID The uid of the configuration. It is only possible to pass\n");
- dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
- dprintf(out, " calling uid is used.\n");
- dprintf(out, " NAME The name of the configuration\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out,
- "usage: adb shell cmd stats send-active-configs [--uid=UID] [--configs] "
- "[NAME1] [NAME2] [NAME3..]\n");
- dprintf(out, " Send a broadcast that informs the subscriber of the current active configs.\n");
- dprintf(out, " --uid=UID The uid of the configurations. It is only possible to pass\n");
- dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
- dprintf(out, " calling uid is used.\n");
- dprintf(out, " --configs Send the list of configs in the name list instead of\n");
- dprintf(out, " the currently active configs\n");
- dprintf(out, " NAME LIST List of configuration names to be included in the broadcast.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats print-stats\n");
- dprintf(out, " Prints some basic stats.\n");
- dprintf(out, " --proto Print proto binary instead of string format.\n");
- dprintf(out, "\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
- dprintf(out, " Clear cached puller data.\n");
- dprintf(out, "\n");
- dprintf(out, "usage: adb shell cmd stats print-logs\n");
- dprintf(out, " Requires root privileges.\n");
- dprintf(out, " Can be disabled by calling adb shell cmd stats print-logs 0\n");
-}
-
-status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) {
- string name;
- bool good = false;
- int uid;
- const int argCount = args.size();
- if (argCount == 2) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- name.assign(args[1].c_str(), args[1].size());
- good = true;
- } else if (argCount == 3) {
- good = getUidFromArgs(args, 1, uid);
- if (!good) {
- dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
- "other UIDs on eng or userdebug builds.\n");
- }
- name.assign(args[2].c_str(), args[2].size());
- }
- if (!good) {
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
- ConfigKey key(uid, StrToInt64(name));
- shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
- if (receiver == nullptr) {
- VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str());
- return UNKNOWN_ERROR;
- } else if (receiver->sendDataBroadcast(mProcessor->getLastReportTimeNs(key)).isOk()) {
- VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
- args[2].c_str());
- } else {
- VLOG("StatsService::trigger broadcast failed to %s, %s", args[1].c_str(), args[2].c_str());
- return UNKNOWN_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_trigger_active_config_broadcast(int out, Vector<String8>& args) {
- const int argCount = args.size();
- int uid;
- vector<int64_t> configIds;
- if (argCount == 1) {
- // Automatically pick the uid and send a broadcast that has no active configs.
- uid = AIBinder_getCallingUid();
- mProcessor->GetActiveConfigs(uid, configIds);
- } else {
- int curArg = 1;
- if(args[curArg].find("--uid=") == 0) {
- string uidArgStr(args[curArg].c_str());
- string uidStr = uidArgStr.substr(6);
- if (!getUidFromString(uidStr.c_str(), uid)) {
- dprintf(out, "Invalid UID. Note that the config can only be set for "
- "other UIDs on eng or userdebug builds.\n");
- return UNKNOWN_ERROR;
- }
- curArg++;
- } else {
- uid = AIBinder_getCallingUid();
- }
- if (curArg == argCount || args[curArg] != "--configs") {
- VLOG("Reached end of args, or specify configs not set. Sending actual active configs,");
- mProcessor->GetActiveConfigs(uid, configIds);
- } else {
- // Flag specified, use the given list of configs.
- curArg++;
- for (int i = curArg; i < argCount; i++) {
- char* endp;
- int64_t configID = strtoll(args[i].c_str(), &endp, 10);
- if (endp == args[i].c_str() || *endp != '\0') {
- dprintf(out, "Error parsing config ID.\n");
- return UNKNOWN_ERROR;
- }
- VLOG("Adding config id %ld", static_cast<long>(configID));
- configIds.push_back(configID);
- }
- }
- }
- shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
- if (receiver == nullptr) {
- VLOG("Could not find receiver for uid %d", uid);
- return UNKNOWN_ERROR;
- } else if (receiver->sendActiveConfigsChangedBroadcast(configIds).isOk()) {
- VLOG("StatsService::trigger active configs changed broadcast succeeded for uid %d" , uid);
- } else {
- VLOG("StatsService::trigger active configs changed broadcast failed for uid %d", uid);
- return UNKNOWN_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& args) {
- const int argCount = args.size();
- if (argCount >= 2) {
- if (args[1] == "update" || args[1] == "remove") {
- bool good = false;
- int uid = -1;
- string name;
-
- if (argCount == 3) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- name.assign(args[2].c_str(), args[2].size());
- good = true;
- } else if (argCount == 4) {
- good = getUidFromArgs(args, 2, uid);
- if (!good) {
- dprintf(err, "Invalid UID. Note that the config can only be set for "
- "other UIDs on eng or userdebug builds.\n");
- }
- name.assign(args[3].c_str(), args[3].size());
- } else if (argCount == 2 && args[1] == "remove") {
- good = true;
- }
-
- if (!good) {
- // If arg parsing failed, print the help text and return an error.
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
-
- if (args[1] == "update") {
- char* endp;
- int64_t configID = strtoll(name.c_str(), &endp, 10);
- if (endp == name.c_str() || *endp != '\0') {
- dprintf(err, "Error parsing config ID.\n");
- return UNKNOWN_ERROR;
- }
-
- // Read stream into buffer.
- string buffer;
- if (!android::base::ReadFdToString(in, &buffer)) {
- dprintf(err, "Error reading stream for StatsConfig.\n");
- return UNKNOWN_ERROR;
- }
-
- // Parse buffer.
- StatsdConfig config;
- if (!config.ParseFromString(buffer)) {
- dprintf(err, "Error parsing proto stream for StatsConfig.\n");
- return UNKNOWN_ERROR;
- }
-
- // Add / update the config.
- mConfigManager->UpdateConfig(ConfigKey(uid, configID), config);
- } else {
- if (argCount == 2) {
- cmd_remove_all_configs(out);
- } else {
- // Remove the config.
- mConfigManager->RemoveConfig(ConfigKey(uid, StrToInt64(name)));
- }
- }
-
- return NO_ERROR;
- }
- }
- print_cmd_help(out);
- return UNKNOWN_ERROR;
-}
-
-status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) {
- if (mProcessor != nullptr) {
- int argCount = args.size();
- bool good = false;
- bool proto = false;
- bool includeCurrentBucket = false;
- bool eraseData = true;
- int uid;
- string name;
- if (!std::strcmp("--proto", args[argCount-1].c_str())) {
- proto = true;
- argCount -= 1;
- }
- if (!std::strcmp("--include_current_bucket", args[argCount-1].c_str())) {
- includeCurrentBucket = true;
- argCount -= 1;
- }
- if (!std::strcmp("--keep_data", args[argCount-1].c_str())) {
- eraseData = false;
- argCount -= 1;
- }
- if (argCount == 2) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- name.assign(args[1].c_str(), args[1].size());
- good = true;
- } else if (argCount == 3) {
- good = getUidFromArgs(args, 1, uid);
- if (!good) {
- dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
- "other UIDs on eng or userdebug builds.\n");
- }
- name.assign(args[2].c_str(), args[2].size());
- }
- if (good) {
- vector<uint8_t> data;
- mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
- includeCurrentBucket, eraseData, ADB_DUMP,
- NO_TIME_CONSTRAINTS,
- &data);
- if (proto) {
- for (size_t i = 0; i < data.size(); i ++) {
- dprintf(out, "%c", data[i]);
- }
- } else {
- dprintf(out, "Non-proto stats data dump not currently supported.\n");
- }
- return android::OK;
- } else {
- // If arg parsing failed, print the help text and return an error.
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
- } else {
- dprintf(out, "Log processor does not exist...\n");
- return UNKNOWN_ERROR;
- }
-}
-
-status_t StatsService::cmd_print_stats(int out, const Vector<String8>& args) {
- int argCount = args.size();
- bool proto = false;
- if (!std::strcmp("--proto", args[argCount-1].c_str())) {
- proto = true;
- argCount -= 1;
- }
- StatsdStats& statsdStats = StatsdStats::getInstance();
- if (proto) {
- vector<uint8_t> data;
- statsdStats.dumpStats(&data, false); // does not reset statsdStats.
- for (size_t i = 0; i < data.size(); i ++) {
- dprintf(out, "%c", data[i]);
- }
-
- } else {
- vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
- for (const ConfigKey& key : configs) {
- dprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
- mProcessor->GetMetricsSize(key));
- }
- statsdStats.dumpStats(out);
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_print_uid_map(int out, const Vector<String8>& args) {
- if (args.size() > 1) {
- string pkg;
- pkg.assign(args[1].c_str(), args[1].size());
- auto uids = mUidMap->getAppUid(pkg);
- dprintf(out, "%s -> [ ", pkg.c_str());
- for (const auto& uid : uids) {
- dprintf(out, "%d ", uid);
- }
- dprintf(out, "]\n");
- } else {
- mUidMap->printUidMap(out);
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_write_data_to_disk(int out) {
- dprintf(out, "Writing data to disk\n");
- mProcessor->WriteDataToDisk(ADB_DUMP, NO_TIME_CONSTRAINTS);
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& args) {
- bool good = false;
- int32_t uid;
- int32_t label;
- int32_t state;
- const int argCount = args.size();
- if (argCount == 3) {
- // Automatically pick the UID
- uid = AIBinder_getCallingUid();
- label = atoi(args[1].c_str());
- state = atoi(args[2].c_str());
- good = true;
- } else if (argCount == 4) {
- good = getUidFromArgs(args, 1, uid);
- if (!good) {
- dprintf(out,
- "Invalid UID. Note that selecting a UID for writing AppBreadcrumb can only be "
- "done for other UIDs on eng or userdebug builds.\n");
- }
- label = atoi(args[2].c_str());
- state = atoi(args[3].c_str());
- }
- if (good) {
- dprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
- android::os::statsd::util::stats_write(
- android::os::statsd::util::APP_BREADCRUMB_REPORTED, uid, label, state);
- } else {
- print_cmd_help(out);
- return UNKNOWN_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_log_binary_push(int out, const Vector<String8>& args) {
- // Security checks are done in the sendBinaryPushStateChanged atom.
- const int argCount = args.size();
- if (argCount != 7 && argCount != 8) {
- dprintf(out, "Incorrect number of argument supplied\n");
- return UNKNOWN_ERROR;
- }
- string trainName = string(args[1].c_str());
- int64_t trainVersion = strtoll(args[2].c_str(), nullptr, 10);
- int32_t state = atoi(args[6].c_str());
- vector<int64_t> experimentIds;
- if (argCount == 8) {
- vector<string> experimentIdsString = android::base::Split(string(args[7].c_str()), ",");
- for (string experimentIdString : experimentIdsString) {
- int64_t experimentId = strtoll(experimentIdString.c_str(), nullptr, 10);
- experimentIds.push_back(experimentId);
- }
- }
- dprintf(out, "Logging BinaryPushStateChanged\n");
- vector<uint8_t> experimentIdBytes;
- writeExperimentIdsToProto(experimentIds, &experimentIdBytes);
- LogEvent event(trainName, trainVersion, args[3], args[4], args[5], state, experimentIdBytes, 0);
- mProcessor->OnLogEvent(&event);
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_print_pulled_metrics(int out, const Vector<String8>& args) {
- int s = atoi(args[1].c_str());
- vector<int32_t> uids;
- if (args.size() > 2) {
- string package = string(args[2].c_str());
- auto it = UidMap::sAidToUidMapping.find(package);
- if (it != UidMap::sAidToUidMapping.end()) {
- uids.push_back(it->second);
- } else {
- set<int32_t> uids_set = mUidMap->getAppUid(package);
- uids.insert(uids.end(), uids_set.begin(), uids_set.end());
- }
- } else {
- uids.push_back(AID_SYSTEM);
- }
- vector<shared_ptr<LogEvent>> stats;
- if (mPullerManager->Pull(s, uids, getElapsedRealtimeNs(), &stats)) {
- for (const auto& it : stats) {
- dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
- }
- dprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
- return NO_ERROR;
- }
- return UNKNOWN_ERROR;
-}
-
-status_t StatsService::cmd_remove_all_configs(int out) {
- dprintf(out, "Removing all configs...\n");
- VLOG("StatsService::cmd_remove_all_configs was called");
- mConfigManager->RemoveAllConfigs();
- StorageManager::deleteAllFiles(STATS_SERVICE_DIR);
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_dump_memory_info(int out) {
- dprintf(out, "meminfo not available.\n");
- return NO_ERROR;
-}
-
-status_t StatsService::cmd_clear_puller_cache(int out) {
- VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
- AIBinder_getCallingPid(), AIBinder_getCallingUid());
- if (checkPermission(kPermissionDump)) {
- int cleared = mPullerManager->ForceClearPullerCache();
- dprintf(out, "Puller removed %d cached data!\n", cleared);
- return NO_ERROR;
- } else {
- return PERMISSION_DENIED;
- }
-}
-
-status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
- Status status = checkUid(AID_ROOT);
- if (!status.isOk()) {
- return PERMISSION_DENIED;
- }
-
- VLOG("StatsService::cmd_print_logs with pid %i, uid %i", AIBinder_getCallingPid(),
- AIBinder_getCallingUid());
- bool enabled = true;
- if (args.size() >= 2) {
- enabled = atoi(args[1].c_str()) != 0;
- }
- mProcessor->setPrintLogs(enabled);
- return NO_ERROR;
-}
-
-bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) {
- return getUidFromString(args[uidArgIndex].c_str(), uid);
-}
-
-bool StatsService::getUidFromString(const char* s, int32_t& uid) {
- if (*s == '\0') {
- return false;
- }
- char* endc = NULL;
- int64_t longUid = strtol(s, &endc, 0);
- if (*endc != '\0') {
- return false;
- }
- int32_t goodUid = static_cast<int32_t>(longUid);
- if (longUid < 0 || static_cast<uint64_t>(longUid) != static_cast<uid_t>(goodUid)) {
- return false; // It was not of uid_t type.
- }
- uid = goodUid;
-
- int32_t callingUid = AIBinder_getCallingUid();
- return mEngBuild // UserDebug/EngBuild are allowed to impersonate uids.
- || (callingUid == goodUid) // Anyone can 'impersonate' themselves.
- || (callingUid == AID_ROOT && goodUid == AID_SHELL); // ROOT can impersonate SHELL.
-}
-
-Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) {
- ENFORCE_UID(AID_SYSTEM);
- // Read stream into buffer.
- string buffer;
- if (!android::base::ReadFdToString(fd.get(), &buffer)) {
- return exception(EX_ILLEGAL_ARGUMENT, "Failed to read all data from the pipe.");
- }
-
- // Parse buffer.
- UidData uidData;
- if (!uidData.ParseFromString(buffer)) {
- return exception(EX_ILLEGAL_ARGUMENT, "Error parsing proto stream for UidData.");
- }
-
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> packageNames;
- vector<int32_t> uids;
- vector<int64_t> versions;
-
- const auto numEntries = uidData.app_info_size();
- versionStrings.reserve(numEntries);
- installers.reserve(numEntries);
- packageNames.reserve(numEntries);
- uids.reserve(numEntries);
- versions.reserve(numEntries);
-
- for (const auto& appInfo: uidData.app_info()) {
- packageNames.emplace_back(String16(appInfo.package_name().c_str()));
- uids.push_back(appInfo.uid());
- versions.push_back(appInfo.version());
- versionStrings.emplace_back(String16(appInfo.version_string().c_str()));
- installers.emplace_back(String16(appInfo.installer().c_str()));
- }
-
- mUidMap->updateMap(getElapsedRealtimeNs(),
- uids,
- versions,
- versionStrings,
- packageNames,
- installers);
-
- mBootCompleteTrigger.markComplete(kUidMapReceivedTag);
- VLOG("StatsService::informAllUidData UidData proto parsed successfully.");
- return Status::ok();
-}
-
-Status StatsService::informOnePackage(const string& app, int32_t uid, int64_t version,
- const string& versionString, const string& installer) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informOnePackage was called");
- String16 utf16App = String16(app.c_str());
- String16 utf16VersionString = String16(versionString.c_str());
- String16 utf16Installer = String16(installer.c_str());
-
- mUidMap->updateApp(getElapsedRealtimeNs(), utf16App, uid, version, utf16VersionString,
- utf16Installer);
- return Status::ok();
-}
-
-Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informOnePackageRemoved was called");
- String16 utf16App = String16(app.c_str());
- mUidMap->removeApp(getElapsedRealtimeNs(), utf16App, uid);
- mConfigManager->RemoveConfigs(uid);
- return Status::ok();
-}
-
-Status StatsService::informAlarmForSubscriberTriggeringFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
- int64_t currentTimeSec = getElapsedRealtimeSec();
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
- mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- if (alarmSet.size() > 0) {
- VLOG("Found periodic alarm fired.");
- mProcessor->onPeriodicAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
- } else {
- ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
- }
- return Status::ok();
-}
-
-Status StatsService::informPollAlarmFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informPollAlarmFired was called");
- mProcessor->informPullAlarmFired(getElapsedRealtimeNs());
- VLOG("StatsService::informPollAlarmFired succeeded");
- return Status::ok();
-}
-
-Status StatsService::systemRunning() {
- ENFORCE_UID(AID_SYSTEM);
-
- // When system_server is up and running, schedule the dropbox task to run.
- VLOG("StatsService::systemRunning");
- sayHiToStatsCompanion();
- return Status::ok();
-}
-
-Status StatsService::informDeviceShutdown() {
- ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::informDeviceShutdown");
- mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST);
- mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
- mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
- return Status::ok();
-}
-
-void StatsService::sayHiToStatsCompanion() {
- shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
- if (statsCompanion != nullptr) {
- VLOG("Telling statsCompanion that statsd is ready");
- statsCompanion->statsdReady();
- } else {
- VLOG("Could not access statsCompanion");
- }
-}
-
-Status StatsService::statsCompanionReady() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::statsCompanionReady was called");
- shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
- if (statsCompanion == nullptr) {
- return exception(EX_NULL_POINTER,
- "StatsCompanion unavailable despite it contacting statsd.");
- }
- VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
- AIBinder_linkToDeath(statsCompanion->asBinder().get(),
- mStatsCompanionServiceDeathRecipient.get(), this);
- mPullerManager->SetStatsCompanionService(statsCompanion);
- mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
- mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
- return Status::ok();
-}
-
-Status StatsService::bootCompleted() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::bootCompleted was called");
- mBootCompleteTrigger.markComplete(kBootCompleteTag);
- return Status::ok();
-}
-
-void StatsService::Startup() {
- mConfigManager->Startup();
- mProcessor->LoadActiveConfigsFromDisk();
- mProcessor->LoadMetadataFromDisk(getWallClockNs(), getElapsedRealtimeNs());
-}
-
-void StatsService::Terminate() {
- ALOGI("StatsService::Terminating");
- if (mProcessor != nullptr) {
- mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST);
- mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
- mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
- }
-}
-
-// Test only interface!!!
-void StatsService::OnLogEvent(LogEvent* event) {
- mProcessor->OnLogEvent(event);
- if (mShellSubscriber != nullptr) {
- mShellSubscriber->onLogEvent(*event);
- }
-}
-
-Status StatsService::getData(int64_t key, const int32_t callingUid, vector<int8_t>* output) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::getData with Uid %i", callingUid);
- ConfigKey configKey(callingUid, key);
- // TODO(b/149254662): Since libbinder_ndk uses int8_t instead of uint8_t,
- // there are inconsistencies with internal statsd logic. Instead of
- // modifying lots of files, we create a temporary output array of int8_t and
- // copy its data into output. This is a bad hack, but hopefully
- // libbinder_ndk will transition to using uint8_t soon: progress is tracked
- // in b/144957764. Same applies to StatsService::getMetadata.
- vector<uint8_t> unsignedOutput;
- // The dump latency does not matter here since we do not include the current bucket, we do not
- // need to pull any new data anyhow.
- mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
- true /* erase_data */, GET_DATA_CALLED, FAST, &unsignedOutput);
- *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
- return Status::ok();
-}
-
-Status StatsService::getMetadata(vector<int8_t>* output) {
- ENFORCE_UID(AID_SYSTEM);
-
- vector<uint8_t> unsignedOutput;
- StatsdStats::getInstance().dumpStats(&unsignedOutput, false); // Don't reset the counters.
- *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
- return Status::ok();
-}
-
-Status StatsService::addConfiguration(int64_t key, const vector <int8_t>& config,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- if (addConfigurationChecked(callingUid, key, config)) {
- return Status::ok();
- } else {
- return exception(EX_ILLEGAL_ARGUMENT, "Could not parse malformatted StatsdConfig.");
- }
-}
-
-bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config) {
- ConfigKey configKey(uid, key);
- StatsdConfig cfg;
- if (config.size() > 0) { // If the config is empty, skip parsing.
- if (!cfg.ParseFromArray(&config[0], config.size())) {
- return false;
- }
- }
- mConfigManager->UpdateConfig(configKey, cfg);
- return true;
-}
-
-Status StatsService::removeDataFetchOperation(int64_t key,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
- ConfigKey configKey(callingUid, key);
- mConfigManager->RemoveConfigReceiver(configKey);
- return Status::ok();
-}
-
-Status StatsService::setDataFetchOperation(int64_t key,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- ConfigKey configKey(callingUid, key);
- mConfigManager->SetConfigReceiver(configKey, pir);
- if (StorageManager::hasConfigMetricsReport(configKey)) {
- VLOG("StatsService::setDataFetchOperation marking configKey %s to dump reports on disk",
- configKey.ToString().c_str());
- mProcessor->noteOnDiskData(configKey);
- }
- return Status::ok();
-}
-
-Status StatsService::setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid,
- vector<int64_t>* output) {
- ENFORCE_UID(AID_SYSTEM);
-
- mConfigManager->SetActiveConfigsChangedReceiver(callingUid, pir);
- if (output != nullptr) {
- mProcessor->GetActiveConfigs(callingUid, *output);
- } else {
- ALOGW("StatsService::setActiveConfigsChanged output was nullptr");
- }
- return Status::ok();
-}
-
-Status StatsService::removeActiveConfigsChangedOperation(const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- mConfigManager->RemoveActiveConfigsChangedReceiver(callingUid);
- return Status::ok();
-}
-
-Status StatsService::removeConfiguration(int64_t key, const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- ConfigKey configKey(callingUid, key);
- mConfigManager->RemoveConfig(configKey);
- return Status::ok();
-}
-
-Status StatsService::setBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::setBroadcastSubscriber called.");
- ConfigKey configKey(callingUid, configId);
- SubscriberReporter::getInstance()
- .setBroadcastSubscriber(configKey, subscriberId, pir);
- return Status::ok();
-}
-
-Status StatsService::unsetBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const int32_t callingUid) {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::unsetBroadcastSubscriber called.");
- ConfigKey configKey(callingUid, configId);
- SubscriberReporter::getInstance()
- .unsetBroadcastSubscriber(configKey, subscriberId);
- return Status::ok();
-}
-
-Status StatsService::allPullersFromBootRegistered() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::allPullersFromBootRegistered was called");
- mBootCompleteTrigger.markComplete(kAllPullersRegisteredTag);
- return Status::ok();
-}
-
-Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownMillis,
- int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) {
- ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::registerPullAtomCallback called.");
- mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
- MillisToNano(timeoutMillis), additiveFields,
- pullerCallback);
- return Status::ok();
-}
-
-Status StatsService::registerNativePullAtomCallback(
- int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) {
- if (!checkPermission(kPermissionRegisterPullAtom)) {
- return exception(
- EX_SECURITY,
- StringPrintf("Uid %d does not have the %s permission when registering atom %d",
- AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
- }
- VLOG("StatsService::registerNativePullAtomCallback called.");
- int32_t uid = AIBinder_getCallingUid();
- mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
- MillisToNano(timeoutMillis), additiveFields,
- pullerCallback);
- return Status::ok();
-}
-
-Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
- ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::unregisterPullAtomCallback called.");
- mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
- return Status::ok();
-}
-
-Status StatsService::unregisterNativePullAtomCallback(int32_t atomTag) {
- if (!checkPermission(kPermissionRegisterPullAtom)) {
- return exception(
- EX_SECURITY,
- StringPrintf("Uid %d does not have the %s permission when unregistering atom %d",
- AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
- }
- VLOG("StatsService::unregisterNativePullAtomCallback called.");
- int32_t uid = AIBinder_getCallingUid();
- mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
- return Status::ok();
-}
-
-Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
- ENFORCE_UID(AID_SYSTEM);
- // TODO: add verifier permission
-
- experimentIdsOut->clear();
- // Read the latest train info
- vector<InstallTrainInfo> trainInfoList = StorageManager::readAllTrainInfo();
- if (trainInfoList.empty()) {
- // No train info means no experiment IDs, return an empty list
- return Status::ok();
- }
-
- // Copy the experiment IDs to the out vector
- for (InstallTrainInfo& trainInfo : trainInfoList) {
- experimentIdsOut->insert(experimentIdsOut->end(),
- trainInfo.experimentIds.begin(),
- trainInfo.experimentIds.end());
- }
- return Status::ok();
-}
-
-void StatsService::statsCompanionServiceDied(void* cookie) {
- auto thiz = static_cast<StatsService*>(cookie);
- thiz->statsCompanionServiceDiedImpl();
-}
-
-void StatsService::statsCompanionServiceDiedImpl() {
- ALOGW("statscompanion service died");
- StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
- if (mProcessor != nullptr) {
- ALOGW("Reset statsd upon system server restarts.");
- int64_t systemServerRestartNs = getElapsedRealtimeNs();
- ProtoOutputStream activeConfigsProto;
- mProcessor->WriteActiveConfigsToProtoOutputStream(systemServerRestartNs,
- STATSCOMPANION_DIED, &activeConfigsProto);
- metadata::StatsMetadataList metadataList;
- mProcessor->WriteMetadataToProto(getWallClockNs(),
- systemServerRestartNs, &metadataList);
- mProcessor->WriteDataToDisk(STATSCOMPANION_DIED, FAST);
- mProcessor->resetConfigs();
-
- std::string serializedActiveConfigs;
- if (activeConfigsProto.serializeToString(&serializedActiveConfigs)) {
- ActiveConfigList activeConfigs;
- if (activeConfigs.ParseFromString(serializedActiveConfigs)) {
- mProcessor->SetConfigsActiveState(activeConfigs, systemServerRestartNs);
- }
- }
- mProcessor->SetMetadataState(metadataList, getWallClockNs(), systemServerRestartNs);
- }
- mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
- mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
- mPullerManager->SetStatsCompanionService(nullptr);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
deleted file mode 100644
index ad66d0f1c472..000000000000
--- a/cmds/statsd/src/StatsService.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STATS_SERVICE_H
-#define STATS_SERVICE_H
-
-#include <aidl/android/os/BnStatsd.h>
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <gtest/gtest_prod.h>
-#include <utils/Looper.h>
-
-#include <mutex>
-
-#include "StatsLogProcessor.h"
-#include "anomaly/AlarmMonitor.h"
-#include "config/ConfigManager.h"
-#include "external/StatsPullerManager.h"
-#include "logd/LogEventQueue.h"
-#include "packages/UidMap.h"
-#include "shell/ShellSubscriber.h"
-#include "statscompanion_util.h"
-#include "utils/MultiConditionTrigger.h"
-
-using namespace android;
-using namespace android::os;
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnStatsd;
-using aidl::android::os::IPendingIntentRef;
-using aidl::android::os::IPullAtomCallback;
-using ::ndk::ScopedAIBinder_DeathRecipient;
-using ::ndk::ScopedFileDescriptor;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsService : public BnStatsd {
-public:
- StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue);
- virtual ~StatsService();
-
- /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
- const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
-
- virtual status_t dump(int fd, const char** args, uint32_t numArgs) override;
- virtual status_t handleShellCommand(int in, int out, int err, const char** argv,
- uint32_t argc) override;
-
- virtual Status systemRunning();
- virtual Status statsCompanionReady();
- virtual Status bootCompleted();
- virtual Status informPollAlarmFired();
- virtual Status informAlarmForSubscriberTriggeringFired();
-
- virtual Status informAllUidData(const ScopedFileDescriptor& fd);
- virtual Status informOnePackage(const string& app, int32_t uid, int64_t version,
- const string& versionString, const string& installer);
- virtual Status informOnePackageRemoved(const string& app, int32_t uid);
- virtual Status informDeviceShutdown();
-
- /**
- * Called right before we start processing events.
- */
- void Startup();
-
- /**
- * Called when terminiation signal received.
- */
- void Terminate();
-
- /**
- * Test ONLY interface. In real world, StatsService reads from LogEventQueue.
- */
- virtual void OnLogEvent(LogEvent* event);
-
- /**
- * Binder call for clients to request data for this configuration key.
- */
- virtual Status getData(int64_t key,
- const int32_t callingUid,
- vector<int8_t>* output) override;
-
-
- /**
- * Binder call for clients to get metadata across all configs in statsd.
- */
- virtual Status getMetadata(vector<int8_t>* output) override;
-
-
- /**
- * Binder call to let clients send a configuration and indicate they're interested when they
- * should requestData for this configuration.
- */
- virtual Status addConfiguration(int64_t key,
- const vector<int8_t>& config,
- const int32_t callingUid) override;
-
- /**
- * Binder call to let clients register the data fetch operation for a configuration.
- */
- virtual Status setDataFetchOperation(int64_t key,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) override;
-
- /**
- * Binder call to remove the data fetch operation for the specified config key.
- */
- virtual Status removeDataFetchOperation(int64_t key,
- const int32_t callingUid) override;
-
- /**
- * Binder call to let clients register the active configs changed operation.
- */
- virtual Status setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid,
- vector<int64_t>* output) override;
-
- /**
- * Binder call to remove the active configs changed operation for the specified package..
- */
- virtual Status removeActiveConfigsChangedOperation(const int32_t callingUid) override;
- /**
- * Binder call to allow clients to remove the specified configuration.
- */
- virtual Status removeConfiguration(int64_t key,
- const int32_t callingUid) override;
-
- /**
- * Binder call to associate the given config's subscriberId with the given pendingIntentRef.
- */
- virtual Status setBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir,
- const int32_t callingUid) override;
-
- /**
- * Binder call to unassociate the given config's subscriberId with any pendingIntentRef.
- */
- virtual Status unsetBroadcastSubscriber(int64_t configId,
- int64_t subscriberId,
- const int32_t callingUid) override;
-
- /** Inform statsCompanion that statsd is ready. */
- virtual void sayHiToStatsCompanion();
-
- /**
- * Binder call to notify statsd that all pullers from boot have been registered.
- */
- virtual Status allPullersFromBootRegistered();
-
- /**
- * Binder call to register a callback function for a pulled atom.
- */
- virtual Status registerPullAtomCallback(
- int32_t uid, int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) override;
-
- /**
- * Binder call to register a callback function for a pulled atom.
- */
- virtual Status registerNativePullAtomCallback(
- int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
- const std::vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& pullerCallback) override;
-
- /**
- * Binder call to unregister any existing callback for the given uid and atom.
- */
- virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override;
-
- /**
- * Binder call to unregister any existing callback for the given atom and calling uid.
- */
- virtual Status unregisterNativePullAtomCallback(int32_t atomTag) override;
-
- /**
- * Binder call to get registered experiment IDs.
- */
- virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
-
-private:
- /**
- * Load system properties at init.
- */
- void init_system_properties();
-
- /**
- * Helper for loading system properties.
- */
- static void init_build_type_callback(void* cookie, const char* name, const char* value,
- uint32_t serial);
-
- /**
- * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto.
- */
- void dumpIncidentSection(int outFd);
-
- /**
- * Text or proto output of statsdStats dumpsys.
- */
- void dumpStatsdStats(int outFd, bool verbose, bool proto);
-
- /**
- * Print usage information for the commands
- */
- void print_cmd_help(int out);
-
- /* Runs on its dedicated thread to process pushed stats event from socket. */
- void readLogs();
-
- /**
- * Trigger a broadcast.
- */
- status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args);
-
-
- /**
- * Trigger an active configs changed broadcast.
- */
- status_t cmd_trigger_active_config_broadcast(int outFd, Vector<String8>& args);
-
- /**
- * Handle the config sub-command.
- */
- status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args);
-
- /**
- * Prints some basic stats to std out.
- */
- status_t cmd_print_stats(int outFd, const Vector<String8>& args);
-
- /**
- * Print the event log.
- */
- status_t cmd_dump_report(int outFd, const Vector<String8>& args);
-
- /**
- * Print the mapping of uids to package names.
- */
- status_t cmd_print_uid_map(int outFd, const Vector<String8>& args);
-
- /**
- * Flush the data to disk.
- */
- status_t cmd_write_data_to_disk(int outFd);
-
- /**
- * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling
- * StatsLog.write(APP_BREADCRUMB_REPORTED).
- */
- status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args);
-
- /**
- * Write an BinaryPushStateChanged event, as if calling StatsLog.logBinaryPushStateChanged().
- */
- status_t cmd_log_binary_push(int outFd, const Vector<String8>& args);
-
- /**
- * Print contents of a pulled metrics source.
- */
- status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args);
-
- /**
- * Removes all configs stored on disk and on memory.
- */
- status_t cmd_remove_all_configs(int outFd);
-
- /*
- * Dump memory usage by statsd.
- */
- status_t cmd_dump_memory_info(int outFd);
-
- /*
- * Clear all puller cached data
- */
- status_t cmd_clear_puller_cache(int outFd);
-
- /**
- * Print all stats logs received to logcat.
- */
- status_t cmd_print_logs(int outFd, const Vector<String8>& args);
-
- /**
- * Writes the value of args[uidArgIndex] into uid.
- * Returns whether the uid is reasonable (type uid_t) and whether
- * 1. it is equal to the calling uid, or
- * 2. the device is mEngBuild, or
- * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
- */
- bool getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid);
-
- /**
- * Writes the value of uidSting into uid.
- * Returns whether the uid is reasonable (type uid_t) and whether
- * 1. it is equal to the calling uid, or
- * 2. the device is mEngBuild, or
- * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
- */
- bool getUidFromString(const char* uidString, int32_t& uid);
-
- /**
- * Adds a configuration after checking permissions and obtaining UID from binder call.
- */
- bool addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config);
-
- /**
- * Update a configuration.
- */
- void set_config(int uid, const string& name, const StatsdConfig& config);
-
- /**
- * Death recipient callback that is called when StatsCompanionService dies.
- * The cookie is a pointer to a StatsService object.
- */
- static void statsCompanionServiceDied(void* cookie);
-
- /**
- * Implementation of statsCompanionServiceDied.
- */
- void statsCompanionServiceDiedImpl();
-
- /**
- * Tracks the uid <--> package name mapping.
- */
- sp<UidMap> mUidMap;
-
- /**
- * Fetches external metrics
- */
- sp<StatsPullerManager> mPullerManager;
-
- /**
- * Tracks the configurations that have been passed to statsd.
- */
- sp<ConfigManager> mConfigManager;
-
- /**
- * The metrics recorder.
- */
- sp<StatsLogProcessor> mProcessor;
-
- /**
- * The alarm monitor for anomaly detection.
- */
- const sp<AlarmMonitor> mAnomalyAlarmMonitor;
-
- /**
- * The alarm monitor for alarms to directly trigger subscriber.
- */
- const sp<AlarmMonitor> mPeriodicAlarmMonitor;
-
- /**
- * Whether this is an eng build.
- */
- bool mEngBuild;
-
- sp<ShellSubscriber> mShellSubscriber;
-
- /**
- * Mutex for setting the shell subscriber
- */
- mutable mutex mShellSubscriberMutex;
- std::shared_ptr<LogEventQueue> mEventQueue;
-
- MultiConditionTrigger mBootCompleteTrigger;
- static const inline string kBootCompleteTag = "BOOT_COMPLETE";
- static const inline string kUidMapReceivedTag = "UID_MAP";
- static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED";
-
- ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient;
-
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
- FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
- FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
- FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
- FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval);
- FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit);
- FRIEND_TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket);
- FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket);
-
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // STATS_SERVICE_H
diff --git a/cmds/statsd/src/active_config_list.proto b/cmds/statsd/src/active_config_list.proto
deleted file mode 100644
index 992983358ae6..000000000000
--- a/cmds/statsd/src/active_config_list.proto
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_multiple_files = true;
-option java_outer_classname = "ActiveConfigProto";
-
-message ActiveEventActivation {
- optional int32 atom_matcher_index = 1;
-
- // Time left in activation. When this proto is loaded after device boot,
- // the activation should be set to active for this duration.
- // This field will only be set when the state is ACTIVE
- optional int64 remaining_ttl_nanos = 2;
-
- enum State {
- UNNKNOWN = 0;
- // This metric should activate for remaining_ttl_nanos when we load the activations.
- ACTIVE = 1;
- // When we load the activations, this metric should activate on next boot for the tll
- // specified in the config.
- ACTIVATE_ON_BOOT = 2;
- }
- optional State state = 3;
-}
-
-message ActiveMetric {
- optional int64 id = 1;
- repeated ActiveEventActivation activation = 2;
-}
-
-message ActiveConfig {
- optional int64 id = 1;
- optional int32 uid = 2;
- repeated ActiveMetric metric = 3;
-}
-
-// all configs and their metrics on device.
-message ActiveConfigList {
- repeated ActiveConfig config = 1;
-}
diff --git a/cmds/statsd/src/annotations.h b/cmds/statsd/src/annotations.h
deleted file mode 100644
index cf7f5433663f..000000000000
--- a/cmds/statsd/src/annotations.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const uint8_t ANNOTATION_ID_IS_UID = 1;
-const uint8_t ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2;
-const uint8_t ANNOTATION_ID_PRIMARY_FIELD = 3;
-const uint8_t ANNOTATION_ID_EXCLUSIVE_STATE = 4;
-const uint8_t ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5;
-const uint8_t ANNOTATION_ID_TRIGGER_STATE_RESET = 7;
-const uint8_t ANNOTATION_ID_STATE_NESTED = 8;
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
deleted file mode 100644
index b632d040eb43..000000000000
--- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include "anomaly/AlarmMonitor.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AlarmMonitor::AlarmMonitor(
- uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
- const std::function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>& updateAlarm,
- const std::function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm)
- : mRegisteredAlarmTimeSec(0),
- mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec),
- mUpdateAlarm(updateAlarm),
- mCancelAlarm(cancelAlarm) {}
-
-AlarmMonitor::~AlarmMonitor() {}
-
-void AlarmMonitor::setStatsCompanionService(
- shared_ptr<IStatsCompanionService> statsCompanionService) {
- std::lock_guard<std::mutex> lock(mLock);
- shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
- mStatsCompanionService = statsCompanionService;
- if (statsCompanionService == nullptr) {
- VLOG("Erasing link to statsCompanionService");
- return;
- }
- VLOG("Creating link to statsCompanionService");
- const sp<const InternalAlarm> top = mPq.top();
- if (top != nullptr) {
- updateRegisteredAlarmTime_l(top->timestampSec);
- }
-}
-
-void AlarmMonitor::add(sp<const InternalAlarm> alarm) {
- std::lock_guard<std::mutex> lock(mLock);
- if (alarm == nullptr) {
- ALOGW("Asked to add a null alarm.");
- return;
- }
- if (alarm->timestampSec < 1) {
- // forbidden since a timestamp 0 is used to indicate no alarm registered
- ALOGW("Asked to add a 0-time alarm.");
- return;
- }
- // TODO(b/110563466): Ensure that refractory period is respected.
- VLOG("Adding alarm with time %u", alarm->timestampSec);
- mPq.push(alarm);
- if (mRegisteredAlarmTimeSec < 1 ||
- alarm->timestampSec + mMinUpdateTimeSec < mRegisteredAlarmTimeSec) {
- updateRegisteredAlarmTime_l(alarm->timestampSec);
- }
-}
-
-void AlarmMonitor::remove(sp<const InternalAlarm> alarm) {
- std::lock_guard<std::mutex> lock(mLock);
- if (alarm == nullptr) {
- ALOGW("Asked to remove a null alarm.");
- return;
- }
- VLOG("Removing alarm with time %u", alarm->timestampSec);
- bool wasPresent = mPq.remove(alarm);
- if (!wasPresent) return;
- if (mPq.empty()) {
- VLOG("Queue is empty. Cancel any alarm.");
- cancelRegisteredAlarmTime_l();
- return;
- }
- uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
- VLOG("Soonest alarm is %u", soonestAlarmTimeSec);
- if (soonestAlarmTimeSec > mRegisteredAlarmTimeSec + mMinUpdateTimeSec) {
- updateRegisteredAlarmTime_l(soonestAlarmTimeSec);
- }
-}
-
-// More efficient than repeatedly calling remove(mPq.top()) since it batches the
-// updates to the registered alarm.
-unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> AlarmMonitor::popSoonerThan(
- uint32_t timestampSec) {
- VLOG("Removing alarms with time <= %u", timestampSec);
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> oldAlarms;
- std::lock_guard<std::mutex> lock(mLock);
-
- for (sp<const InternalAlarm> t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec;
- t = mPq.top()) {
- oldAlarms.insert(t);
- mPq.pop(); // remove t
- }
- // Always update registered alarm time (if anything has changed).
- if (!oldAlarms.empty()) {
- if (mPq.empty()) {
- VLOG("Queue is empty. Cancel any alarm.");
- cancelRegisteredAlarmTime_l();
- } else {
- // Always update the registered alarm in this case (unlike remove()).
- updateRegisteredAlarmTime_l(mPq.top()->timestampSec);
- }
- }
- return oldAlarms;
-}
-
-void AlarmMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
- VLOG("Updating reg alarm time to %u", timestampSec);
- mRegisteredAlarmTimeSec = timestampSec;
- mUpdateAlarm(mStatsCompanionService, secToMs(mRegisteredAlarmTimeSec));
-}
-
-void AlarmMonitor::cancelRegisteredAlarmTime_l() {
- VLOG("Cancelling reg alarm.");
- mRegisteredAlarmTimeSec = 0;
- mCancelAlarm(mStatsCompanionService);
-}
-
-int64_t AlarmMonitor::secToMs(uint32_t timeSec) {
- return ((int64_t)timeSec) * 1000;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
deleted file mode 100644
index 5c34e381ba0b..000000000000
--- a/cmds/statsd/src/anomaly/AlarmMonitor.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "anomaly/indexed_priority_queue.h"
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-
-#include <unordered_set>
-#include <vector>
-
-using namespace android;
-
-using aidl::android::os::IStatsCompanionService;
-using std::function;
-using std::shared_ptr;
-using std::unordered_set;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Represents an alarm, associated with some aggregate metric, holding a
- * projected time at which the metric is expected to exceed its anomaly
- * threshold.
- * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106.
- */
-struct InternalAlarm : public RefBase {
- explicit InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
- }
-
- const uint32_t timestampSec;
-
- /** InternalAlarm a is smaller (higher priority) than b if its timestamp is sooner. */
- struct SmallerTimestamp {
- bool operator()(sp<const InternalAlarm> a, sp<const InternalAlarm> b) const {
- return (a->timestampSec < b->timestampSec);
- }
- };
-};
-
-/**
- * Manages internal alarms that may get registered with the AlarmManager.
- */
-class AlarmMonitor : public RefBase {
-public:
- /**
- * @param minDiffToUpdateRegisteredAlarmTimeSec If the soonest alarm differs
- * from the registered alarm by more than this amount, update the registered
- * alarm.
- */
- AlarmMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
- const function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>&
- updateAlarm,
- const function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm);
- ~AlarmMonitor();
-
- /**
- * Tells AnomalyMonitor what IStatsCompanionService to use and, if
- * applicable, immediately registers an existing alarm with it.
- * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't
- * update IStatsCompanionService (until such time as it is set non-null).
- */
- void setStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
-
- /**
- * Adds the given alarm (reference) to the queue.
- */
- void add(sp<const InternalAlarm> alarm);
-
- /**
- * Removes the given alarm (reference) from the queue.
- * Note that alarm comparison is reference-based; if another alarm exists
- * with the same timestampSec, that alarm will still remain in the queue.
- */
- void remove(sp<const InternalAlarm> alarm);
-
- /**
- * Returns and removes all alarms whose timestamp <= the given timestampSec.
- * Always updates the registered alarm if return is non-empty.
- */
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> popSoonerThan(
- uint32_t timestampSec);
-
- /**
- * Returns the projected alarm timestamp that is registered with
- * StatsCompanionService. This may not be equal to the soonest alarm,
- * but should be within minDiffToUpdateRegisteredAlarmTimeSec of it.
- */
- uint32_t getRegisteredAlarmTimeSec() const {
- return mRegisteredAlarmTimeSec;
- }
-
-private:
- std::mutex mLock;
-
- /**
- * Timestamp (seconds since epoch) of the alarm registered with
- * StatsCompanionService. This, in general, may not be equal to the soonest
- * alarm stored in mPq, but should be within minUpdateTimeSec of it.
- * A value of 0 indicates that no alarm is currently registered.
- */
- uint32_t mRegisteredAlarmTimeSec;
-
- /**
- * Priority queue of alarms, prioritized by soonest alarm.timestampSec.
- */
- indexed_priority_queue<InternalAlarm, InternalAlarm::SmallerTimestamp> mPq;
-
- /**
- * Binder interface for communicating with StatsCompanionService.
- */
- shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
-
- /**
- * Amount by which the soonest projected alarm must differ from
- * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime_l is called.
- */
- uint32_t mMinUpdateTimeSec;
-
- /**
- * Updates the alarm registered with StatsCompanionService to the given time.
- * Also correspondingly updates mRegisteredAlarmTimeSec.
- */
- void updateRegisteredAlarmTime_l(uint32_t timestampSec);
-
- /**
- * Cancels the alarm registered with StatsCompanionService.
- * Also correspondingly sets mRegisteredAlarmTimeSec to 0.
- */
- void cancelRegisteredAlarmTime_l();
-
- /** Converts uint32 timestamp in seconds to a Java long in msec. */
- int64_t secToMs(uint32_t timeSec);
-
- // Callback function to update the alarm via StatsCompanionService.
- std::function<void(const shared_ptr<IStatsCompanionService>, int64_t)> mUpdateAlarm;
-
- // Callback function to cancel the alarm via StatsCompanionService.
- std::function<void(const shared_ptr<IStatsCompanionService>)> mCancelAlarm;
-
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
deleted file mode 100644
index 6d9beb8f718d..000000000000
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "anomaly/AlarmTracker.h"
-#include "anomaly/subscriber_util.h"
-#include "HashableDimensionKey.h"
-#include "stats_util.h"
-#include "storage/StorageManager.h"
-
-#include <time.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AlarmTracker::AlarmTracker(const int64_t startMillis,
- const int64_t currentMillis,
- const Alarm& alarm, const ConfigKey& configKey,
- const sp<AlarmMonitor>& alarmMonitor)
- : mAlarmConfig(alarm),
- mConfigKey(configKey),
- mAlarmMonitor(alarmMonitor) {
- VLOG("AlarmTracker() called");
- mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
- // startMillis is the time statsd is created. We need to find the 1st alarm timestamp after
- // the config is added to statsd.
- mAlarmSec = findNextAlarmSec(currentMillis / MS_PER_SEC); // round up
- mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
- VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->add(mInternalAlarm);
- }
-}
-
-AlarmTracker::~AlarmTracker() {
- VLOG("~AlarmTracker() called");
- if (mInternalAlarm != nullptr && mAlarmMonitor != nullptr) {
- mAlarmMonitor->remove(mInternalAlarm);
- }
-}
-
-void AlarmTracker::addSubscription(const Subscription& subscription) {
- mSubscriptions.push_back(subscription);
-}
-
-int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) {
- if (currentTimeSec < mAlarmSec) {
- return mAlarmSec;
- }
- int64_t periodsForward =
- ((currentTimeSec - mAlarmSec) * MS_PER_SEC) / mAlarmConfig.period_millis() + 1;
- return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC;
-}
-
-void AlarmTracker::informAlarmsFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
- if (firedAlarms.empty() || mInternalAlarm == nullptr ||
- firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
- return;
- }
- if (!mSubscriptions.empty()) {
- VLOG("AlarmTracker triggers the subscribers.");
- triggerSubscribers(mAlarmConfig.id(), 0 /*metricId N/A*/, DEFAULT_METRIC_DIMENSION_KEY,
- 0 /* metricValue N/A */, mConfigKey, mSubscriptions);
- }
- firedAlarms.erase(mInternalAlarm);
- mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up
- mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
- VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->add(mInternalAlarm);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
deleted file mode 100644
index 2da4a18682ae..000000000000
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-#include "AlarmMonitor.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alarm
-
-#include <stdlib.h>
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class AlarmTracker : public virtual RefBase {
-public:
- AlarmTracker(const int64_t startMillis,
- const int64_t currentMillis,
- const Alarm& alarm, const ConfigKey& configKey,
- const sp<AlarmMonitor>& subscriberAlarmMonitor);
-
- virtual ~AlarmTracker();
-
- void onAlarmFired();
-
- void addSubscription(const Subscription& subscription);
-
- void informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms);
-
-protected:
- // For test only. Returns the alarm timestamp in seconds. Otherwise returns 0.
- inline int32_t getAlarmTimestampSec() const {
- return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
- }
-
- int64_t findNextAlarmSec(int64_t currentTimeMillis);
-
- // statsd_config.proto Alarm message that defines this tracker.
- const Alarm mAlarmConfig;
-
- // A reference to the Alarm's config key.
- const ConfigKey mConfigKey;
-
- // The subscriptions that depend on this alarm.
- std::vector<Subscription> mSubscriptions;
-
- // Alarm monitor.
- sp<AlarmMonitor> mAlarmMonitor;
-
- // The current expected alarm time in seconds.
- int64_t mAlarmSec;
-
- // The current alarm.
- sp<const InternalAlarm> mInternalAlarm;
-
- FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp);
- FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
deleted file mode 100644
index 619752c7c44a..000000000000
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "AnomalyTracker.h"
-#include "external/Perfetto.h"
-#include "guardrail/StatsdStats.h"
-#include "metadata_util.h"
-#include "stats_log_util.h"
-#include "subscriber_util.h"
-#include "subscriber/IncidentdReporter.h"
-#include "subscriber/SubscriberReporter.h"
-
-#include <inttypes.h>
-#include <statslog_statsd.h>
-#include <time.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
- : mAlert(alert), mConfigKey(configKey), mNumOfPastBuckets(mAlert.num_buckets() - 1) {
- VLOG("AnomalyTracker() called");
- if (mAlert.num_buckets() <= 0) {
- ALOGE("Cannot create AnomalyTracker with %lld buckets", (long long)mAlert.num_buckets());
- return;
- }
- if (!mAlert.has_trigger_if_sum_gt()) {
- ALOGE("Cannot create AnomalyTracker without threshold");
- return;
- }
- resetStorage(); // initialization
-}
-
-AnomalyTracker::~AnomalyTracker() {
- VLOG("~AnomalyTracker() called");
-}
-
-void AnomalyTracker::resetStorage() {
- VLOG("resetStorage() called.");
- mPastBuckets.clear();
- // Excludes the current bucket.
- mPastBuckets.resize(mNumOfPastBuckets);
- mSumOverPastBuckets.clear();
-}
-
-size_t AnomalyTracker::index(int64_t bucketNum) const {
- if (bucketNum < 0) {
- ALOGE("index() was passed a negative bucket number (%lld)!", (long long)bucketNum);
- }
- return bucketNum % mNumOfPastBuckets;
-}
-
-void AnomalyTracker::advanceMostRecentBucketTo(const int64_t& bucketNum) {
- VLOG("advanceMostRecentBucketTo() called.");
- if (mNumOfPastBuckets <= 0) {
- return;
- }
- if (bucketNum <= mMostRecentBucketNum) {
- ALOGW("Cannot advance buckets backwards (bucketNum=%lld but mMostRecentBucketNum=%lld)",
- (long long)bucketNum, (long long)mMostRecentBucketNum);
- return;
- }
- // If in the future (i.e. buckets are ancient), just empty out all past info.
- if (bucketNum >= mMostRecentBucketNum + mNumOfPastBuckets) {
- resetStorage();
- mMostRecentBucketNum = bucketNum;
- return;
- }
-
- // Clear out space by emptying out old mPastBuckets[i] values and update mSumOverPastBuckets.
- for (int64_t i = mMostRecentBucketNum + 1; i <= bucketNum; i++) {
- const int idx = index(i);
- subtractBucketFromSum(mPastBuckets[idx]);
- mPastBuckets[idx] = nullptr; // release (but not clear) the old bucket.
- }
- mMostRecentBucketNum = bucketNum;
-}
-
-void AnomalyTracker::addPastBucket(const MetricDimensionKey& key,
- const int64_t& bucketValue,
- const int64_t& bucketNum) {
- VLOG("addPastBucket(bucketValue) called.");
- if (mNumOfPastBuckets == 0 ||
- bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets) {
- return;
- }
-
- const int bucketIndex = index(bucketNum);
- if (bucketNum <= mMostRecentBucketNum && (mPastBuckets[bucketIndex] != nullptr)) {
- // We need to insert into an already existing past bucket.
- std::shared_ptr<DimToValMap>& bucket = mPastBuckets[bucketIndex];
- auto itr = bucket->find(key);
- if (itr != bucket->end()) {
- // Old entry already exists; update it.
- subtractValueFromSum(key, itr->second);
- itr->second = bucketValue;
- } else {
- bucket->insert({key, bucketValue});
- }
- mSumOverPastBuckets[key] += bucketValue;
- } else {
- // Bucket does not exist yet (in future or was never made), so we must make it.
- std::shared_ptr<DimToValMap> bucket = std::make_shared<DimToValMap>();
- bucket->insert({key, bucketValue});
- addPastBucket(bucket, bucketNum);
- }
-}
-
-void AnomalyTracker::addPastBucket(std::shared_ptr<DimToValMap> bucket,
- const int64_t& bucketNum) {
- VLOG("addPastBucket(bucket) called.");
- if (mNumOfPastBuckets == 0 ||
- bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets) {
- return;
- }
-
- if (bucketNum <= mMostRecentBucketNum) {
- // We are updating an old bucket, not adding a new one.
- subtractBucketFromSum(mPastBuckets[index(bucketNum)]);
- } else {
- // Clear space for the new bucket to be at bucketNum.
- advanceMostRecentBucketTo(bucketNum);
- }
- mPastBuckets[index(bucketNum)] = bucket;
- addBucketToSum(bucket);
-}
-
-void AnomalyTracker::subtractBucketFromSum(const shared_ptr<DimToValMap>& bucket) {
- if (bucket == nullptr) {
- return;
- }
- for (const auto& keyValuePair : *bucket) {
- subtractValueFromSum(keyValuePair.first, keyValuePair.second);
- }
-}
-
-
-void AnomalyTracker::subtractValueFromSum(const MetricDimensionKey& key,
- const int64_t& bucketValue) {
- auto itr = mSumOverPastBuckets.find(key);
- if (itr == mSumOverPastBuckets.end()) {
- return;
- }
- itr->second -= bucketValue;
- if (itr->second == 0) {
- mSumOverPastBuckets.erase(itr);
- }
-}
-
-void AnomalyTracker::addBucketToSum(const shared_ptr<DimToValMap>& bucket) {
- if (bucket == nullptr) {
- return;
- }
- // For each dimension present in the bucket, add its value to its corresponding sum.
- for (const auto& keyValuePair : *bucket) {
- mSumOverPastBuckets[keyValuePair.first] += keyValuePair.second;
- }
-}
-
-int64_t AnomalyTracker::getPastBucketValue(const MetricDimensionKey& key,
- const int64_t& bucketNum) const {
- if (bucketNum < 0 || mMostRecentBucketNum < 0
- || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets
- || bucketNum > mMostRecentBucketNum) {
- return 0;
- }
-
- const auto& bucket = mPastBuckets[index(bucketNum)];
- if (bucket == nullptr) {
- return 0;
- }
- const auto& itr = bucket->find(key);
- return itr == bucket->end() ? 0 : itr->second;
-}
-
-int64_t AnomalyTracker::getSumOverPastBuckets(const MetricDimensionKey& key) const {
- const auto& itr = mSumOverPastBuckets.find(key);
- if (itr != mSumOverPastBuckets.end()) {
- return itr->second;
- }
- return 0;
-}
-
-bool AnomalyTracker::detectAnomaly(const int64_t& currentBucketNum,
- const MetricDimensionKey& key,
- const int64_t& currentBucketValue) {
-
- // currentBucketNum should be the next bucket after pastBuckets. If not, advance so that it is.
- if (currentBucketNum > mMostRecentBucketNum + 1) {
- advanceMostRecentBucketTo(currentBucketNum - 1);
- }
- return mAlert.has_trigger_if_sum_gt() &&
- getSumOverPastBuckets(key) + currentBucketValue > mAlert.trigger_if_sum_gt();
-}
-
-void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, int64_t metricId,
- const MetricDimensionKey& key, int64_t metricValue) {
- // TODO(b/110563466): Why receive timestamp? RefractoryPeriod should always be based on
- // real time right now.
- if (isInRefractoryPeriod(timestampNs, key)) {
- VLOG("Skipping anomaly declaration since within refractory period");
- return;
- }
- if (mAlert.has_refractory_period_secs()) {
- mRefractoryPeriodEndsSec[key] = ((timestampNs + NS_PER_SEC - 1) / NS_PER_SEC) // round up
- + mAlert.refractory_period_secs();
- // TODO(b/110563466): If we had access to the bucket_size_millis, consider
- // calling resetStorage()
- // if (mAlert.refractory_period_secs() > mNumOfPastBuckets * bucketSizeNs) {resetStorage();}
- }
-
- if (!mSubscriptions.empty()) {
- ALOGI("An anomaly (%" PRId64 ") %s has occurred! Informing subscribers.",
- mAlert.id(), key.toString().c_str());
- informSubscribers(key, metricId, metricValue);
- } else {
- ALOGI("An anomaly has occurred! (But no subscriber for that alert.)");
- }
-
- StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.id());
-
- // TODO(b/110564268): This should also take in the const MetricDimensionKey& key?
- util::stats_write(util::ANOMALY_DETECTED, mConfigKey.GetUid(),
- mConfigKey.GetId(), mAlert.id());
-}
-
-void AnomalyTracker::detectAndDeclareAnomaly(const int64_t& timestampNs,
- const int64_t& currBucketNum, int64_t metricId,
- const MetricDimensionKey& key,
- const int64_t& currentBucketValue) {
- if (detectAnomaly(currBucketNum, key, currentBucketValue)) {
- declareAnomaly(timestampNs, metricId, key, currentBucketValue);
- }
-}
-
-bool AnomalyTracker::isInRefractoryPeriod(const int64_t& timestampNs,
- const MetricDimensionKey& key) const {
- const auto& it = mRefractoryPeriodEndsSec.find(key);
- if (it != mRefractoryPeriodEndsSec.end()) {
- return timestampNs < (it->second * (int64_t)NS_PER_SEC);
- }
- return false;
-}
-
-void AnomalyTracker::informSubscribers(const MetricDimensionKey& key, int64_t metric_id,
- int64_t metricValue) {
- triggerSubscribers(mAlert.id(), metric_id, key, metricValue, mConfigKey, mSubscriptions);
-}
-
-bool AnomalyTracker::writeAlertMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::AlertMetadata* alertMetadata) {
- bool metadataWritten = false;
-
- if (mRefractoryPeriodEndsSec.empty()) {
- return false;
- }
-
- for (const auto& it: mRefractoryPeriodEndsSec) {
- // Do not write the timestamp to disk if it has already expired
- if (it.second < systemElapsedTimeNs / NS_PER_SEC) {
- continue;
- }
-
- metadataWritten = true;
- if (alertMetadata->alert_dim_keyed_data_size() == 0) {
- alertMetadata->set_alert_id(mAlert.id());
- }
-
- metadata::AlertDimensionKeyedData* keyedData = alertMetadata->add_alert_dim_keyed_data();
- // We convert and write the refractory_end_sec to wall clock time because we do not know
- // when statsd will start again.
- int32_t refractoryEndWallClockSec = (int32_t) ((currentWallClockTimeNs / NS_PER_SEC) +
- (it.second - systemElapsedTimeNs / NS_PER_SEC));
-
- keyedData->set_last_refractory_ends_sec(refractoryEndWallClockSec);
- writeMetricDimensionKeyToMetadataDimensionKey(
- it.first, keyedData->mutable_dimension_key());
- }
-
- return metadataWritten;
-}
-
-void AnomalyTracker::loadAlertMetadata(
- const metadata::AlertMetadata& alertMetadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- for (const metadata::AlertDimensionKeyedData& keyedData :
- alertMetadata.alert_dim_keyed_data()) {
- if ((uint64_t) keyedData.last_refractory_ends_sec() < currentWallClockTimeNs / NS_PER_SEC) {
- // Do not update the timestamp if it has already expired.
- continue;
- }
- MetricDimensionKey metricKey = loadMetricDimensionKeyFromProto(
- keyedData.dimension_key());
- int32_t refractoryPeriodEndsSec = (int32_t) keyedData.last_refractory_ends_sec() -
- currentWallClockTimeNs / NS_PER_SEC + systemElapsedTimeNs / NS_PER_SEC;
- mRefractoryPeriodEndsSec[metricKey] = refractoryPeriodEndsSec;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
deleted file mode 100644
index bf36a3bc8990..000000000000
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdlib.h>
-
-#include <gtest/gtest_prod.h>
-#include <utils/RefBase.h>
-
-#include "AlarmMonitor.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h" // AlertMetadata
-#include "stats_util.h" // HashableDimensionKey and DimToValMap
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::shared_ptr;
-using std::unordered_map;
-
-// Does NOT allow negative values.
-class AnomalyTracker : public virtual RefBase {
-public:
- AnomalyTracker(const Alert& alert, const ConfigKey& configKey);
-
- virtual ~AnomalyTracker();
-
- // Add subscriptions that depend on this alert.
- void addSubscription(const Subscription& subscription) {
- mSubscriptions.push_back(subscription);
- }
-
- // Adds a bucket for the given bucketNum (index starting at 0).
- // If a bucket for bucketNum already exists, it will be replaced.
- // Also, advances to bucketNum (if not in the past), effectively filling any intervening
- // buckets with 0s.
- void addPastBucket(std::shared_ptr<DimToValMap> bucket, const int64_t& bucketNum);
-
- // Inserts (or replaces) the bucket entry for the given bucketNum at the given key to be the
- // given bucketValue. If the bucket does not exist, it will be created.
- // Also, advances to bucketNum (if not in the past), effectively filling any intervening
- // buckets with 0s.
- void addPastBucket(const MetricDimensionKey& key, const int64_t& bucketValue,
- const int64_t& bucketNum);
-
- // Returns true if, based on past buckets plus the new currentBucketValue (which generally
- // represents the partially-filled current bucket), an anomaly has happened.
- // Also advances to currBucketNum-1.
- bool detectAnomaly(const int64_t& currBucketNum, const MetricDimensionKey& key,
- const int64_t& currentBucketValue);
-
- // Informs incidentd about the detected alert.
- void declareAnomaly(const int64_t& timestampNs, int64_t metricId, const MetricDimensionKey& key,
- int64_t metricValue);
-
- // Detects if, based on past buckets plus the new currentBucketValue (which generally
- // represents the partially-filled current bucket), an anomaly has happened, and if so,
- // declares an anomaly and informs relevant subscribers.
- // Also advances to currBucketNum-1.
- void detectAndDeclareAnomaly(const int64_t& timestampNs, const int64_t& currBucketNum,
- int64_t metricId, const MetricDimensionKey& key,
- const int64_t& currentBucketValue);
-
- // Init the AlarmMonitor which is shared across anomaly trackers.
- virtual void setAlarmMonitor(const sp<AlarmMonitor>& alarmMonitor) {
- return; // Base AnomalyTracker class has no need for the AlarmMonitor.
- }
-
- // Returns the sum of all past bucket values for the given dimension key.
- int64_t getSumOverPastBuckets(const MetricDimensionKey& key) const;
-
- // Returns the value for a past bucket, or 0 if that bucket doesn't exist.
- int64_t getPastBucketValue(const MetricDimensionKey& key, const int64_t& bucketNum) const;
-
- // Returns the anomaly threshold set in the configuration.
- inline int64_t getAnomalyThreshold() const {
- return mAlert.trigger_if_sum_gt();
- }
-
- // Returns the refractory period ending timestamp (in seconds) for the given key.
- // Before this moment, any detected anomaly will be ignored.
- // If there is no stored refractory period ending timestamp, returns 0.
- uint32_t getRefractoryPeriodEndsSec(const MetricDimensionKey& key) const {
- const auto& it = mRefractoryPeriodEndsSec.find(key);
- return it != mRefractoryPeriodEndsSec.end() ? it->second : 0;
- }
-
- // Returns the (constant) number of past buckets this anomaly tracker can store.
- inline int getNumOfPastBuckets() const {
- return mNumOfPastBuckets;
- }
-
- // Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
- // and removes it from firedAlarms. Does NOT remove the alarm from the AlarmMonitor.
- virtual void informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
- return; // The base AnomalyTracker class doesn't have alarms.
- }
-
- // Writes metadata of the alert (refractory_period_end_sec) to AlertMetadata.
- // Returns true if at least one element is written to alertMetadata.
- bool writeAlertMetadataToProto(
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs, metadata::AlertMetadata* alertMetadata);
-
- void loadAlertMetadata(
- const metadata::AlertMetadata& alertMetadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-
-protected:
- // For testing only.
- // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
- // returns 0.
- virtual uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const {
- return 0; // The base AnomalyTracker class doesn't have alarms.
- }
-
- // statsd_config.proto Alert message that defines this tracker.
- const Alert mAlert;
-
- // The subscriptions that depend on this alert.
- std::vector<Subscription> mSubscriptions;
-
- // A reference to the Alert's config key.
- const ConfigKey mConfigKey;
-
- // Number of past buckets. One less than the total number of buckets needed
- // for the anomaly detection (since the current bucket is not in the past).
- const int mNumOfPastBuckets;
-
- // Values for each of the past mNumOfPastBuckets buckets. Always of size mNumOfPastBuckets.
- // mPastBuckets[i] can be null, meaning that no data is present in that bucket.
- std::vector<shared_ptr<DimToValMap>> mPastBuckets;
-
- // Cached sum over all existing buckets in mPastBuckets.
- // Its buckets never contain entries of 0.
- DimToValMap mSumOverPastBuckets;
-
- // The bucket number of the last added bucket.
- int64_t mMostRecentBucketNum = -1;
-
- // Map from each dimension to the timestamp that its refractory period (if this anomaly was
- // declared for that dimension) ends, in seconds. From this moment and onwards, anomalies
- // can be declared again.
- // Entries may be, but are not guaranteed to be, removed after the period is finished.
- unordered_map<MetricDimensionKey, uint32_t> mRefractoryPeriodEndsSec;
-
- // Advances mMostRecentBucketNum to bucketNum, deleting any data that is now too old.
- // Specifically, since it is now too old, removes the data for
- // [mMostRecentBucketNum - mNumOfPastBuckets + 1, bucketNum - mNumOfPastBuckets].
- void advanceMostRecentBucketTo(const int64_t& bucketNum);
-
- // Add the information in the given bucket to mSumOverPastBuckets.
- void addBucketToSum(const shared_ptr<DimToValMap>& bucket);
-
- // Subtract the information in the given bucket from mSumOverPastBuckets
- // and remove any items with value 0.
- void subtractBucketFromSum(const shared_ptr<DimToValMap>& bucket);
-
- // From mSumOverPastBuckets[key], subtracts bucketValue, removing it if it is now 0.
- void subtractValueFromSum(const MetricDimensionKey& key, const int64_t& bucketValue);
-
- // Returns true if in the refractory period, else false.
- bool isInRefractoryPeriod(const int64_t& timestampNs, const MetricDimensionKey& key) const;
-
- // Calculates the corresponding bucket index within the circular array.
- // Requires bucketNum >= 0.
- size_t index(int64_t bucketNum) const;
-
- // Resets all bucket data. For use when all the data gets stale.
- virtual void resetStorage();
-
- // Informs the subscribers (incidentd, perfetto, broadcasts, etc) that an anomaly has occurred.
- void informSubscribers(const MetricDimensionKey& key, int64_t metricId, int64_t metricValue);
-
- FRIEND_TEST(AnomalyTrackerTest, TestConsecutiveBuckets);
- FRIEND_TEST(AnomalyTrackerTest, TestSparseBuckets);
- FRIEND_TEST(GaugeMetricProducerTest, TestAnomalyDetection);
- FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
deleted file mode 100644
index 2b56810170e5..000000000000
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "DurationAnomalyTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-DurationAnomalyTracker::DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
- const sp<AlarmMonitor>& alarmMonitor)
- : AnomalyTracker(alert, configKey), mAlarmMonitor(alarmMonitor) {
- VLOG("DurationAnomalyTracker() called");
-}
-
-DurationAnomalyTracker::~DurationAnomalyTracker() {
- VLOG("~DurationAnomalyTracker() called");
- cancelAllAlarms();
-}
-
-void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
- const int64_t& timestampNs) {
- // Alarms are stored in secs. Must round up, since if it fires early, it is ignored completely.
- uint32_t timestampSec = static_cast<uint32_t>((timestampNs -1) / NS_PER_SEC) + 1; // round up
- if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
- VLOG("Not setting anomaly alarm since it would fall in the refractory period.");
- return;
- }
-
- auto itr = mAlarms.find(dimensionKey);
- if (itr != mAlarms.end() && mAlarmMonitor != nullptr) {
- mAlarmMonitor->remove(itr->second);
- }
-
- sp<const InternalAlarm> alarm = new InternalAlarm{timestampSec};
- mAlarms[dimensionKey] = alarm;
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->add(alarm);
- }
-}
-
-void DurationAnomalyTracker::stopAlarm(const MetricDimensionKey& dimensionKey,
- const int64_t& timestampNs) {
- const auto itr = mAlarms.find(dimensionKey);
- if (itr == mAlarms.end()) {
- return;
- }
-
- // If the alarm is set in the past but hasn't fired yet (due to lag), catch it now.
- if (itr->second != nullptr && timestampNs >= (int64_t)NS_PER_SEC * itr->second->timestampSec) {
- declareAnomaly(timestampNs, mAlert.metric_id(), dimensionKey,
- mAlert.trigger_if_sum_gt() + (timestampNs / NS_PER_SEC) -
- itr->second->timestampSec);
- }
- if (mAlarmMonitor != nullptr) {
- mAlarmMonitor->remove(itr->second);
- }
- mAlarms.erase(dimensionKey);
-}
-
-void DurationAnomalyTracker::cancelAllAlarms() {
- if (mAlarmMonitor != nullptr) {
- for (const auto& itr : mAlarms) {
- mAlarmMonitor->remove(itr.second);
- }
- }
- mAlarms.clear();
-}
-
-void DurationAnomalyTracker::informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
-
- if (firedAlarms.empty() || mAlarms.empty()) return;
- // Find the intersection of firedAlarms and mAlarms.
- // The for loop is inefficient, since it loops over all keys, but that's okay since it is very
- // seldomly called. The alternative would be having InternalAlarms store information about the
- // DurationAnomalyTracker and key, but that's a lot of data overhead to speed up something that
- // is rarely ever called.
- unordered_map<MetricDimensionKey, sp<const InternalAlarm>> matchedAlarms;
- for (const auto& kv : mAlarms) {
- if (firedAlarms.count(kv.second) > 0) {
- matchedAlarms.insert({kv.first, kv.second});
- }
- }
-
- // Now declare each of these alarms to have fired.
- for (const auto& kv : matchedAlarms) {
- declareAnomaly(
- timestampNs, mAlert.metric_id(), kv.first,
- mAlert.trigger_if_sum_gt() + (timestampNs / NS_PER_SEC) - kv.second->timestampSec);
- mAlarms.erase(kv.first);
- firedAlarms.erase(kv.second); // No one else can also own it, so we're done with it.
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
deleted file mode 100644
index 686d8f95c7f6..000000000000
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "AlarmMonitor.h"
-#include "AnomalyTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-
-class DurationAnomalyTracker : public virtual AnomalyTracker {
-public:
- DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
- const sp<AlarmMonitor>& alarmMonitor);
-
- virtual ~DurationAnomalyTracker();
-
- // Sets an alarm for the given timestamp.
- // Replaces previous alarm if one already exists.
- void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime);
-
- // Stops the alarm.
- // If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
- // declare the anomaly now.
- void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs);
-
- // Stop all the alarms owned by this tracker. Does not declare any anomalies.
- void cancelAllAlarms();
-
- // Declares an anomaly for each alarm in firedAlarms that belongs to this DurationAnomalyTracker
- // and removes it from firedAlarms. The AlarmMonitor is not informed.
- // Note that this will generally be called from a different thread from the other functions;
- // the caller is responsible for thread safety.
- void informAlarmsFired(const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) override;
-
-protected:
- // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
- // returns 0.
- uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const override {
- auto it = mAlarms.find(dimensionKey);
- return it == mAlarms.end() ? 0 : it->second->timestampSec;
- }
-
- // The alarms owned by this tracker. The alarm monitor also shares the alarm pointers when they
- // are still active.
- std::unordered_map<MetricDimensionKey, sp<const InternalAlarm>> mAlarms;
-
- // Anomaly alarm monitor.
- sp<AlarmMonitor> mAlarmMonitor;
-
- FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/indexed_priority_queue.h b/cmds/statsd/src/anomaly/indexed_priority_queue.h
deleted file mode 100644
index 99882d0337b1..000000000000
--- a/cmds/statsd/src/anomaly/indexed_priority_queue.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <utils/RefBase.h>
-#include <unordered_map>
-#include <vector>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/** Defines a hash function for sp<const AA>, returning the hash of the underlying pointer. */
-template <class AA>
-struct SpHash {
- size_t operator()(const sp<const AA>& k) const {
- return std::hash<const AA*>()(k.get());
- }
-};
-
-/**
- * Min priority queue for generic type AA.
- * Unlike a regular priority queue, this class is also capable of removing interior elements.
- * @tparam Comparator must implement [bool operator()(sp<const AA> a, sp<const AA> b)], returning
- * whether a should be closer to the top of the queue than b.
- */
-template <class AA, class Comparator>
-class indexed_priority_queue {
-public:
- indexed_priority_queue();
- /** Adds a into the priority queue. If already present or a==nullptr, does nothing. */
- void push(sp<const AA> a);
- /*
- * Removes a from the priority queue. If not present or a==nullptr, does nothing.
- * Returns true if a had been present (and is now removed), else false.
- */
- bool remove(sp<const AA> a);
- /** Removes the top element, if there is one. */
- void pop();
- /** Removes all elements. */
- void clear();
- /** Returns whether priority queue contains a (not just a copy of a, but a itself). */
- bool contains(sp<const AA> a) const;
- /** Returns min element. Returns nullptr iff empty(). */
- sp<const AA> top() const;
- /** Returns number of elements in priority queue. */
- size_t size() const {
- return pq.size() - 1;
- } // pq is 1-indexed
- /** Returns true iff priority queue is empty. */
- bool empty() const {
- return size() < 1;
- }
-
-private:
- /** Vector representing a min-heap (1-indexed, with nullptr at 0). */
- std::vector<sp<const AA>> pq;
- /** Mapping of each element in pq to its index in pq (i.e. the inverse of a=pq[i]). */
- std::unordered_map<sp<const AA>, size_t, SpHash<AA>> indices;
-
- void init();
- void sift_up(size_t idx);
- void sift_down(size_t idx);
- /** Returns whether pq[idx1] is considered higher than pq[idx2], according to Comparator. */
- bool higher(size_t idx1, size_t idx2) const;
- void swap_indices(size_t i, size_t j);
-};
-
-// Implementation must be done in this file due to use of template.
-
-template <class AA, class Comparator>
-indexed_priority_queue<AA, Comparator>::indexed_priority_queue() {
- init();
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::push(sp<const AA> a) {
- if (a == nullptr) return;
- if (contains(a)) return;
- pq.push_back(a);
- size_t idx = size(); // index of last element since 1-indexed
- indices.insert({a, idx});
- sift_up(idx); // get the pq back in order
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::remove(sp<const AA> a) {
- if (a == nullptr) return false;
- if (!contains(a)) return false;
- size_t idx = indices[a];
- if (idx >= pq.size()) {
- return false;
- }
- if (idx == size()) { // if a is the last element, i.e. at index idx == size() == (pq.size()-1)
- pq.pop_back();
- indices.erase(a);
- return true;
- }
- // move last element (guaranteed not to be at idx) to idx, then delete a
- sp<const AA> last_a = pq.back();
- pq[idx] = last_a;
- pq.pop_back();
- indices[last_a] = idx;
- indices.erase(a);
-
- // get the heap back in order (since the element at idx is not in order)
- sift_up(idx);
- sift_down(idx);
-
- return true;
-}
-
-// The same as, but slightly more efficient than, remove(top()).
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::pop() {
- sp<const AA> a = top();
- if (a == nullptr) return;
- const size_t idx = 1;
- if (idx == size()) { // if a is the last element
- pq.pop_back();
- indices.erase(a);
- return;
- }
- // move last element (guaranteed not to be at idx) to idx, then delete a
- sp<const AA> last_a = pq.back();
- pq[idx] = last_a;
- pq.pop_back();
- indices[last_a] = idx;
- indices.erase(a);
-
- // get the heap back in order (since the element at idx is not in order)
- sift_down(idx);
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::clear() {
- pq.clear();
- indices.clear();
- init();
-}
-
-template <class AA, class Comparator>
-sp<const AA> indexed_priority_queue<AA, Comparator>::top() const {
- if (empty()) return nullptr;
- return pq[1];
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::init() {
- pq.push_back(nullptr); // so that pq is 1-indexed.
- indices.insert({nullptr, 0}); // just to be consistent with pq.
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::sift_up(size_t idx) {
- while (idx > 1) {
- size_t parent = idx / 2;
- if (higher(idx, parent))
- swap_indices(idx, parent);
- else
- break;
- idx = parent;
- }
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::sift_down(size_t idx) {
- while (2 * idx <= size()) {
- size_t child = 2 * idx;
- if (child < size() && higher(child + 1, child)) child++;
- if (higher(child, idx))
- swap_indices(child, idx);
- else
- break;
- idx = child;
- }
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::higher(size_t idx1, size_t idx2) const {
- if (!(0u < idx1 && idx1 < pq.size() && 0u < idx2 && idx2 < pq.size())) {
- return false; // got to do something.
- }
- return Comparator()(pq[idx1], pq[idx2]);
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::contains(sp<const AA> a) const {
- if (a == nullptr) return false; // publicly, we pretend that nullptr is not actually in pq.
- return indices.count(a) > 0;
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::swap_indices(size_t i, size_t j) {
- if (!(0u < i && i < pq.size() && 0u < j && j < pq.size())) {
- return;
- }
- sp<const AA> val_i = pq[i];
- sp<const AA> val_j = pq[j];
- pq[i] = val_j;
- pq[j] = val_i;
- indices[val_i] = j;
- indices[val_j] = i;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
deleted file mode 100644
index 5a4a41d01de6..000000000000
--- a/cmds/statsd/src/anomaly/subscriber_util.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "external/Perfetto.h"
-#include "subscriber/IncidentdReporter.h"
-#include "subscriber/SubscriberReporter.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void triggerSubscribers(int64_t ruleId, int64_t metricId, const MetricDimensionKey& dimensionKey,
- int64_t metricValue, const ConfigKey& configKey,
- const std::vector<Subscription>& subscriptions) {
- VLOG("informSubscribers called.");
- if (subscriptions.empty()) {
- VLOG("No Subscriptions were associated.");
- return;
- }
-
- for (const Subscription& subscription : subscriptions) {
- if (subscription.probability_of_informing() < 1
- && ((float)rand() / (float)RAND_MAX) >= subscription.probability_of_informing()) {
- // Note that due to float imprecision, 0.0 and 1.0 might not truly mean never/always.
- // The config writer was advised to use -0.1 and 1.1 for never/always.
- ALOGI("Fate decided that a subscriber would not be informed.");
- continue;
- }
- switch (subscription.subscriber_information_case()) {
- case Subscription::SubscriberInformationCase::kIncidentdDetails:
- if (!GenerateIncidentReport(subscription.incidentd_details(), ruleId, metricId,
- dimensionKey, metricValue, configKey)) {
- ALOGW("Failed to generate incident report.");
- }
- break;
- case Subscription::SubscriberInformationCase::kPerfettoDetails:
- if (!CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details(),
- subscription.id(), ruleId, configKey)) {
- ALOGW("Failed to generate perfetto traces.");
- }
- break;
- case Subscription::SubscriberInformationCase::kBroadcastSubscriberDetails:
- SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription,
- dimensionKey);
- break;
- default:
- break;
- }
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.h b/cmds/statsd/src/anomaly/subscriber_util.h
deleted file mode 100644
index 1df3c8991f94..000000000000
--- a/cmds/statsd/src/anomaly/subscriber_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void triggerSubscribers(const int64_t ruleId, const int64_t metricId,
- const MetricDimensionKey& dimensionKey, int64_t metricValue,
- const ConfigKey& configKey, const std::vector<Subscription>& subscriptions);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
deleted file mode 100644
index ff5717e4fa78..000000000000
--- a/cmds/statsd/src/atom_field_options.proto
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_multiple_files = true;
-option java_outer_classname = "AtomFieldOptions";
-
-import "google/protobuf/descriptor.proto";
-
-// Used to annotate an atom that represents a state change. A state change atom must have exactly
-// ONE exclusive state field, and any number of primary key fields. For example, message
-// UidProcessStateChanged {
-// optional int32 uid = 1 [(state_field_option).primary_field = true];
-// optional android.app.ProcessStateEnum state =
-// 2 [(state_field_option).exclusive_state = true];
-// }
-// Each UidProcessStateChanged atom event represents a state change for a specific uid.
-// A new state automatically overrides the previous state.
-//
-// If the atom has 2 or more primary fields, it means the combination of the
-// primary fields are the primary key.
-// For example:
-// message ThreadStateChanged {
-// optional int32 pid = 1 [(state_field_option).primary_field = true];
-// optional int32 tid = 2 [(state_field_option).primary_field = true];
-// optional int32 state = 3 [(state_field_option).exclusive_state = true];
-// }
-//
-// Sometimes, there is no primary key field, when the state is GLOBAL.
-// For example,
-// message ScreenStateChanged {
-// optional android.view.DisplayStateEnum state =
-// 1 [(state_field_option).exclusive_state = true];
-// }
-//
-// For state atoms with attribution chain, sometimes the primary key is the first uid in the chain.
-// For example:
-// message AudioStateChanged {
-// repeated AttributionNode attribution_node = 1
-// [(stateFieldOption).primary_field_first_uid = true];
-//
-// enum State {
-// OFF = 0;
-// ON = 1;
-// // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes).
-// RESET = 2;
-// }
-// optional State state = 2 [(stateFieldOption).exclusive_state = true];
-// }
-message StateAtomFieldOption {
- // Fields that represent the key that the state belongs to.
- // Used on simple proto fields. Do not use on attribution chains.
- optional bool primary_field = 1 [default = false];
-
- // The field that represents the state. It's an exclusive state.
- optional bool exclusive_state = 2 [default = false];
-
- // Used on an attribution chain field to indicate that the first uid is the
- // primary field.
- optional bool primary_field_first_uid = 3 [default = false];
-
- // Note: We cannot annotate directly on the enums because many enums are imported from other
- // proto files in the platform. proto-lite cc library does not support annotations unfortunately
-
- // Knowing the default state value allows state trackers to remove entries that become the
- // default state. If there is no default value specified, the default value is unknown, and all
- // states will be tracked in memory.
- optional int32 default_state_value = 4;
-
- // A reset state signals all states go to default value. For example, BLE reset means all active
- // BLE scans are to be turned off.
- optional int32 trigger_state_reset_value = 5;
-
- // If the state change needs to count nesting.
- optional bool nested = 6 [default = true];
-}
-
-// Used to generate StatsLog.write APIs.
-enum LogMode {
- MODE_UNSET = 0;
- // Log fields as their actual types e.g., all primary data types.
- // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode
- MODE_AUTOMATIC = 1;
- // Log fields in their proto binary format. These fields will not be parsed in statsd
- MODE_BYTES = 2;
-}
-
-extend google.protobuf.FieldOptions {
- // Flags to decorate an atom that presents a state change.
- optional StateAtomFieldOption state_field_option = 50000;
-
- // Flags to decorate the uid fields in an atom.
- optional bool is_uid = 50001 [default = false];
-
- optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
-
- repeated string module = 50004;
-
- optional bool truncate_timestamp = 50005 [default = false];
-}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
deleted file mode 100644
index fa68b790328b..000000000000
--- a/cmds/statsd/src/atoms.proto
+++ /dev/null
@@ -1,11275 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "AtomsProto";
-
-import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
-import "frameworks/base/core/proto/android/app/enums.proto";
-import "frameworks/base/core/proto/android/app/job/enums.proto";
-import "frameworks/base/core/proto/android/app/settings_enums.proto";
-import "frameworks/base/core/proto/android/app/media_output_enum.proto";
-import "frameworks/base/core/proto/android/app/tvsettings_enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/a2dp/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/hci/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/hfp/enums.proto";
-import "frameworks/base/core/proto/android/bluetooth/smp/enums.proto";
-import "frameworks/base/core/proto/android/debug/enums.proto";
-import "frameworks/base/core/proto/android/hardware/biometrics/enums.proto";
-import "frameworks/base/core/proto/android/hardware/sensor/assist/enums.proto";
-import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
-import "frameworks/base/core/proto/android/os/enums.proto";
-import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto";
-import "frameworks/base/core/proto/android/server/enums.proto";
-import "frameworks/base/core/proto/android/server/job/enums.proto";
-import "frameworks/base/core/proto/android/server/location/enums.proto";
-import "frameworks/base/core/proto/android/service/procstats_enum.proto";
-import "frameworks/base/core/proto/android/service/usb.proto";
-import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
-import "frameworks/base/core/proto/android/stats/connectivity/tethering.proto";
-import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto";
-import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto";
-import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto";
-import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto";
-import "frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto";
-import "frameworks/base/core/proto/android/stats/enums.proto";
-import "frameworks/base/core/proto/android/stats/intelligence/enums.proto";
-import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
-import "frameworks/base/core/proto/android/stats/location/location_enums.proto";
-import "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.proto";
-import "frameworks/base/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto";
-import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto";
-import "frameworks/base/core/proto/android/stats/style/style_enums.proto";
-import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto";
-import "frameworks/base/core/proto/android/telecomm/enums.proto";
-import "frameworks/base/core/proto/android/telephony/enums.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
-import "frameworks/base/core/proto/android/wifi/enums.proto";
-import "frameworks/base/core/proto/android/stats/textclassifier/textclassifier_enums.proto";
-import "frameworks/base/core/proto/android/stats/otaupdate/updateengine_enums.proto";
-
-/**
- * The master atom class. This message defines all of the available
- * raw stats log events from the Android system, also known as "atoms."
- *
- * This field contains a single oneof with all of the available messages.
- * The stats-log-api-gen tool runs as part of the Android build and
- * generates the android.util.StatsLog class, which contains the constants
- * and methods that Android uses to log.
- *
- * This Atom class is not actually built into the Android system.
- * Instead, statsd on Android constructs these messages synthetically,
- * in the format defined here and in stats_log.proto.
- */
-message Atom {
- // Pushed atoms start at 2.
- oneof pushed {
- // For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
- BleScanStateChanged ble_scan_state_changed = 2
- [(module) = "bluetooth", (module) = "statsdtest"];
- ProcessStateChanged process_state_changed = 3 [(module) = "framework"];
- BleScanResultReceived ble_scan_result_received = 4 [(module) = "bluetooth"];
- SensorStateChanged sensor_state_changed =
- 5 [(module) = "framework", (module) = "statsdtest"];
- GpsScanStateChanged gps_scan_state_changed = 6 [(module) = "framework"];
- SyncStateChanged sync_state_changed = 7 [(module) = "framework", (module) = "statsdtest"];
- ScheduledJobStateChanged scheduled_job_state_changed =
- 8 [(module) = "framework", (module) = "statsdtest"];
- ScreenBrightnessChanged screen_brightness_changed =
- 9 [(module) = "framework", (module) = "statsdtest"];
- WakelockStateChanged wakelock_state_changed =
- 10 [(module) = "framework", (module) = "statsdtest"];
- LongPartialWakelockStateChanged long_partial_wakelock_state_changed =
- 11 [(module) = "framework"];
- MobileRadioPowerStateChanged mobile_radio_power_state_changed =
- 12 [(module) = "framework", (truncate_timestamp) = true];
- WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13 [(module) = "framework"];
- ActivityManagerSleepStateChanged activity_manager_sleep_state_changed =
- 14 [(module) = "framework"];
- MemoryFactorStateChanged memory_factor_state_changed = 15 [(module) = "framework"];
- ExcessiveCpuUsageReported excessive_cpu_usage_reported = 16 [(module) = "framework"];
- CachedKillReported cached_kill_reported = 17 [(module) = "framework"];
- ProcessMemoryStatReported process_memory_stat_reported = 18 [(module) = "framework"];
- LauncherUIChanged launcher_event = 19 [(module) = "sysui"];
- BatterySaverModeStateChanged battery_saver_mode_state_changed =
- 20 [(module) = "framework", (module) = "statsdtest"];
- DeviceIdleModeStateChanged device_idle_mode_state_changed = 21 [(module) = "framework"];
- DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22 [(module) = "framework"];
- AudioStateChanged audio_state_changed =
- 23 [(module) = "framework", (truncate_timestamp) = true];
- MediaCodecStateChanged media_codec_state_changed = 24 [(module) = "framework"];
- CameraStateChanged camera_state_changed = 25 [(module) = "framework"];
- FlashlightStateChanged flashlight_state_changed = 26 [(module) = "framework"];
- UidProcessStateChanged uid_process_state_changed =
- 27 [(module) = "framework", (module) = "statsdtest"];
- ProcessLifeCycleStateChanged process_life_cycle_state_changed =
- 28 [(module) = "framework", (module) = "statsdtest"];
- ScreenStateChanged screen_state_changed =
- 29 [(module) = "framework", (module) = "statsdtest"];
- BatteryLevelChanged battery_level_changed =
- 30 [(module) = "framework", (module) = "statsdtest"];
- ChargingStateChanged charging_state_changed = 31 [(module) = "framework"];
- PluggedStateChanged plugged_state_changed = 32
- [(module) = "framework", (module) = "statsdtest"];
- InteractiveStateChanged interactive_state_changed = 33 [(module) = "framework"];
- TouchEventReported touch_event_reported = 34;
- WakeupAlarmOccurred wakeup_alarm_occurred = 35 [(module) = "framework"];
- KernelWakeupReported kernel_wakeup_reported = 36 [(module) = "framework"];
- WifiLockStateChanged wifi_lock_state_changed = 37 [(module) = "wifi"];
- WifiSignalStrengthChanged wifi_signal_strength_changed = 38 [(module) = "wifi"];
- WifiScanStateChanged wifi_scan_state_changed = 39 [(module) = "wifi"];
- PhoneSignalStrengthChanged phone_signal_strength_changed =
- 40 [(module) = "framework", (truncate_timestamp) = true];
- SettingChanged setting_changed = 41 [(module) = "framework"];
- ActivityForegroundStateChanged activity_foreground_state_changed =
- 42 [(module) = "framework", (module) = "statsdtest"];
- IsolatedUidChanged isolated_uid_changed =
- 43 [(module) = "framework", (module) = "statsd", (module) = "statsdtest"];
- PacketWakeupOccurred packet_wakeup_occurred = 44 [(module) = "framework"];
- WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"];
- AnomalyDetected anomaly_detected = 46 [(module) = "statsd"];
- AppBreadcrumbReported app_breadcrumb_reported = 47 [(module) = "statsd"];
- AppStartOccurred app_start_occurred = 48 [(module) = "framework", (module) = "statsdtest"];
- AppStartCanceled app_start_canceled = 49 [(module) = "framework"];
- AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"];
- LmkKillOccurred lmk_kill_occurred = 51 [(module) = "lmkd"];
- PictureInPictureStateChanged picture_in_picture_state_changed = 52 [(module) = "framework"];
- WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53 [(module) = "wifi"];
- LmkStateChanged lmk_state_changed = 54 [(module) = "lmkd"];
- AppStartMemoryStateCaptured app_start_memory_state_captured = 55 [(module) = "framework"];
- ShutdownSequenceReported shutdown_sequence_reported = 56 [(module) = "framework"];
- BootSequenceReported boot_sequence_reported = 57;
- DaveyOccurred davey_occurred = 58 [(module) = "statsd"];
- OverlayStateChanged overlay_state_changed =
- 59 [(module) = "framework", (module) = "statsdtest"];
- ForegroundServiceStateChanged foreground_service_state_changed
- = 60 [(module) = "framework"];
- CallStateChanged call_state_changed =
- 61 [(module) = "telecom", (truncate_timestamp) = true];
- KeyguardStateChanged keyguard_state_changed = 62 [(module) = "sysui"];
- KeyguardBouncerStateChanged keyguard_bouncer_state_changed = 63 [(module) = "sysui"];
- KeyguardBouncerPasswordEntered keyguard_bouncer_password_entered = 64 [(module) = "sysui"];
- AppDied app_died = 65 [(module) = "framework"];
- ResourceConfigurationChanged resource_configuration_changed = 66 [(module) = "framework"];
- BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67 [(module) = "framework"];
- BluetoothConnectionStateChanged bluetooth_connection_state_changed =
- 68 [(module) = "bluetooth"];
- GpsSignalQualityChanged gps_signal_quality_changed = 69 [(module) = "framework"];
- UsbConnectorStateChanged usb_connector_state_changed = 70 [(module) = "framework"];
- SpeakerImpedanceReported speaker_impedance_reported = 71;
- HardwareFailed hardware_failed = 72;
- PhysicalDropDetected physical_drop_detected = 73;
- ChargeCyclesReported charge_cycles_reported = 74;
- MobileConnectionStateChanged mobile_connection_state_changed = 75 [(module) = "telephony"];
- MobileRadioTechnologyChanged mobile_radio_technology_changed = 76 [(module) = "telephony"];
- UsbDeviceAttached usb_device_attached = 77 [(module) = "framework"];
- AppCrashOccurred app_crash_occurred = 78 [(module) = "framework", (module) = "statsdtest"];
- ANROccurred anr_occurred = 79 [(module) = "framework"];
- WTFOccurred wtf_occurred = 80 [(module) = "framework"];
- LowMemReported low_mem_reported = 81 [(module) = "framework"];
- GenericAtom generic_atom = 82;
- KeyValuePairsAtom key_value_pairs_atom = 83 [(module) = "framework", (module) = "statsd"];
- VibratorStateChanged vibrator_state_changed = 84 [(module) = "framework"];
- DeferredJobStatsReported deferred_job_stats_reported = 85 [(module) = "framework"];
- ThermalThrottlingStateChanged thermal_throttling = 86 [deprecated=true];
- BiometricAcquired biometric_acquired = 87 [(module) = "framework"];
- BiometricAuthenticated biometric_authenticated = 88 [(module) = "framework"];
- BiometricErrorOccurred biometric_error_occurred = 89 [(module) = "framework"];
- UiEventReported ui_event_reported = 90 [(module) = "framework", (module) = "sysui"];
- BatteryHealthSnapshot battery_health_snapshot = 91;
- SlowIo slow_io = 92;
- BatteryCausedShutdown battery_caused_shutdown = 93;
- PhoneServiceStateChanged phone_service_state_changed = 94 [(module) = "framework"];
- PhoneStateChanged phone_state_changed = 95 [(module) = "framework"];
- UserRestrictionChanged user_restriction_changed = 96;
- SettingsUIChanged settings_ui_changed = 97 [(module) = "settings"];
- ConnectivityStateChanged connectivity_state_changed = 98 [(module) = "framework"];
- // TODO: service state change is very noisy shortly after boot, as well
- // as at other transitions - coming out of doze, device plugged in, etc.
- // Consider removing this if it becomes a problem
- ServiceStateChanged service_state_changed = 99 [(module) = "framework"];
- ServiceLaunchReported service_launch_reported = 100 [(module) = "framework"];
- FlagFlipUpdateOccurred flag_flip_update_occurred = 101 [(module) = "framework"];
- BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "statsd"];
- DevicePolicyEvent device_policy_event = 103 [(module) = "framework"];
- DocsUIFileOperationCanceledReported docs_ui_file_op_canceled = 104 [(module) = "docsui"];
- DocsUIFileOperationCopyMoveModeReported docs_ui_file_op_copy_move_mode_reported =
- 105 [(module) = "docsui"];
- DocsUIFileOperationFailureReported docs_ui_file_op_failure = 106 [(module) = "docsui"];
- DocsUIFileOperationReported docs_ui_provider_file_op = 107 [(module) = "docsui"];
- DocsUIInvalidScopedAccessRequestReported docs_ui_invalid_scoped_access_request =
- 108 [(module) = "docsui"];
- DocsUILaunchReported docs_ui_launch_reported = 109 [(module) = "docsui"];
- DocsUIRootVisitedReported docs_ui_root_visited = 110 [(module) = "docsui"];
- DocsUIStartupMsReported docs_ui_startup_ms = 111 [(module) = "docsui"];
- DocsUIUserActionReported docs_ui_user_action_reported = 112 [(module) = "docsui"];
- WifiEnabledStateChanged wifi_enabled_state_changed = 113 [(module) = "framework"];
- WifiRunningStateChanged wifi_running_state_changed = 114
- [(module) = "framework", deprecated = true];
- AppCompacted app_compacted = 115 [(module) = "framework"];
- NetworkDnsEventReported network_dns_event_reported = 116 [(module) = "resolv"];
- DocsUIPickerLaunchedFromReported docs_ui_picker_launched_from_reported =
- 117 [(module) = "docsui"];
- DocsUIPickResultReported docs_ui_pick_result_reported = 118 [(module) = "docsui"];
- DocsUISearchModeReported docs_ui_search_mode_reported = 119 [(module) = "docsui"];
- DocsUISearchTypeReported docs_ui_search_type_reported = 120 [(module) = "docsui"];
- DataStallEvent data_stall_event = 121 [(module) = "network_stack"];
- RescuePartyResetReported rescue_party_reset_reported = 122 [(module) = "framework"];
- SignedConfigReported signed_config_reported = 123 [(module) = "framework"];
- GnssNiEventReported gnss_ni_event_reported = 124 [(module) = "framework"];
- BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event =
- 125 [(module) = "bluetooth"];
- BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed =
- 126 [(module) = "bluetooth"];
- BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed =
- 127 [(module) = "bluetooth"];
- AppDowngraded app_downgraded = 128 [(module) = "framework"];
- AppOptimizedAfterDowngraded app_optimized_after_downgraded = 129;
- LowStorageStateChanged low_storage_state_changed = 130 [(module) = "framework"];
- GnssNfwNotificationReported gnss_nfw_notification_reported = 131 [(module) = "framework"];
- GnssConfigurationReported gnss_configuration_reported = 132 [(module) = "framework"];
- UsbPortOverheatEvent usb_port_overheat_event_reported = 133;
- NfcErrorOccurred nfc_error_occurred = 134 [(module) = "nfc"];
- NfcStateChanged nfc_state_changed = 135 [(module) = "nfc"];
- NfcBeamOccurred nfc_beam_occurred = 136 [(module) = "nfc"];
- NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"];
- NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"];
- NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"];
- SeStateChanged se_state_changed = 140 [(module) = "secure_element"];
- SeOmapiReported se_omapi_reported = 141 [(module) = "secure_element"];
- BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported =
- 142 [(module) = "framework"];
- AttentionManagerServiceResultReported attention_manager_service_result_reported =
- 143 [(module) = "framework"];
- AdbConnectionChanged adb_connection_changed = 144 [(module) = "framework"];
- SpeechDspStatReported speech_dsp_stat_reported = 145;
- UsbContaminantReported usb_contaminant_reported = 146 [(module) = "framework"];
- WatchdogRollbackOccurred watchdog_rollback_occurred =
- 147 [(module) = "framework", (module) = "statsd"];
- BiometricSystemHealthIssueDetected biometric_system_health_issue_detected =
- 148 [(module) = "framework"];
- BubbleUIChanged bubble_ui_changed = 149 [(module) = "sysui"];
- ScheduledJobConstraintChanged scheduled_job_constraint_changed =
- 150 [(module) = "framework"];
- BluetoothActiveDeviceChanged bluetooth_active_device_changed =
- 151 [(module) = "bluetooth"];
- BluetoothA2dpPlaybackStateChanged bluetooth_a2dp_playback_state_changed =
- 152 [(module) = "bluetooth"];
- BluetoothA2dpCodecConfigChanged bluetooth_a2dp_codec_config_changed =
- 153 [(module) = "bluetooth"];
- BluetoothA2dpCodecCapabilityChanged bluetooth_a2dp_codec_capability_changed =
- 154 [(module) = "bluetooth"];
- BluetoothA2dpAudioUnderrunReported bluetooth_a2dp_audio_underrun_reported =
- 155 [(module) = "bluetooth"];
- BluetoothA2dpAudioOverrunReported bluetooth_a2dp_audio_overrun_reported =
- 156 [(module) = "bluetooth"];
- BluetoothDeviceRssiReported bluetooth_device_rssi_reported =
- 157 [(module) = "bluetooth"];
- BluetoothDeviceFailedContactCounterReported
- bluetooth_device_failed_contact_counter_reported = 158 [(module) = "bluetooth"];
- BluetoothDeviceTxPowerLevelReported bluetooth_device_tx_power_level_reported =
- 159 [(module) = "bluetooth"];
- BluetoothHciTimeoutReported bluetooth_hci_timeout_reported =
- 160 [(module) = "bluetooth"];
- BluetoothQualityReportReported bluetooth_quality_report_reported =
- 161 [(module) = "bluetooth"];
- BluetoothDeviceInfoReported bluetooth_device_info_reported =
- 162 [(module) = "bluetooth"];
- BluetoothRemoteVersionInfoReported bluetooth_remote_version_info_reported =
- 163 [(module) = "bluetooth"];
- BluetoothSdpAttributeReported bluetooth_sdp_attribute_reported =
- 164 [(module) = "bluetooth"];
- BluetoothBondStateChanged bluetooth_bond_state_changed =
- 165 [(module) = "bluetooth"];
- BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported =
- 166 [(module) = "bluetooth"];
- BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported =
- 167 [(module) = "bluetooth"];
- ScreenTimeoutExtensionReported screen_timeout_extension_reported =
- 168 [(module) = "framework"];
- ProcessStartTime process_start_time = 169 [(module) = "framework"];
- PermissionGrantRequestResultReported permission_grant_request_result_reported =
- 170 [(module) = "permissioncontroller"];
- BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
- DeviceIdentifierAccessDenied device_identifier_access_denied =
- 172 [(module) = "telephony_common"];
- BubbleDeveloperErrorReported bubble_developer_error_reported = 173 [(module) = "framework"];
- AssistGestureStageReported assist_gesture_stage_reported = 174 [(module) = "sysui"];
- AssistGestureFeedbackReported assist_gesture_feedback_reported = 175 [(module) = "sysui"];
- AssistGestureProgressReported assist_gesture_progress_reported = 176 [(module) = "sysui"];
- TouchGestureClassified touch_gesture_classified = 177 [(module) = "framework"];
- HiddenApiUsed hidden_api_used = 178 [(module) = "framework"];
- StyleUIChanged style_ui_changed = 179 [(module) = "sysui"];
- PrivacyIndicatorsInteracted privacy_indicators_interacted =
- 180 [(module) = "permissioncontroller"];
- AppInstallOnExternalStorageReported app_install_on_external_storage_reported =
- 181 [(module) = "framework"];
- NetworkStackReported network_stack_reported = 182 [(module) = "network_stack"];
- AppMovedStorageReported app_moved_storage_reported = 183 [(module) = "framework"];
- BiometricEnrolled biometric_enrolled = 184 [(module) = "framework"];
- SystemServerWatchdogOccurred system_server_watchdog_occurred = 185 [(module) = "framework"];
- TombStoneOccurred tomb_stone_occurred = 186 [(module) = "framework"];
- BluetoothClassOfDeviceReported bluetooth_class_of_device_reported =
- 187 [(module) = "bluetooth"];
- IntelligenceEventReported intelligence_event_reported =
- 188 [(module) = "intelligence"];
- ThermalThrottlingSeverityStateChanged thermal_throttling_severity_state_changed =
- 189 [(module) = "framework"];
- RoleRequestResultReported role_request_result_reported =
- 190 [(module) = "permissioncontroller"];
- MediametricsAudiopolicyReported mediametrics_audiopolicy_reported = 191;
- MediametricsAudiorecordReported mediametrics_audiorecord_reported = 192;
- MediametricsAudiothreadReported mediametrics_audiothread_reported = 193;
- MediametricsAudiotrackReported mediametrics_audiotrack_reported = 194;
- MediametricsCodecReported mediametrics_codec_reported = 195;
- MediametricsDrmWidevineReported mediametrics_drm_widevine_reported = 196;
- MediametricsExtractorReported mediametrics_extractor_reported = 197;
- MediametricsMediadrmReported mediametrics_mediadrm_reported = 198;
- MediametricsNuPlayerReported mediametrics_nuplayer_reported = 199;
- MediametricsRecorderReported mediametrics_recorder_reported = 200;
- MediametricsDrmManagerReported mediametrics_drmmanager_reported = 201;
- CarPowerStateChanged car_power_state_changed = 203 [(module) = "car"];
- GarageModeInfo garage_mode_info = 204 [(module) = "car"];
- TestAtomReported test_atom_reported = 205 [(module) = "cts"];
- ContentCaptureCallerMismatchReported content_capture_caller_mismatch_reported =
- 206 [(module) = "framework"];
- ContentCaptureServiceEvents content_capture_service_events = 207 [(module) = "framework"];
- ContentCaptureSessionEvents content_capture_session_events = 208 [(module) = "framework"];
- ContentCaptureFlushed content_capture_flushed = 209 [(module) = "framework"];
- LocationManagerApiUsageReported location_manager_api_usage_reported =
- 210 [(module) = "framework"];
- ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported =
- 211 [(module) = "permissioncontroller"];
- RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result =
- 212 [(module) = "permissioncontroller"];
- GrantPermissionsActivityButtonActions grant_permissions_activity_button_actions =
- 213 [(module) = "permissioncontroller"];
- LocationAccessCheckNotificationAction location_access_check_notification_action =
- 214 [(module) = "permissioncontroller"];
- AppPermissionFragmentActionReported app_permission_fragment_action_reported =
- 215 [(module) = "permissioncontroller"];
- AppPermissionFragmentViewed app_permission_fragment_viewed =
- 216 [(module) = "permissioncontroller"];
- AppPermissionsFragmentViewed app_permissions_fragment_viewed =
- 217 [(module) = "permissioncontroller"];
- PermissionAppsFragmentViewed permission_apps_fragment_viewed =
- 218 [(module) = "permissioncontroller"];
- TextSelectionEvent text_selection_event = 219 [(module) = "textclassifier"];
- TextLinkifyEvent text_linkify_event = 220 [(module) = "textclassifier"];
- ConversationActionsEvent conversation_actions_event = 221 [(module) = "textclassifier"];
- LanguageDetectionEvent language_detection_event = 222 [(module) = "textclassifier"];
- ExclusionRectStateChanged exclusion_rect_state_changed = 223 [(module) = "framework"];
- BackGesture back_gesture_reported_reported = 224 [(module) = "sysui"];
- UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225;
- UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226;
- CameraActionEvent camera_action_event = 227 [(module) = "framework"];
- AppCompatibilityChangeReported app_compatibility_change_reported =
- 228 [(module) = "framework"];
- PerfettoUploaded perfetto_uploaded = 229 [(module) = "perfetto"];
- VmsClientConnectionStateChanged vms_client_connection_state_changed =
- 230 [(module) = "car"];
- MediaProviderScanOccurred media_provider_scan_occurred = 233 [(module) = "mediaprovider"];
- MediaContentDeleted media_content_deleted = 234 [(module) = "mediaprovider"];
- MediaProviderPermissionRequested media_provider_permission_requested =
- 235 [(module) = "mediaprovider"];
- MediaProviderSchemaChanged media_provider_schema_changed = 236 [(module) = "mediaprovider"];
- MediaProviderIdleMaintenanceFinished media_provider_idle_maintenance_finished =
- 237 [(module) = "mediaprovider"];
- RebootEscrowRecoveryReported reboot_escrow_recovery_reported = 238 [(module) = "framework"];
- BootTimeEventDuration boot_time_event_duration_reported = 239 [(module) = "framework"];
- BootTimeEventElapsedTime boot_time_event_elapsed_time_reported =
- 240 [(module) = "framework"];
- BootTimeEventUtcTime boot_time_event_utc_time_reported = 241;
- BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"];
- UserspaceRebootReported userspace_reboot_reported = 243 [(module) = "framework"];
- NotificationReported notification_reported = 244 [(module) = "framework"];
- NotificationPanelReported notification_panel_reported = 245 [(module) = "sysui"];
- NotificationChannelModified notification_channel_modified = 246 [(module) = "framework"];
- IntegrityCheckResultReported integrity_check_result_reported = 247 [(module) = "framework"];
- IntegrityRulesPushed integrity_rules_pushed = 248 [(module) = "framework"];
- CellBroadcastMessageReported cb_message_reported =
- 249 [(module) = "cellbroadcast"];
- CellBroadcastMessageError cb_message_error =
- 250 [(module) = "cellbroadcast"];
- WifiHealthStatReported wifi_health_stat_reported = 251 [(module) = "wifi"];
- WifiFailureStatReported wifi_failure_stat_reported = 252 [(module) = "wifi"];
- WifiConnectionResultReported wifi_connection_result_reported = 253 [(module) = "wifi"];
- AppFreezeChanged app_freeze_changed = 254 [(module) = "framework"];
- SnapshotMergeReported snapshot_merge_reported = 255;
- ForegroundServiceAppOpSessionEnded foreground_service_app_op_session_ended =
- 256 [(module) = "framework"];
- DisplayJankReported display_jank_reported = 257;
- AppStandbyBucketChanged app_standby_bucket_changed = 258 [(module) = "framework"];
- SharesheetStarted sharesheet_started = 259 [(module) = "framework"];
- RankingSelected ranking_selected = 260 [(module) = "framework", (module) = "sysui"];
- TvSettingsUIInteracted tvsettings_ui_interacted = 261 [(module) = "tv_settings"];
- LauncherStaticLayout launcher_snapshot = 262 [(module) = "sysui"];
- PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"];
- UserLifecycleJourneyReported user_lifecycle_journey_reported = 264 [(module) = "framework"];
- UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"];
- AccessibilityShortcutReported accessibility_shortcut_reported =
- 266 [(module) = "framework"];
- AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "settings"];
- DocsUIDragAndDropReported docs_ui_drag_and_drop_reported = 268 [(module) = "docsui"];
- AppUsageEventOccurred app_usage_event_occurred = 269 [(module) = "framework"];
- AutoRevokeNotificationClicked auto_revoke_notification_clicked =
- 270 [(module) = "permissioncontroller"];
- AutoRevokeFragmentAppViewed auto_revoke_fragment_app_viewed =
- 271 [(module) = "permissioncontroller"];
- AutoRevokedAppInteraction auto_revoked_app_interaction =
- 272 [(module) = "permissioncontroller", (module) = "settings"];
- AppPermissionGroupsFragmentAutoRevokeAction
- app_permission_groups_fragment_auto_revoke_action =
- 273 [(module) = "permissioncontroller"];
- EvsUsageStatsReported evs_usage_stats_reported = 274 [(module) = "evs"];
- AudioPowerUsageDataReported audio_power_usage_data_reported = 275;
- TvTunerStateChanged tv_tuner_state_changed = 276 [(module) = "framework"];
- MediaOutputOpSwitchReported mediaoutput_op_switch_reported =
- 277 [(module) = "settings"];
- CellBroadcastMessageFiltered cb_message_filtered =
- 278 [(module) = "cellbroadcast"];
- TvTunerDvrStatus tv_tuner_dvr_status = 279 [(module) = "framework"];
- TvCasSessionOpenStatus tv_cas_session_open_status =
- 280 [(module) = "framework"];
- AssistantInvocationReported assistant_invocation_reported = 281 [(module) = "framework"];
- DisplayWakeReported display_wake_reported = 282 [(module) = "framework"];
- CarUserHalModifyUserRequestReported car_user_hal_modify_user_request_reported =
- 283 [(module) = "car"];
- CarUserHalModifyUserResponseReported car_user_hal_modify_user_response_reported =
- 284 [(module) = "car"];
- CarUserHalPostSwitchResponseReported car_user_hal_post_switch_response_reported =
- 285 [(module) = "car"];
- CarUserHalInitialUserInfoRequestReported car_user_hal_initial_user_info_request_reported =
- 286 [(module) = "car"];
- CarUserHalInitialUserInfoResponseReported car_user_hal_initial_user_info_response_reported =
- 287 [(module) = "car"];
- CarUserHalUserAssociationRequestReported car_user_hal_user_association_request_reported =
- 288 [(module) = "car"];
- CarUserHalSetUserAssociationResponseReported car_user_hal_set_user_association_response_reported =
- 289 [(module) = "car"];
- NetworkIpProvisioningReported network_ip_provisioning_reported =
- 290 [(module) = "network_stack"];
- NetworkDhcpRenewReported network_dhcp_renew_reported = 291 [(module) = "network_stack"];
- NetworkValidationReported network_validation_reported = 292 [(module) = "network_stack"];
- NetworkStackQuirkReported network_stack_quirk_reported = 293 [(module) = "network_stack"];
- MediametricsAudioRecordDeviceUsageReported mediametrics_audiorecorddeviceusage_reported =
- 294;
- MediametricsAudioThreadDeviceUsageReported mediametrics_audiothreaddeviceusage_reported =
- 295;
- MediametricsAudioTrackDeviceUsageReported mediametrics_audiotrackdeviceusage_reported =
- 296;
- MediametricsAudioDeviceConnectionReported mediametrics_audiodeviceconnection_reported =
- 297;
- BlobCommitted blob_committed = 298 [(module) = "framework"];
- BlobLeased blob_leased = 299 [(module) = "framework"];
- BlobOpened blob_opened = 300 [(module) = "framework"];
- ContactsProviderStatusReported contacts_provider_status_reported = 301;
- KeystoreKeyEventReported keystore_key_event_reported = 302;
- NetworkTetheringReported network_tethering_reported =
- 303 [(module) = "network_tethering"];
- ImeTouchReported ime_touch_reported = 304 [(module) = "sysui"];
-
- MediametricsMediaParserReported mediametrics_mediaparser_reported = 316;
-
- TextClassifierApiUsageReported text_classifier_api_usage_reported = 318 [(module) = "textclassifier"];
-
- // StatsdStats tracks platform atoms with ids upto 500.
- // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
- }
-
- // Pulled events will start at field 10000.
- // Next: 10084
- oneof pulled {
- WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"];
- WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"];
- MobileBytesTransfer mobile_bytes_transfer =
- 10002 [(module) = "framework", (truncate_timestamp) = true];
- MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg =
- 10003 [(module) = "framework", (truncate_timestamp) = true];
- BluetoothBytesTransfer bluetooth_bytes_transfer = 10006 [(module) = "framework"];
- KernelWakelock kernel_wakelock = 10004 [(module) = "framework"];
- SubsystemSleepState subsystem_sleep_state = 10005 [(module) = "statsdtest"];
- CpuTimePerFreq cpu_time_per_freq = 10008 [(module) = "framework"];
- CpuTimePerUid cpu_time_per_uid = 10009 [(module) = "framework", (module) = "statsdtest"];
- CpuTimePerUidFreq cpu_time_per_uid_freq =
- 10010 [(module) = "framework", (module) = "statsd"];
- WifiActivityInfo wifi_activity_info = 10011 [(module) = "framework"];
- ModemActivityInfo modem_activity_info = 10012 [(module) = "framework"];
- BluetoothActivityInfo bluetooth_activity_info = 10007 [(module) = "framework"];
- ProcessMemoryState process_memory_state = 10013 [(module) = "framework"];
- SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"];
- SystemUptime system_uptime = 10015 [(module) = "framework"];
- CpuActiveTime cpu_active_time = 10016 [(module) = "framework", (module) = "statsdtest"];
- CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework"];
- DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"];
- RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"];
- FullBatteryCapacity full_battery_capacity = 10020 [(module) = "framework"];
- Temperature temperature = 10021 [(module) = "framework", (module) = "statsdtest"];
- BinderCalls binder_calls = 10022 [(module) = "framework", (module) = "statsd"];
- BinderCallsExceptions binder_calls_exceptions = 10023 [(module) = "framework"];
- LooperStats looper_stats = 10024 [(module) = "framework", (module) = "statsd"];
- DiskStats disk_stats = 10025 [(module) = "framework"];
- DirectoryUsage directory_usage = 10026 [(module) = "framework"];
- AppSize app_size = 10027 [(module) = "framework"];
- CategorySize category_size = 10028 [(module) = "framework"];
- ProcStats proc_stats = 10029 [(module) = "framework"];
- BatteryVoltage battery_voltage = 10030 [(module) = "framework"];
- NumFingerprintsEnrolled num_fingerprints_enrolled = 10031 [(module) = "framework"];
- DiskIo disk_io = 10032 [(module) = "framework"];
- PowerProfile power_profile = 10033 [(module) = "framework"];
- ProcStatsPkgProc proc_stats_pkg_proc = 10034 [(module) = "framework"];
- ProcessCpuTime process_cpu_time = 10035 [(module) = "framework"];
- CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037 [(module) = "framework"];
- OnDevicePowerMeasurement on_device_power_measurement = 10038;
- DeviceCalculatedPowerUse device_calculated_power_use = 10039 [(module) = "framework"];
- DeviceCalculatedPowerBlameUid device_calculated_power_blame_uid =
- 10040 [(module) = "framework"];
- DeviceCalculatedPowerBlameOther device_calculated_power_blame_other =
- 10041 [(module) = "framework"];
- ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042 [(module) = "framework"];
- BatteryLevel battery_level = 10043 [(module) = "framework"];
- BuildInformation build_information = 10044 [(module) = "framework"];
- BatteryCycleCount battery_cycle_count = 10045 [(module) = "framework"];
- DebugElapsedClock debug_elapsed_clock = 10046 [(module) = "framework"];
- DebugFailingElapsedClock debug_failing_elapsed_clock = 10047 [(module) = "framework"];
- NumFacesEnrolled num_faces_enrolled = 10048 [(module) = "framework"];
- RoleHolder role_holder = 10049 [(module) = "framework"];
- DangerousPermissionState dangerous_permission_state = 10050 [(module) = "framework"];
- TrainInfo train_info = 10051 [(module) = "statsd"];
- TimeZoneDataInfo time_zone_data_info = 10052 [(module) = "framework"];
- ExternalStorageInfo external_storage_info = 10053 [(module) = "framework"];
- GpuStatsGlobalInfo gpu_stats_global_info = 10054;
- GpuStatsAppInfo gpu_stats_app_info = 10055;
- SystemIonHeapSize system_ion_heap_size = 10056 [deprecated = true, (module) = "framework"];
- AppsOnExternalStorageInfo apps_on_external_storage_info = 10057 [(module) = "framework"];
- FaceSettings face_settings = 10058 [(module) = "framework"];
- CoolingDevice cooling_device = 10059 [(module) = "framework"];
- AppOps app_ops = 10060 [(module) = "framework"];
- ProcessSystemIonHeapSize process_system_ion_heap_size = 10061 [(module) = "framework"];
- SurfaceflingerStatsGlobalInfo surfaceflinger_stats_global_info = 10062;
- SurfaceflingerStatsLayerInfo surfaceflinger_stats_layer_info = 10063;
- ProcessMemorySnapshot process_memory_snapshot = 10064 [(module) = "framework"];
- VmsClientStats vms_client_stats = 10065 [(module) = "car"];
- NotificationRemoteViews notification_remote_views = 10066 [(module) = "framework"];
- DangerousPermissionStateSampled dangerous_permission_state_sampled =
- 10067 [(module) = "framework"];
- GraphicsStats graphics_stats = 10068;
- RuntimeAppOpAccess runtime_app_op_access = 10069 [(module) = "framework"];
- IonHeapSize ion_heap_size = 10070 [(module) = "framework"];
- PackageNotificationPreferences package_notification_preferences =
- 10071 [(module) = "framework"];
- PackageNotificationChannelPreferences package_notification_channel_preferences =
- 10072 [(module) = "framework"];
- PackageNotificationChannelGroupPreferences package_notification_channel_group_preferences =
- 10073 [(module) = "framework"];
- GnssStats gnss_stats = 10074 [(module) = "framework"];
- AttributedAppOps attributed_app_ops = 10075 [(module) = "framework"];
- VoiceCallSession voice_call_session = 10076 [(module) = "telephony"];
- VoiceCallRatUsage voice_call_rat_usage = 10077 [(module) = "telephony"];
- SimSlotState sim_slot_state = 10078 [(module) = "telephony"];
- SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"];
- SettingSnapshot setting_snapshot = 10080 [(module) = "framework"];
- BlobInfo blob_info = 10081 [(module) = "framework"];
- DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"];
- BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered =
- 10083 [(module) = "framework"];
- DNDModeProto dnd_mode_rule = 10084 [(module) = "framework"];
- GeneralExternalStorageAccessStats general_external_storage_access_stats =
- 10085 [(module) = "mediaprovider"];
- }
-
- // DO NOT USE field numbers above 100,000 in AOSP.
- // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use.
- // Field numbers 200,000 and above are reserved for future use; do not use them at all.
-
- reserved 10036;
-}
-
-/**
- * This proto represents a node of an attribution chain.
- * Note: All attribution chains are represented as a repeated field of type
- * AttributionNode. It is understood that in such arrays, the order is that
- * of calls, that is [A, B, C] if A calls B that calls C.
- */
-message AttributionNode {
- // The uid for a given element in the attribution chain.
- optional int32 uid = 1;
-
- // The (optional) string tag for an element in the attribution chain. If the
- // element has no tag, it is encoded as an empty string.
- optional string tag = 2;
-}
-
-message KeyValuePair {
- optional int32 key = 1;
- oneof value {
- int32 value_int = 2;
- int64 value_long = 3;
- string value_str = 4;
- float value_float = 5;
- }
-}
-
-message KeyValuePairsAtom {
- optional int32 uid = 1;
- repeated KeyValuePair pairs = 2;
-}
-
-/*
- * *****************************************************************************
- * Below are all of the individual atoms that are logged by Android via statsd.
- *
- * RULES:
- * - The field ids for each atom must start at 1, and count upwards by 1.
- * Skipping field ids is not allowed.
- * - These form an API, so renaming, renumbering or removing fields is
- * not allowed between android releases. (This is not currently enforced,
- * but there will be a tool to enforce this restriction).
- * - The types must be built-in protocol buffer types, namely, no sub-messages
- * are allowed (yet). The bytes type is also not allowed.
- * - The CamelCase name of the message type should match the
- * underscore_separated name as defined in Atom.
- * - If an atom represents work that can be attributed to an app, there can
- * be exactly one AttributionChain field. It must be field number 1.
- * - A field that is a uid should be a string field, tagged with the [xxx]
- * annotation. The generated code on android will be represented by UIDs,
- * and those UIDs will be translated in xxx to those strings.
- *
- * CONVENTIONS:
- * - Events are past tense. e.g. ScreenStateChanged, not ScreenStateChange.
- * - If there is a UID, it goes first. Think in an object-oriented fashion.
- * *****************************************************************************
- */
-
-/**
- * This atom is deprecated starting in Q. Please use ThermalThrottlingSeverityStateChanged.
- * Logs when the Thermal service HAL notifies the throttling start/stop events.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/stats/StatsCompanionService.java
- */
-message ThermalThrottlingStateChanged {
- // The type of temperature being reported (CPU, GPU, SKIN, etc)
- optional android.os.TemperatureTypeEnum sensor_type = 1;
-
- // Throttling state, this field is DEPRECATED
- enum State {
- UNKNOWN = 0;
- START = 1; // START indicated that throttling was triggered.
- STOP = 2; // STOP indicates that throttling was cleared.
- }
- optional State state = 2;
-
- optional float temperature = 3;
-}
-
-/**
- * Logs when the screen state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScreenStateChanged {
- // New screen state, from frameworks/base/core/proto/android/view/enums.proto.
- optional android.view.DisplayStateEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs that the process state of the uid, as determined by ActivityManager
- * (i.e. the highest process state of that uid's processes) has changed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message UidProcessStateChanged {
- optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true];
-
- // The state, from frameworks/base/core/proto/android/app/enums.proto.
- optional android.app.ProcessStateEnum state = 2
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs process state change of a process, as per the activity manager.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
- */
-message ProcessStateChanged {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- // TODO: remove this when validation is done
- optional int64 version = 5;
- // The state, from frameworks/base/core/proto/android/app/enums.proto.
- optional android.app.ProcessStateEnum state = 4;
-}
-
-/**
- * Logs when ActivityManagerService sleep state is changed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java
- */
-message ActivityManagerSleepStateChanged {
- // TODO: import frameworks proto
- enum State {
- UNKNOWN = 0;
- ASLEEP = 1;
- AWAKE = 2;
- }
- optional State state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs when system memory state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message MemoryFactorStateChanged {
- // TODO: import frameworks proto
- enum State {
- MEMORY_UNKNOWN = 0;
- NORMAL = 1; // normal.
- MODERATE = 2; // moderate memory pressure.
- LOW = 3; // low memory.
- CRITICAL = 4; // critical memory.
-
- }
- optional State factor = 1 [(state_field_option).exclusive_state = true];
-}
-
-/**
- * Logs when app is using too much cpu, according to ActivityManagerService.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message ExcessiveCpuUsageReported {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- // package version. TODO: remove this when validation is done
- optional int64 version = 4;
-}
-
-/**
- * Logs when a cached process is killed, along with its pss.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message CachedKillReported {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- // TODO: remove this when validation is done
- optional int64 version = 5;
- optional int64 pss = 4;
-}
-
-/**
- * Logs the change in wifi health.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiDataStall.java
- */
-message WifiHealthStatReported {
- enum Band {
- UNKNOWN = 0;
- // All of 2.4GHz band
- BAND_2G = 1;
- // Frequencies in the range of [5150, 5250) GHz
- BAND_5G_LOW = 2;
- // Frequencies in the range of [5250, 5725) GHz
- BAND_5G_MIDDLE = 3;
- // Frequencies in the range of [5725, 5850) GHz
- BAND_5G_HIGH = 4;
- // Frequencies in the range of [5925, 6425) GHz
- BAND_6G_LOW = 5;
- // Frequencies in the range of [6425, 6875) GHz
- BAND_6G_MIDDLE = 6;
- // Frequencies in the range of [6875, 7125) GHz
- BAND_6G_HIGH = 7;
- }
- // duration this stat is obtained over in milliseconds
- optional int32 duration_millis = 1;
- // whether wifi is classified as sufficient for the user's data traffic, determined
- // by whether the calculated throughput exceeds the average demand within |duration_millis|
- optional bool is_sufficient = 2;
- // whether cellular data is available
- optional bool is_cell_data_available = 3;
- // the Band bucket the connected network is on
- optional Band band = 4;
-}
-
-/**
- * Logged when wifi detects a significant change in connection failure rate.
- *
- * Logged from: frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiHealthMonitor.java
- *
- */
-message WifiFailureStatReported {
- enum AbnormalityType {
- UNKNOWN = 0;
- SIGNIFICANT_INCREASE = 1;
- SIGNIFICANT_DECREASE = 2;
- SIMPLY_HIGH = 3;
- }
- enum FailureType {
- FAILURE_UNKNOWN = 0;
- FAILURE_CONNECTION = 1;
- FAILURE_ASSOCIATION_REJECTION = 2;
- FAILURE_ASSOCIATION_TIMEOUT = 3;
- FAILURE_AUTHENTICATION = 4;
- FAILURE_NON_LOCAL_DISCONNECTION = 5;
- FAILURE_SHORT_CONNECTION_DUE_TO_NON_LOCAL_DISCONNECTION = 6;
- }
- // Reason for uploading this stat
- optional AbnormalityType abnormality_type = 1;
- // The particular type of failure
- optional FailureType failure_type = 2;
- // How many times we have encountered this combination of AbnormalityType and FailureType
- optional int32 failure_count = 3;
-}
-
-/**
- * Logs whether a wifi connection is successful and reasons for failure if it isn't.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java
- */
-message WifiConnectionResultReported {
- enum FailureCode {
- FAILURE_UNKNOWN = 0;
- FAILURE_ASSOCIATION_TIMEOUT = 1;
- FAILURE_ASSOCIATION_REJECTION = 2;
- FAILURE_AUTHENTICATION_GENERAL = 3;
- FAILURE_AUTHENTICATION_EAP = 4;
- FAILURE_DHCP = 5;
- FAILURE_NETWORK_DISCONNECTION = 6;
- FAILURE_ROAM_TIMEOUT = 7;
- }
- // true represents a successful connection
- optional bool connection_result = 1;
- // reason for the connection failure
- optional FailureCode failure_code = 2;
- // scan rssi before the connection attempt
- optional int32 rssi = 3;
-}
-
-/**
- * Logs when memory stats of a process is reported.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
- */
-message ProcessMemoryStatReported {
- optional int32 uid = 1;
- optional string process_name = 2;
- optional string package_name = 3;
- //TODO: remove this when validation is done
- optional int64 version = 9;
- optional int64 pss = 4;
- optional int64 uss = 5;
- optional int64 rss = 6;
- enum Type {
- ADD_PSS_INTERNAL_SINGLE = 0;
- ADD_PSS_INTERNAL_ALL_MEM = 1;
- ADD_PSS_INTERNAL_ALL_POLL = 2;
- ADD_PSS_EXTERNAL = 3;
- ADD_PSS_EXTERNAL_SLOW = 4;
- }
- optional Type type = 7;
- optional int64 duration_millis = 8;
-}
-
-/**
- * Logs that a process started, finished, crashed, or ANRed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ProcessLifeCycleStateChanged {
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name (usually same as the app name).
- optional string process_name = 2;
-
- // What lifecycle state the process changed to.
- // This enum is specific to atoms.proto.
- enum State {
- FINISHED = 0;
- STARTED = 1;
- CRASHED = 2;
- }
- optional State state = 3;
-}
-
-/**
- * Logs when the ble scan state changes.
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java
- */
-message BleScanStateChanged {
- repeated AttributionNode attribution_node = 1
- [(state_field_option).primary_field_first_uid = true];
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all ble stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2 [
- (state_field_option).exclusive_state = true,
- (state_field_option).default_state_value = 0 /* State.OFF */,
- (state_field_option).trigger_state_reset_value = 2 /* State.RESET */,
- (state_field_option).nested = true
- ];
-
- // Does the scan have a filter.
- optional bool is_filtered = 3 [(state_field_option).primary_field = true];
- // Whether the scan is a CALLBACK_TYPE_FIRST_MATCH scan. Called 'background' scan internally.
- optional bool is_first_match = 4 [(state_field_option).primary_field = true];
- // Whether the scan set to piggy-back off the results of other scans (SCAN_MODE_OPPORTUNISTIC).
- optional bool is_opportunistic = 5 [(state_field_option).primary_field = true];
-}
-
-/**
- * Logs reporting of a ble scan finding results.
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java
- */
-// TODO: Consider also tracking per-scanner-id.
-message BleScanResultReceived {
- repeated AttributionNode attribution_node = 1;
-
- // Number of ble scan results returned.
- optional int32 num_results = 2;
-}
-
-/**
- * Logs when a sensor state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message SensorStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // The id (int) of the sensor.
- optional int32 sensor_id = 2;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 3;
-}
-
-/**
- * Logs when GPS state changes.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message GpsScanStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when GPS signal quality.
- *
- * Logged from:
- * /frameworks/base/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
- */
-message GpsSignalQualityChanged {
- optional android.server.location.GpsSignalQualityEnum level = 1;
-}
-
-
-/**
- * Logs when a sync manager sync state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message SyncStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the sync (as named in the app). Can be chosen at run-time.
- optional string sync_name = 2;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 3;
-}
-
-/*
- * Deferred job stats.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java
-*/
-message DeferredJobStatsReported {
- repeated AttributionNode attribution_node = 1;
-
- // Number of jobs deferred.
- optional int32 num_jobs_deferred = 2;
-
- // Time since the last job runs.
- optional int64 time_since_last_job_millis = 3;
-}
-
-/**
- * Logs when a job scheduler job state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScheduledJobStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the job (as named in the app)
- optional string job_name = 2;
-
- enum State {
- FINISHED = 0;
- STARTED = 1;
- SCHEDULED = 2;
- }
- optional State state = 3;
-
- // The reason a job has stopped.
- // This is only applicable when the state is FINISHED.
- // The default value is STOP_REASON_UNKNOWN.
- optional android.app.job.StopReasonEnum stop_reason = 4;
-
- // The standby bucket of the app that scheduled the job. These match the framework constants
- // defined in JobSchedulerService.java with the addition of UNKNOWN using -1, as ACTIVE is
- // already assigned 0.
- enum Bucket {
- UNKNOWN = -1;
- ACTIVE = 0;
- WORKING_SET = 1;
- FREQUENT = 2;
- RARE = 3;
- NEVER = 4;
- RESTRICTED = 5;
- }
- optional Bucket standby_bucket = 5 [default = UNKNOWN];
-
- // The job id (as assigned by the app).
- optional int32 job_id = 6;
-
- // One flag for each of the API constraints defined by Jobscheduler. Does not include implcit
- // constraints as they are always assumed to be set.
- optional bool has_charging_constraint = 7;
- optional bool has_battery_not_low_constraint = 8;
- optional bool has_storage_not_low_constraint = 9;
- optional bool has_timing_delay_constraint = 10;
- optional bool has_deadline_constraint = 11;
- optional bool has_idle_constraint = 12;
- optional bool has_connectivity_constraint = 13;
- optional bool has_content_trigger_constraint = 14;
-}
-
-/**
- * Logs when the audio state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message AudioStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when the video codec state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message MediaCodecStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all mediaCodec stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when the flashlight state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message FlashlightStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all flashlight stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when the camera state changes.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message CameraStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- // RESET indicates all camera stopped. Used when it (re)starts (e.g. after it crashes).
- RESET = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs that the state of a wakelock (per app and per wakelock name) has changed.
- *
- * Logged from:
- * TODO
- */
-message WakelockStateChanged {
- repeated AttributionNode attribution_node = 1
- [(state_field_option).primary_field_first_uid = true];
-
- // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock.
- // From frameworks/base/core/proto/android/os/enums.proto.
- optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).primary_field = true];
-
- // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
- optional string tag = 3 [(state_field_option).primary_field = true];
-
- enum State {
- RELEASE = 0;
- ACQUIRE = 1;
- CHANGE_RELEASE = 2;
- CHANGE_ACQUIRE = 3;
- }
- optional State state = 4 [
- (state_field_option).exclusive_state = true,
- (state_field_option).default_state_value = 0,
- (state_field_option).nested = true
- ];
-}
-
-/**
- * Logs when a partial wakelock is considered 'long' (over 1 min).
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message LongPartialWakelockStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
- optional string tag = 2;
-
- // TODO: I have no idea what this is.
- optional string history_tag = 3;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 4;
-}
-
-/**
- * Logs when the device is interactive, according to the PowerManager Notifier.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/power/Notifier.java
- */
-message InteractiveStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
-/**
- * Logs Battery Saver state change.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message BatterySaverModeStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs Doze mode state change.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceIdleModeStateChanged {
- optional android.server.DeviceIdleModeEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-
-/**
- * Logs state change of Doze mode including maintenance windows.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceIdlingModeStateChanged {
- optional android.server.DeviceIdleModeEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs screen brightness level.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScreenBrightnessChanged {
- // Screen brightness level. Should be in [-1, 255] according to PowerManager.java.
- optional int32 level = 1;
-}
-
-/**
- * Logs battery level (percent full, from 0 to 100).
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message BatteryLevelChanged {
- // Battery level. Should be in [0, 100].
- optional int32 battery_level = 1;
-}
-
-/**
- * Logs change in charging status of the device.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message ChargingStateChanged {
- // State of the battery, from frameworks/base/core/proto/android/os/enums.proto.
- optional android.os.BatteryStatusEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs whether the device is plugged in, and what power source it is using.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message PluggedStateChanged {
- // Whether the device is plugged in, from frameworks/base/core/proto/android/os/enums.proto.
- optional android.os.BatteryPluggedStateEnum state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs when an app's wakeup alarm fires.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message WakeupAlarmOccurred {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the wakeup alarm.
- optional string tag = 2;
-
- // Name of source package (for historical reasons, since BatteryStats tracked it).
- optional string package_name = 3;
-
- // The App Standby bucket of the app that scheduled the alarm at the time the alarm fired.
- optional AppStandbyBucketChanged.Bucket app_standby_bucket = 4;
-}
-
-/**
- * Logs when an an app causes the mobile radio to change state.
- * Changing from LOW to MEDIUM or HIGH can be considered the app waking the mobile radio.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
- */
-message MobileRadioPowerStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.DataConnectionPowerStateEnum state = 2;
-}
-
-/**
- * Logs when an an app causes the wifi radio to change state.
- * Changing from LOW to MEDIUM or HIGH can be considered the app waking the wifi radio.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
- */
-message WifiRadioPowerStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.DataConnectionPowerStateEnum state = 2;
-}
-
-/**
- * Logs kernel wakeup reasons and aborts.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message KernelWakeupReported {
- // Name of the kernel wakeup reason (or abort).
- optional string wakeup_reason_name = 1;
-
- // Duration (in microseconds) for the wake-up interrupt to be serviced.
- optional int64 duration_micros = 2;
-}
-
-/**
- * Logs when Wifi is toggled on/off.
- * Note that Wifi may still perform certain functions (e.g. location scanning) even when disabled.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message WifiEnabledStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
-/**
- * This atom is deprecated starting in R.
- *
- * Logs when an app causes Wifi to run. In this context, 'to run' means to use Wifi Client Mode.
- * TODO: Include support for Hotspot, perhaps by using an extra field to denote 'mode'.
- * Note that Wifi Scanning is monitored separately in WifiScanStateChanged.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message WifiRunningStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-}
-
-/**
- * Logs wifi locks held by an app.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message WifiLockStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-
- // WifiLock type, from frameworks/base/core/proto/android/wifi/enums.proto.
- optional android.net.wifi.WifiModeEnum mode = 3;
-}
-
-/**
- * Logs wifi signal strength changes.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java
- */
-message WifiSignalStrengthChanged {
- // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.SignalStrengthEnum signal_strength = 1;
-}
-
-/**
- * Logs wifi scans performed by an app.
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
- */
-message WifiScanStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-}
-
-/**
- * Logs wifi multicast locks held by an app
- *
- * Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMulticastLockManager.java
- */
-message WifiMulticastLockStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-
- optional string tag = 3;
-}
-
-/**
- * Logs shutdown reason and duration on next boot.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/server/BootReceiver.java
- */
-message ShutdownSequenceReported {
- // True if shutdown is for a reboot. Default: false if we do not know.
- optional bool reboot = 1;
-
- // Reason for shutdown. Eg: userrequested. Default: "<EMPTY>".
- optional string reason = 2;
-
- // Beginning of shutdown time in ms using wall clock time since unix epoch.
- // Default: 0 if no start time received.
- optional int64 start_time_millis = 3;
-
- // Duration of shutdown in ms. Default: 0 if no duration received.
- optional int64 duration_millis = 4;
-}
-
-
-/**
- * Logs boot reason and duration.
- *
- * Logged from:
- * system/core/bootstat/bootstat.cpp
- */
-message BootSequenceReported {
- // Reason for bootloader boot. Eg. reboot. See bootstat.cpp for larger list
- // Default: "<EMPTY>" if not available.
- optional string bootloader_reason = 1;
-
- // Reason for system boot. Eg. bootloader, reboot,userrequested
- // Default: "<EMPTY>" if not available.
- optional string system_reason = 2;
-
- // End of boot time in ms from unix epoch using system wall clock.
- optional int64 end_time_millis = 3;
-
- // Total boot duration in ms.
- optional int64 total_duration_millis = 4;
-
- // Bootloader duration in ms.
- optional int64 bootloader_duration_millis = 5;
-
- // Time since last boot in ms. Default: 0 if not available.
- optional int64 time_since_last_boot = 6;
-}
-
-
-/**
- * Logs call state and disconnect cause (if applicable).
- *
- * Logged from:
- * packages/services/Telecomm/src/com/android/server/telecom/Call.java
- */
-message CallStateChanged {
- // The state of the call. Eg. DIALING, ACTIVE, ON_HOLD, DISCONNECTED.
- // From frameworks/base/core/proto/android/telecomm/enums.proto.
- optional android.telecom.CallStateEnum call_state = 1;
-
- // The reason the call disconnected. Eg. ERROR, MISSED, REJECTED, BUSY.
- // This value is only applicable when the call_state is DISCONNECTED, and
- // should always be UNKNOWN if the call_state is not DISCONNECTED.
- // From frameworks/base/core/proto/android/telecomm/enums.proto.
- optional android.telecom.DisconnectCauseEnum disconnect_cause = 2;
-
- // True if the call is self-managed, which are apps that use the
- // telecom infrastructure to make their own calls.
- optional bool self_managed = 3;
-
- // True if call is external. External calls are calls on connected Wear
- // devices but show up in Telecom so the user can pull them onto the device.
- optional bool external_call = 4;
-}
-
-/**
- * Logs keyguard state. The keyguard is the lock screen.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
- */
-message KeyguardStateChanged {
- enum State {
- UNKNOWN = 0;
- // The keyguard is hidden when the phone is unlocked.
- HIDDEN = 1;
- // The keyguard is shown when the phone is locked (screen turns off).
- SHOWN= 2;
- // The keyguard is occluded when something is overlaying the keyguard.
- // Eg. Opening the camera while on the lock screen.
- OCCLUDED = 3;
- }
- optional State state = 1;
-}
-
-/**
- * Logs keyguard bouncer state. The bouncer is a part of the keyguard, and
- * prompts the user to enter a password (pattern, pin, etc).
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
- */
-
-message KeyguardBouncerStateChanged {
- enum State {
- UNKNOWN = 0;
- // Bouncer is hidden, either as a result of successfully entering the
- // password, screen timing out, or user going back to lock screen.
- HIDDEN = 1;
- // This is when the user is being prompted to enter the password.
- SHOWN = 2;
- }
- optional State state = 1;
-}
-
-/**
- * Logs the result of entering a password into the keyguard bouncer.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
- */
-message KeyguardBouncerPasswordEntered {
- enum BouncerResult {
- UNKNOWN = 0;
- // The password entered was incorrect.
- FAILURE = 1;
- // The password entered was correct.
- SUCCESS = 2;
- }
- optional BouncerResult result = 1;
-}
-
-/*
- * Logs changes to the configuration of the device. The configuration is defined
- * in frameworks/base/core/java/android/content/res/Configuration.java
- * More documentation is at https://d.android.com/reference/android/content/res/Configuration.html
- * Please go there to interpret the possible values each field can be.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message ResourceConfigurationChanged {
- // Bit mask of color capabilities of the screen.
- // Contains information about the color gamut and hdr mode of the screen.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#colorMode
- optional int32 color_mode = 1;
-
- // The target screen density being rendered to.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#densityDpi
- optional int32 density_dpi = 2;
-
- // Current user preference for the scaling factor for fonts,
- // relative to the base density scaling.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#fontScale
- optional float font_scale = 3;
-
- // Flag indicating whether the hard keyboard is hidden.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#hardKeyboardHidden
- optional int32 hard_keyboard_hidden = 4;
-
- // The type of keyboard attached to the device.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboard
- optional int32 keyboard = 5;
-
- // Flag indicating whether any keyboard is available. Takes soft keyboards into account.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboardHidden
- optional int32 keyboard_hidden = 6;
-
- // IMSI MCC (Mobile Country Code), corresponding to mcc resource qualifier.
- // 0 if undefined.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#mcc
- optional int32 mcc = 7;
-
- // IMSI MNC (Mobile Network Code), corresponding to mnc resource qualifier.
- // 0 if undefined. Note: the actual MNC may be 0, to check for this use the
- // MNC_ZERO symbol defined in Configuration.java.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#mnc
- optional int32 mnc = 8;
-
- // The kind of navigation available on the device.
- // See: https://developer.android.com/reference/android/content/res/Configuration.html#navigation
- optional int32 navigation = 9;
-
- // Flag indicating whether the navigation is available.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#navigationHidden
- optional int32 navigation_hidden = 10;
-
- // Overall orientation of the screen.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#orientation
- optional int32 orientation = 11;
-
- // The current height of the available screen space, in dp units.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#screenHeightDp
- optional int32 screen_height_dp = 12;
-
- // Bit mask of overall layout of the screen.
- // Contains information about screen size, whether the screen is wider/taller
- // than normal, whether the screen layout is right-tl-left or left-to-right,
- // and whether the screen has a rounded shape.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#screenLayout
- optional int32 screen_layout = 13;
-
- // Current width of the available screen space, in dp units.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#screenWidthDp
- optional int32 screen_width_dp = 14;
-
- // The smallest screen size an application will see in normal operation.
- // This is the smallest value of both screenWidthDp and screenHeightDp
- // in portrait and landscape.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#smallestScreenWidthDp
- optional int32 smallest_screen_width_dp = 15;
-
- // The type of touch screen attached to the device.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#touchscreen
- optional int32 touchscreen = 16;
-
- // Bit mask of the ui mode.
- // Contains information about the overall ui mode of the device.
- // Eg: NORMAL, DESK, CAR, TELEVISION, WATCH, VR_HEADSET
- // Also contains information about whether the device is in night mode.
- // See: https://d.android.com/reference/android/content/res/Configuration.html#uiMode
- optional int32 ui_mode = 17;
-}
-
-
-/**
- * Logs changes in the connection state of the mobile radio.
- *
- * Logged from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
- */
-message MobileConnectionStateChanged {
- // States are from the state machine DataConnection.java.
- enum State {
- UNKNOWN = 0;
- // The connection is inactive, or disconnected.
- INACTIVE = 1;
- // The connection is being activated, or connecting.
- ACTIVATING = 2;
- // The connection is active, or connected.
- ACTIVE = 3;
- // The connection is disconnecting.
- DISCONNECTING = 4;
- // The connection is disconnecting after creating a connection.
- DISCONNECTION_ERROR_CREATING_CONNECTION = 5;
- }
- optional State state = 1;
- // For multi-sim phones, this distinguishes between the sim cards.
- optional int32 sim_slot_index = 2;
- // Used to identify the connection. Starts at 0 and increments by 1 for
- // every new network created. Resets whenever the device reboots.
- optional int32 data_connection_id = 3;
- // A bitmask for the capabilities of this connection.
- // Eg. DEFAULT (internet), MMS, SUPL, DUN, IMS.
- // Default value (if we have no information): 0
- optional int64 capabilities = 4;
- // If this connection has internet.
- // This just checks if the DEFAULT bit of capabilities is set.
- optional bool has_internet = 5;
-}
-
-/**
- * Logs changes in mobile radio technology. eg: LTE, EDGE, CDMA.
- *
- * Logged from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java
- */
-message MobileRadioTechnologyChanged {
- optional android.telephony.NetworkTypeEnum state = 1;
- // For multi-sim phones, this distinguishes between the sim cards.
- optional int32 sim_slot_index = 2;
-}
-
-/**
- * Logs the VID and PID of any connected USB devices.
- *
- * Notes if any Audio, HID (input buttons/mouse/keyboard), or Storage interfaces are present.
- *
- * Logged by Vendor.
- */
-message UsbDeviceAttached {
- optional int32 vid = 1;
- optional int32 pid = 2;
- optional bool has_audio = 3;
- optional bool has_hid = 4;
- optional bool has_storage = 5;
- enum State {
- STATE_DISCONNECTED = 0;
- STATE_CONNECTED = 1;
- }
- optional State state = 6;
- optional int64 last_connect_duration_millis = 7;
-}
-
-
-/**
- * Logs when Bluetooth is enabled and disabled.
- *
- * Logged from:
- * services/core/java/com/android/server/BluetoothManagerService.java
- */
-message BluetoothEnabledStateChanged {
- repeated AttributionNode attribution_node = 1;
- // Whether or not bluetooth is enabled on the device.
- enum State {
- UNKNOWN = 0;
- ENABLED = 1;
- DISABLED = 2;
- }
- optional State state = 2;
- // The reason for being enabled/disabled.
- // Eg. Airplane mode, crash, application request.
- optional android.bluetooth.EnableDisableReasonEnum reason = 3;
- // If the reason is an application request, this will be the package name.
- optional string pkg_name = 4;
-}
-
-/**
- * Logs when profiles on a Bluetooth device connects and disconnects.
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java
- *
- * Next Tag: 6
- */
-message BluetoothConnectionStateChanged {
- // The state of the connection.
- // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED.
- optional android.bluetooth.ConnectionStateEnum state = 1;
- // An identifier that can be used to match connect and disconnect events.
- // Currently is last two bytes of a hash of a device level ID and
- // the mac address of the bluetooth device that is connected.
- // Deprecated: use obfuscated_id instead, this one is always 0 for Q+
- optional int32 obfuscated_id = 2 [deprecated = true];
- // The profile that is connected. Eg. GATT, A2DP, HEADSET.
- // From android.bluetooth.BluetoothAdapter.java
- // Default: 0 when not used
- optional int32 bt_profile = 3;
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes new_obfuscated_id = 4 [(android.os.statsd.log_mode) = MODE_BYTES];
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when a Bluetooth device connects and disconnects over ACL
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
- *
- * Next Tag: 4
- */
-message BluetoothAclConnectionStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // The state of the connection.
- // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED.
- optional android.bluetooth.ConnectionStateEnum state = 2;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 3;
-}
-
-/**
- * Logs when a Bluetooth device connects and disconnects over SCO
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetClientStateMachine.java
- *
- * Next Tag: 5
- */
-message BluetoothScoConnectionStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // The state of the connection.
- // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED.
- optional android.bluetooth.ConnectionStateEnum state = 2;
- // Codec used for this SCO connection
- // Default: UNKNOWN
- optional android.bluetooth.hfp.ScoCodec codec = 3;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 4;
-}
-
-/**
- * Logged when active device of a profile changes
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetService.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/hearingaid/HearingAidService.java
- */
-message BluetoothActiveDeviceChanged {
- // The profile whose active device has changed. Eg. A2DP, HEADSET, HEARING_AID
- // From android.bluetooth.BluetoothProfile
- optional int32 bt_profile = 1;
- // An identifier that can be used to match events for this new active device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if there is no active device for this profile
- optional bytes obfuscated_id = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 3;
-}
-
-// Logs when there is an event affecting Bluetooth device's link layer connection.
-// - This event is triggered when there is a related HCI command or event
-// - Users of this metrics can deduce Bluetooth device's connection state from these events
-// - HCI commands are logged before the command is sent, after receiving command status, and after
-// receiving command complete
-// - HCI events are logged when they arrive
-//
-// Low level log from system/bt
-//
-// Bluetooth classic commands:
-// - CMD_CREATE_CONNECTION
-// - CMD_DISCONNECT
-// - CMD_CREATE_CONNECTION_CANCEL
-// - CMD_ACCEPT_CONNECTION_REQUEST
-// - CMD_REJECT_CONNECTION_REQUEST
-// - CMD_SETUP_ESCO_CONNECTION
-// - CMD_ACCEPT_ESCO_CONNECTION
-// - CMD_REJECT_ESCO_CONNECTION
-// - CMD_ENH_SETUP_ESCO_CONNECTION
-// - CMD_ENH_ACCEPT_ESCO_CONNECTION
-//
-// Bluetooth low energy commands:
-// - CMD_BLE_CREATE_LL_CONN [Only logged on error or when initiator filter policy is 0x00]
-// - CMD_BLE_CREATE_CONN_CANCEL [Only logged when there is an error]
-// - CMD_BLE_EXTENDED_CREATE_CONNECTION [Only logged on error or when initiator filter policy is 0x00]
-// - CMD_BLE_CLEAR_WHITE_LIST
-// - CMD_BLE_ADD_WHITE_LIST
-// - CMD_BLE_REMOVE_WHITE_LIST
-//
-// Bluetooth classic events:
-// - EVT_CONNECTION_COMP
-// - EVT_CONNECTION_REQUEST
-// - EVT_DISCONNECTION_COMP
-// - EVT_ESCO_CONNECTION_COMP
-// - EVT_ESCO_CONNECTION_CHANGED
-//
-// Bluetooth low energy meta events:
-// - BLE_EVT_CONN_COMPLETE_EVT
-// - BLE_EVT_ENHANCED_CONN_COMPLETE_EVT
-//
-// Next tag: 10
-message BluetoothLinkLayerConnectionEvent {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // Direction of the link
- // Default: DIRECTION_UNKNOWN
- optional android.bluetooth.DirectionEnum direction = 3;
- // Type of this link
- // Default: LINK_TYPE_UNKNOWN
- optional android.bluetooth.LinkTypeEnum type = 4;
-
- // Reason metadata for this link layer connection event, rules for interpretation:
- // 1. If hci_cmd is set and valid, hci_event can be either EVT_COMMAND_STATUS or
- // EVT_COMMAND_COMPLETE, ignore hci_ble_event in this case
- // 2. If hci_event is set to EVT_BLE_META, look at hci_ble_event; otherwise, if hci_event is
- // set and valid, ignore hci_ble_event
-
- // HCI command associated with this event
- // Default: CMD_UNKNOWN
- optional android.bluetooth.hci.CommandEnum hci_cmd = 5;
- // HCI event associated with this event
- // Default: EVT_UNKNOWN
- optional android.bluetooth.hci.EventEnum hci_event = 6;
- // HCI BLE meta event associated with this event
- // Default: BLE_EVT_UNKNOWN
- optional android.bluetooth.hci.BleMetaEventEnum hci_ble_event = 7;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum cmd_status = 8;
- // HCI reason code associated with this event
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum reason_code = 9;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 10;
-}
-
-/**
- * Logs when a module is rolled back by Watchdog.
- *
- * Logged from: Rollback Manager
- */
-message WatchdogRollbackOccurred {
- enum RollbackType {
- UNKNOWN = 0;
- ROLLBACK_INITIATE = 1;
- ROLLBACK_SUCCESS = 2;
- ROLLBACK_FAILURE = 3;
- ROLLBACK_BOOT_TRIGGERED = 4;
- }
- optional RollbackType rollback_type = 1;
-
- optional string package_name = 2;
-
- optional int32 package_version_code = 3;
-
- enum RollbackReasonType {
- REASON_UNKNOWN = 0;
- REASON_NATIVE_CRASH = 1;
- REASON_EXPLICIT_HEALTH_CHECK = 2;
- REASON_APP_CRASH = 3;
- REASON_APP_NOT_RESPONDING = 4;
- REASON_NATIVE_CRASH_DURING_BOOT = 5;
- }
- optional RollbackReasonType rollback_reason = 4;
-
- // Set by RollbackPackageHealthObserver to be the package that is failing when a rollback
- // is initiated. Empty if the package is unknown.
- optional string failing_package_name = 5;
-
- optional TrainExperimentIds experiment_ids = 6 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Logs when there is a change in Bluetooth A2DP playback state
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- */
-message BluetoothA2dpPlaybackStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Current playback state
- // Default: PLAYBACK_STATE_UNKNOWN
- optional android.bluetooth.a2dp.PlaybackStateEnum playback_state = 2;
- // Current audio coding mode
- // Default: AUDIO_CODING_MODE_UNKNOWN
- optional android.bluetooth.a2dp.AudioCodingModeEnum audio_coding_mode = 3;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 4;
-}
-
-/**
- * Logs when there is a change in A2DP codec config for a particular remote device
- *
- * Logged from:
- * frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- */
-message BluetoothA2dpCodecConfigChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Type of codec as defined by various SOURCE_CODEC_TYPE_* constants in BluetoothCodecConfig
- // Default SOURCE_CODEC_TYPE_INVALID
- optional int32 codec_type = 2;
- // Codec priroity, the higher the more preferred, -1 for disabled
- // Default: CODEC_PRIORITY_DEFAULT
- optional int32 codec_priority = 3;
- // Sample rate in Hz as defined by various SAMPLE_RATE_* constants in BluetoothCodecConfig
- // Default: SAMPLE_RATE_NONE
- optional int32 sample_rate = 4;
- // Bits per sample as defined by various BITS_PER_SAMPLE_* constants in BluetoothCodecConfig
- // Default: BITS_PER_SAMPLE_NONE
- optional int32 bits_per_sample = 5;
- // Channel mode as defined by various CHANNEL_MODE_* constants in BluetoothCodecConfig
- // Default: CHANNEL_MODE_NONE
- optional int32 channel_mode = 6;
- // Codec specific values
- // Default 0
- optional int64 codec_specific_1 = 7;
- optional int64 codec_specific_2 = 8;
- optional int64 codec_specific_3 = 9;
- optional int64 codec_specific_4 = 10;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 11;
-}
-
-/**
- * Logs when there is a change in selectable A2DP codec capability for a paricular remote device
- * Each codec's capability is logged separately due to statsd restriction
- *
- * Logged from:
- * frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java
- */
-message BluetoothA2dpCodecCapabilityChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Type of codec as defined by various SOURCE_CODEC_TYPE_* constants in BluetoothCodecConfig
- // Default SOURCE_CODEC_TYPE_INVALID
- optional int32 codec_type = 2;
- // Codec priroity, the higher the more preferred, -1 for disabled
- // Default: CODEC_PRIORITY_DEFAULT
- optional int32 codec_priority = 3;
- // A bit field of supported sample rates as defined by various SAMPLE_RATE_* constants
- // in BluetoothCodecConfig
- // Default: empty and SAMPLE_RATE_NONE for individual item
- optional int32 sample_rate = 4;
- // A bit field of supported bits per sample as defined by various BITS_PER_SAMPLE_* constants
- // in BluetoothCodecConfig
- // Default: empty and BITS_PER_SAMPLE_NONE for individual item
- optional int32 bits_per_sample = 5;
- // A bit field of supported channel mode as defined by various CHANNEL_MODE_* constants in
- // BluetoothCodecConfig
- // Default: empty and CHANNEL_MODE_NONE for individual item
- optional int32 channel_mode = 6;
- // Codec specific values
- // Default 0
- optional int64 codec_specific_1 = 7;
- optional int64 codec_specific_2 = 8;
- optional int64 codec_specific_3 = 9;
- optional int64 codec_specific_4 = 10;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 11;
-}
-
-/**
- * Logs when A2DP failed to read from PCM source.
- * This typically happens when audio HAL cannot supply A2DP with data fast enough for encoding.
- *
- * Logged from:
- * system/bt
- */
-message BluetoothA2dpAudioUnderrunReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Encoding interval in nanoseconds
- // Default: 0
- optional int64 encoding_interval_nanos = 2;
- // Number of bytes of PCM data that could not be read from the source
- // Default: 0
- optional int32 num_missing_pcm_bytes = 3;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 4;
-}
-
-/**
- * Logs when A2DP failed send encoded data to the remote device fast enough such that the transmit
- * buffer queue is full and we have to drop data
- *
- * Logged from:
- * system/bt
- */
-message BluetoothA2dpAudioOverrunReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Encoding interval in nanoseconds
- // Default: 0
- optional int64 encoding_interval_nanos = 2;
- // Number of buffers dropped in this event
- // Each buffer is encoded in one encoding interval and consists of multiple encoded frames
- // Default: 0
- optional int32 num_dropped_buffers = 3;
- // Number of encoded buffers dropped in this event
- // Default 0
- optional int32 num_dropped_encoded_frames = 4;
- // Number of encoded bytes dropped in this event
- // Default: 0
- optional int32 num_dropped_encoded_bytes = 5;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 6;
-}
-
-/**
- * Logs when we receive reports regarding a device's RSSI value
- *
- * Logged from:
- * system/bt
- */
-message BluetoothDeviceRssiReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum hci_status = 3;
- // BR/EDR
- // Range: -128 ≤ N ≤ 127 (signed integer)
- // Units: dB
- // LE:
- // Range: -127 to 20, 127 (signed integer)
- // Units: dBm
- // Invalid when an out of range value is reported
- optional int32 rssi = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when we receive reports regarding how many consecutive failed contacts for a connection
- *
- * Logged from:
- * system/bt
- */
-message BluetoothDeviceFailedContactCounterReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum cmd_status = 3;
- // Number of consecutive failed contacts for a connection corresponding to the Handle
- // Range: uint16_t, 0-0xFFFF
- // Default: 0xFFFFF
- optional int32 failed_contact_counter = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when we receive reports regarding the tranmit power level used for a specific connection
- *
- * Logged from:
- * system/bt
- */
-message BluetoothDeviceTxPowerLevelReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command status code if this is triggered by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum hci_status = 3;
- // Range: -30 ≤ N ≤ 20
- // Units: dBm
- // Invalid when an out of range value is reported
- optional int32 transmit_power_level = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when Bluetooth controller failed to reply with command status within a timeout period after
- * receiving an HCI command from the host
- *
- * Logged from: system/bt
- */
-message BluetoothHciTimeoutReported {
- // HCI command associated with this event
- // Default: CMD_UNKNOWN
- optional android.bluetooth.hci.CommandEnum hci_command = 1;
-}
-
-/**
- * Logs when we receive Bluetooth Link Quality Report event from the controller
- * See Android Bluetooth HCI specification for more details
- *
- * Note: all count and bytes field are counted since last event
- *
- * Logged from: system/bt
- */
-message BluetoothQualityReportReported {
- // Quality report ID
- // Original type: uint8_t
- // Default: BQR_ID_UNKNOWN
- optional android.bluetooth.hci.BqrIdEnum quality_report_id = 1;
- // Packet type of the connection
- // Original type: uint8_t
- // Default: BQR_PACKET_TYPE_UNKNOWN
- optional android.bluetooth.hci.BqrPacketTypeEnum packet_types = 2;
- // Connection handle of the connection
- // Original type: uint16_t
- optional int32 connection_handle = 3;
- // Performing Role for the connection
- // Original type: uint8_t
- optional int32 connection_role = 4;
- // Current Transmit Power Level for the connection. This value is the same as the controller's
- // response to the HCI_Read_Transmit_Power_Level HCI command
- // Original type: uint8_t
- optional int32 tx_power_level = 5;
- // Received Signal Strength Indication (RSSI) value for the connection. This value is an
- // absolute receiver signal strength value
- // Original type: int8_t
- optional int32 rssi = 6;
- // Signal-to-Noise Ratio (SNR) value for the connection. It is the average SNR of all the
- // channels used by the link currently
- // Original type: uint8_t
- optional int32 snr = 7;
- // Indicates the number of unused channels in AFH_channel_map
- // Original type: uint8_t
- optional int32 unused_afh_channel_count = 8;
- // Indicates the number of the channels which are interfered and quality is bad but are still
- // selected for AFH
- // Original type: uint8_t
- optional int32 afh_select_unideal_channel_count = 9;
- // Current Link Supervision Timeout Setting
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint16_t
- optional int32 lsto = 10;
- // Piconet Clock for the specified Connection_Handle. This value is the same as the controller's
- // response to HCI_Read_Clock HCI command with the parameter "Which_Clock" of
- // 0x01 (Piconet Clock)
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint32_t
- optional int64 connection_piconet_clock = 11;
- // The count of retransmission
- // Original type: uint32_t
- optional int64 retransmission_count = 12;
- // The count of no RX
- // Original type: uint32_t
- optional int64 no_rx_count = 13;
- // The count of NAK (Negative Acknowledge)
- // Original type: uint32_t
- optional int64 nak_count = 14;
- // Controller timestamp of last TX ACK
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint32_t
- optional int64 last_tx_ack_timestamp = 15;
- // The count of Flow-off (STOP)
- // Original type: uint32_t
- optional int64 flow_off_count = 16;
- // Controller timestamp of last Flow-on (GO)
- // Unit: N * 0.3125 ms (1 Bluetooth Clock)
- // Original type: uint32_t
- optional int64 last_flow_on_timestamp = 17;
- // Buffer overflow count (how many bytes of TX data are dropped) since the last event
- // Original type: uint32_t
- optional int64 buffer_overflow_bytes = 18;
- // Buffer underflow count (in byte) since last event
- // Original type: uint32_t
- optional int64 buffer_underflow_bytes = 19;
-}
-
-/**
- * Logs when a Bluetooth device's manufacturer information is learnt by the Bluetooth stack
- *
- * Notes:
- * - Each event can be partially filled as we might learn different pieces of device
- * information at different time
- * - Multiple device info events can be combined to give more complete picture
- * - When multiple device info events tries to describe the same information, the
- * later one wins
- *
- * Logged from:
- * packages/apps/Bluetooth
- */
-message BluetoothDeviceInfoReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Where is this device info obtained from
- optional android.bluetooth.DeviceInfoSrcEnum source_type = 2;
- // Name of the data source
- // For EXTERNAL: package name of the data source
- // For INTERNAL: null for general case, component name otherwise
- optional string source_name = 3;
- // Name of the manufacturer of this device
- optional string manufacturer = 4;
- // Model of this device
- optional string model = 5;
- // Hardware version of this device
- optional string hardware_version = 6;
- // Software version of this device
- optional string software_version = 7;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 8;
-}
-
-/**
- * Logs when we receive Bluetooth Read Remote Version Information Complete Event from the remote
- * device, as documented by the Bluetooth Core HCI specification
- * Reference: https://www.bluetooth.com/specifications/bluetooth-core-specification
- * Vol 2, Part E, Page 1118
- *
- * Logged from:
- * system/bt
- */
-message BluetoothRemoteVersionInfoReported {
- // Connection handle of the connection
- // Original type: uint16_t
- optional int32 connection_handle = 1;
- // HCI command status code
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum hci_status = 2;
- // 1 byte Version of current LMP in the remote controller
- optional int32 lmp_version = 3;
- // 2 bytes LMP manufacturer code of the remote controller
- // https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
- optional int32 lmp_manufacturer_code = 4;
- // 4 bytes subversion of the LMP in the remote controller
- optional int32 lmp_subversion = 5;
-}
-
-/**
- * Logs when certain Bluetooth SDP attributes are discovered
- * Constant definitions are from:
- * https://www.bluetooth.com/specifications/assigned-numbers/service-discovery
- *
- * Current logged attributes:
- * - BluetoothProfileDescriptorList
- * - Supported Features Bitmask
- *
- * Logged from:
- * system/bt
- */
-message BluetoothSdpAttributeReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Short form UUIDs used to identify Bluetooth protocols, profiles, and service classes
- // Original type: uint16_t
- optional int32 protocol_uuid = 2;
- // Short form UUIDs used to identify Bluetooth SDP attribute types
- // Original type: uint16_t
- optional int32 attribute_id = 3;
- // Attribute value for the particular attribute
- optional bytes attribute_value = 4 [(android.os.statsd.log_mode) = MODE_BYTES];
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when bond state of a Bluetooth device changes
- *
- * Logged from:
- * frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
- */
-message BluetoothBondStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Preferred transport type to remote dual mode device
- // Default: TRANSPORT_AUTO means no preference
- optional android.bluetooth.TransportTypeEnum transport = 2;
- // The type of this Bluetooth device (Classic, LE, or Dual mode)
- // Default: UNKNOWN
- optional android.bluetooth.DeviceTypeEnum type = 3;
- // Current bond state (NONE, BONDING, BONDED)
- // Default: BOND_STATE_UNKNOWN
- optional android.bluetooth.BondStateEnum bond_state = 4;
- // Bonding sub state
- // Default: BOND_SUB_STATE_UNKNOWN
- optional android.bluetooth.BondSubStateEnum bonding_sub_state = 5;
- // Unbond Reason
- // Default: UNBOND_REASON_UNKNOWN
- optional android.bluetooth.UnbondReasonEnum unbond_reason = 6;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 7;
-}
-
-/**
- * Logs there is an event related Bluetooth classic pairing
- *
- * Logged from:
- * system/bt
- */
-message BluetoothClassicPairingEventReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Connection handle of this connection if available
- // Range: 0x0000 - 0x0EFF (12 bits)
- // Default: 0xFFFF if the handle is unknown
- optional int32 connection_handle = 2;
- // HCI command associated with this event
- // Default: CMD_UNKNOWN
- optional android.bluetooth.hci.CommandEnum hci_cmd = 3;
- // HCI event associated with this event
- // Default: EVT_UNKNOWN
- optional android.bluetooth.hci.EventEnum hci_event = 4;
- // HCI command status code if this is triggerred by hci_cmd
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum cmd_status = 5;
- // HCI reason code associated with this event
- // Default: STATUS_UNKNOWN
- optional android.bluetooth.hci.StatusEnum reason_code = 6;
- // A status value related to this specific event
- // Default: 0
- optional int64 event_value = 7;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 8;
-}
-
-/**
- * Logs when there is an event related to Bluetooth Security Manager Protocol (SMP)
- *
- * Logged from:
- * system/bt
- */
-message BluetoothSmpPairingEventReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if the device identifier is not known
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // SMP command sent or received over L2CAP
- // Default: CMD_UNKNOWN
- optional android.bluetooth.smp.CommandEnum smp_command = 2;
- // Whether this command is sent or received
- // Default: DIRECTION_UNKNOWN
- optional android.bluetooth.DirectionEnum direction = 3;
- // SMP failure reason code
- // Default: PAIRING_FAIL_REASON_DEFAULT
- optional android.bluetooth.smp.PairingFailReasonEnum smp_fail_reason = 4;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 5;
-}
-
-/**
- * Logs when a Bluetooth socket’s connection state changed
- *
- * Logged from:
- * system/bt
- */
-message BluetoothSocketConnectionStateChanged {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if this is a server listener socket
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Temporary port of this socket for the current connection or session only
- // Default 0 when unknown or don't care
- optional int32 port = 2;
- // Socket type as mentioned in
- // frameworks/base/core/java/android/bluetooth/BluetoothSocket.java
- // Default: SOCKET_TYPE_UNKNOWN
- optional android.bluetooth.SocketTypeEnum type = 3;
- // Socket connection state
- // Default: SOCKET_CONNECTION_STATE_UNKNOWN
- optional android.bluetooth.SocketConnectionstateEnum state = 4;
- // Number of bytes sent to remote device during this connection
- optional int64 tx_bytes = 5;
- // Number of bytes received from remote device during this connection
- optional int64 rx_bytes = 6;
- // Socket owner's UID
- optional int32 uid = 7 [(is_uid) = true];
- // Server port of this socket, if any. When both |server_port| and |port| fields are populated,
- // |port| must be spawned by |server_port|
- // Default 0 when unknown or don't care
- optional int32 server_port = 8;
- // Whether this is a server listener socket
- optional android.bluetooth.SocketRoleEnum is_server = 9;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 10;
-}
-
-/**
- * Logs when Class of Device (CoD) value is learnt for a device during pairing or connection
- *
- * Logged from:
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
- * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java
- *
- */
-message BluetoothClassOfDeviceReported {
- // An identifier that can be used to match events for this device.
- // Currently, this is a salted hash of the MAC address of this Bluetooth device.
- // Salt: Randomly generated 256 bit value
- // Hash algorithm: HMAC-SHA256
- // Size: 32 byte
- // Default: null or empty if this is a server listener socket
- optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
- // Class of Device (CoD) value including both Major, Minor device class and service class
- // Defined in: https://www.bluetooth.com/specifications/assigned-numbers/baseband
- // Also defined in: https://developer.android.com/reference/android/bluetooth/BluetoothClass
- // Default: 0
- optional int32 class_of_device = 2;
- // An identifier that can be used to match events for this device.
- // The incremental identifier is locally generated and guaranteed not derived
- // from any globally unique hardware id.
- // For paired devices, it stays consistent between Bluetooth toggling for the
- // same remote device.
- // For unpaired devices, it stays consistent within the same Bluetooth adapter
- // session for the same remote device.
- // Default: 0 if the device's metric id is unknown.
- optional int32 metric_id = 3;
-}
-
-/**
- * Logs when something is plugged into or removed from the USB-C connector.
- *
- * Logged from:
- * UsbService
- */
-message UsbConnectorStateChanged {
- enum State {
- STATE_DISCONNECTED = 0;
- STATE_CONNECTED = 1;
- }
- optional State state = 1
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
- optional string id = 2 [(state_field_option).primary_field = true];
- // Last active session in ms.
- // 0 when the port is in connected state.
- optional int64 last_connect_duration_millis = 3;
-}
-
-/**
- * Logs the reported speaker impedance.
- *
- * Logged from:
- * Vendor audio implementation.
- */
-message SpeakerImpedanceReported {
- optional int32 speaker_location = 1;
- optional int32 impedance = 2;
-}
-
-/**
- * Logs the report of a failed hardware.
- *
- * Logged from:
- * Vendor HALs.
- *
- */
-message HardwareFailed {
- enum HardwareType {
- HARDWARE_FAILED_UNKNOWN = 0;
- HARDWARE_FAILED_MICROPHONE = 1;
- HARDWARE_FAILED_CODEC = 2;
- HARDWARE_FAILED_SPEAKER = 3;
- HARDWARE_FAILED_FINGERPRINT = 4;
- }
- optional HardwareType hardware_type = 1;
-
- /**
- * hardware_location allows vendors to differentiate between multiple instances of
- * the same hardware_type. The specific locations are vendor defined integers,
- * referring to board-specific numbering schemes.
- */
- optional int32 hardware_location = 2;
-
- /**
- * failure_code is specific to the HardwareType of the failed hardware.
- * It should use one of the enum values defined below.
- */
- enum HardwareErrorCode {
- UNKNOWN = 0;
- COMPLETE = 1;
- SPEAKER_HIGH_Z = 2;
- SPEAKER_SHORT = 3;
- FINGERPRINT_SENSOR_BROKEN = 4;
- FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
- DEGRADE = 6;
- }
- optional int32 failure_code = 3;
-}
-
-/**
- * Log an event when the device has been physically dropped.
- * Reported from the /vendor partition.
- */
-message PhysicalDropDetected {
- // Confidence that the event was actually a drop, 0 -> 100
- optional int32 confidence_pctg = 1;
- // Peak acceleration of the drop, in 1/1000s of a g.
- optional int32 accel_peak_thousandths_g = 2;
- // Duration of freefall in ms
- optional int32 freefall_time_millis = 3;
-}
-
-/**
- * Log bucketed battery charge cycles.
- *
- * Each bucket represents cycles of the battery past
- * a given charge point. For example, if 10 cycle buckets are
- * initialized, bucket 1 is the lowest 1/10th of the battery,
- * and bucket 10 is 100%.
- *
- * Logged from:
- * /sys/class/power_supply/bms/cycle_count, via Vendor.
- */
-message ChargeCyclesReported {
- optional int32 cycle_bucket_1 = 1;
- optional int32 cycle_bucket_2 = 2;
- optional int32 cycle_bucket_3 = 3;
- optional int32 cycle_bucket_4 = 4;
- optional int32 cycle_bucket_5 = 5;
- optional int32 cycle_bucket_6 = 6;
- optional int32 cycle_bucket_7 = 7;
- optional int32 cycle_bucket_8 = 8;
- optional int32 cycle_bucket_9 = 9;
- optional int32 cycle_bucket_10 = 10;
-}
-
-/**
- * Log battery health snapshot.
- *
- * Resistance, Voltage, Open Circuit Voltage, Temperature, and Charge Level
- * are snapshotted periodically over 24hrs.
- */
-message BatteryHealthSnapshot {
- enum BatterySnapshotType {
- UNKNOWN = 0;
- MIN_TEMP = 1; // Snapshot at min batt temp over 24hrs.
- MAX_TEMP = 2; // Snapshot at max batt temp over 24hrs.
- MIN_RESISTANCE = 3; // Snapshot at min batt resistance over 24hrs.
- MAX_RESISTANCE = 4; // Snapshot at max batt resistance over 24hrs.
- MIN_VOLTAGE = 5; // Snapshot at min batt voltage over 24hrs.
- MAX_VOLTAGE = 6; // Snapshot at max batt voltage over 24hrs.
- MIN_CURRENT = 7; // Snapshot at min batt current over 24hrs.
- MAX_CURRENT = 8; // Snapshot at max batt current over 24hrs.
- MIN_BATT_LEVEL = 9; // Snapshot at min battery level (SoC) over 24hrs.
- MAX_BATT_LEVEL = 10; // Snapshot at max battery level (SoC) over 24hrs.
- AVG_RESISTANCE = 11; // Snapshot at average battery resistance over 24hrs.
- }
- optional BatterySnapshotType type = 1;
- // Temperature, in 1/10ths of degree C.
- optional int32 temperature_deci_celsius = 2;
- // Voltage Battery Voltage, in microVolts.
- optional int32 voltage_micro_volt = 3;
- // Current Battery current, in microAmps.
- optional int32 current_micro_amps = 4;
- // OpenCircuitVoltage Battery Open Circuit Voltage, in microVolts.
- optional int32 open_circuit_micro_volt = 5;
- // Resistance Battery Resistance, in microOhms.
- optional int32 resistance_micro_ohm = 6;
- // Level Battery Level, as % of full.
- optional int32 level_percent = 7;
-}
-
-/**
- * Log slow I/O operations on the primary storage.
- */
-message SlowIo {
- // Classifications of IO Operations.
- enum IoOperation {
- UNKNOWN = 0;
- READ = 1;
- WRITE = 2;
- UNMAP = 3;
- SYNC = 4;
- }
- optional IoOperation operation = 1;
-
- // The number of slow IO operations of this type over 24 hours.
- optional int32 count = 2;
-}
-
-/**
- * Log battery caused shutdown with the last recorded voltage.
- */
-message BatteryCausedShutdown {
- // The last recorded battery voltage prior to shutdown.
- optional int32 last_recorded_micro_volt = 1;
-}
-
-/**
- * Logs when ThermalService receives throttling events.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/stats/StatsCompanionService.java
- */
-message ThermalThrottlingSeverityStateChanged {
- // The type of temperature being reported (CPU, GPU, SKIN, etc)
- optional android.os.TemperatureTypeEnum sensor_type = 1;
-
- // The name of the temperature source. Eg. CPU0
- optional string sensor_name = 2;
-
- // Temperature in tenths of a degree C.
- // For BCL, it is decimillivolt, decimilliamps, and percentage * 10.
- optional int32 temperature_deci_celsius = 3;
-
- // Relative severity of the throttling, see enum definition.
- optional android.os.ThrottlingSeverityEnum severity = 4;
-}
-
-/**
- * Logs the duration of a davey (jank of >=700ms) when it occurs
- *
- * Logged from:
- * frameworks/base/libs/hwui/JankTracker.cpp
- */
-message DaveyOccurred {
- // The UID that logged this atom.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Amount of time it took to render the frame. Should be >=700ms.
- optional int64 jank_duration_millis = 2;
-}
-
-/**
- * Logs phone signal strength changes.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message PhoneSignalStrengthChanged {
- // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto.
- optional android.telephony.SignalStrengthEnum signal_strength = 1;
-}
-
-
-/**
- * Logs when the phone state, sim state or signal strength changes
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message PhoneServiceStateChanged {
- optional android.telephony.ServiceStateEnum state = 1;
- optional android.telephony.SimStateEnum sim_state = 2;
- optional android.telephony.SignalStrengthEnum signal_strength = 3;
-}
-
-/**
- * Logs when the phone becomes on or off.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/TelephonyRegistry.java
- */
-message PhoneStateChanged {
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 1;
-}
-
-message BackGesture {
- enum BackType {
- DEFAULT_BACK_TYPE = 0;
- COMPLETED = 1;
- COMPLETED_REJECTED = 2; // successful because coming from rejected area
- INCOMPLETE_EXCLUDED = 3; // would have been successful but in the exclusion area
- INCOMPLETE = 4; // Unsuccessful, for reasons other than below.
- INCOMPLETE_FAR_FROM_EDGE = 5; // Unsuccessful, far from the edge.
- INCOMPLETE_MULTI_TOUCH = 6; // Unsuccessful, multi touch.
- INCOMPLETE_LONG_PRESS = 7; // Unsuccessful, long press.
- INCOMPLETE_VERTICAL_MOVE = 8; // Unsuccessful, move vertically.
- }
- optional BackType type = 1;
-
- optional int32 y_coordinate = 2 [deprecated = true]; // y coordinate for ACTION_DOWN event
- optional int32 start_x = 4; // X coordinate for ACTION_DOWN event.
- optional int32 start_y = 5; // Y coordinate for ACTION_DOWN event.
- optional int32 end_x = 6; // X coordinate for ACTION_MOVE event.
- optional int32 end_y = 7; // Y coordinate for ACTION_MOVE event.
- optional int32 left_boundary = 8; // left edge width + left inset
- optional int32 right_boundary = 9; // screen width - (right edge width + right inset)
-
- enum WindowHorizontalLocation {
- DEFAULT_LOCATION = 0;
- LEFT = 1;
- RIGHT = 2;
- }
- optional WindowHorizontalLocation x_location = 3 [deprecated = true];
-}
-
-message ExclusionRectStateChanged {
- optional string component_name = 1; // if not available, simply packageName
- optional int32 requested_height = 2; // px
- optional int32 rejected_height = 3; // px
-
- enum WindowHorizontalLocation {
- DEFAULT_LOCATION = 0;
- LEFT = 1;
- RIGHT = 2;
- }
- optional WindowHorizontalLocation x_location = 4;
- optional bool landscape = 5;
- optional bool splitscreen = 6;
- optional int32 duration_millis = 7;
-}
-
-/**
- * Logs when IME is on.
- *
- * Logged from: /packages/SystemUI/src/com/android/systemui/
- statusbar/phone/NavigationBarView.java
- *
- */
-message ImeTouchReported {
- optional int32 x_coordinate = 1; // X coordinate for ACTION_DOWN event.
- optional int32 y_coordinate = 2; // Y coordinate for ACTION_DOWN event.
-}
-
-/**
- * Logs when Launcher (HomeScreen) UI has changed or was interacted.
- *
- * Logged from:
- * packages/apps/Launcher3
- */
-message LauncherUIChanged {
- optional android.stats.launcher.LauncherAction action = 1 [deprecated = true];
- optional android.stats.launcher.LauncherState src_state = 2;
- optional android.stats.launcher.LauncherState dst_state = 3;
- optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES, deprecated = true];
- optional bool is_swipe_up_enabled = 5 [deprecated = true];
-
- // The event id (e.g., app launch, drag and drop, long press)
- optional int32 event_id = 6;
- // The event's source or target id (e.g., icon, task, button)
- optional int32 target_id = 7;
- // If the target needs to be tracked, use this id field
- optional int32 instance_id = 8;
- optional int32 uid = 9 [(is_uid) = true];
- optional string package_name = 10;
- optional string component_name = 11;
-
- // (x, y) coordinate and the index information of the target on the container
- optional int32 grid_x = 12 [default = -1];
- optional int32 grid_y = 13 [default = -1];
- optional int32 page_id = 14 [default = -2];
-
- // e.g., folder icon's (x, y) location and index information on the workspace
- optional int32 grid_x_parent = 15 [default = -1];
- optional int32 grid_y_parent = 16 [default = -1];
- optional int32 page_id_parent = 17 [default = -2];
-
- // e.g., SEARCHBOX_ALLAPPS, FOLDER_WORKSPACE
- optional int32 hierarchy = 18;
-
- optional bool is_work_profile = 19;
-
- // Used to store the predicted rank of the target
- optional int32 rank = 20 [default = -1];
-
- // e.g., folderLabelState can be captured in the following two fields
- optional int32 from_state = 21;
- optional int32 to_state = 22;
-
- // e.g., autofilled or suggested texts that are not user entered
- optional string edittext = 23;
-
- // e.g., number of contents inside a container (e.g., icons inside a folder)
- optional int32 cardinality = 24;
-}
-
-/**
- * Used for snapshot of the HomeScreen UI elements
- *
- * Logged from:
- * packages/apps/Launcher3
- */
-message LauncherStaticLayout {
- // The event id (e.g., snapshot, drag and drop)
- optional int32 event_id = 1;
- // The event's source or target id (e.g., icon, shortcut, widget)
- optional int32 target_id = 2;
- // If the target needs to be tracked, use this id field
- optional int32 instance_id = 3;
- optional int32 uid = 4 [(is_uid) = true];
- optional string package_name = 5;
- optional string component_name = 6;
-
- // (x, y) coordinate and the index information of the target on the container
- optional int32 grid_x = 7 [default = -1];
- optional int32 grid_y = 8 [default = -1];
- optional int32 page_id = 9 [default = -2];
-
- // e.g., folder icon's (x, y) location and index information on the workspace
- // e.g., when used with widgets target, use these values for (span_x, span_y)
- optional int32 grid_x_parent = 10 [default = -1];
- optional int32 grid_y_parent = 11 [default = -1];
- optional int32 page_id_parent = 12 [default = -2];
-
- // UNKNOWN = 0
- // HOTSEAT = 1
- // WORKSPACE = 2
- // FOLDER_HOTSEAT = 3
- // FOLDER_WORKSPACE = 4
- optional int32 hierarchy = 13;
-
- optional bool is_work_profile = 14;
-
- // e.g., PIN, WIDGET TRAY, APPS TRAY, PREDICTION
- optional int32 origin = 15;
-
- // e.g., number of icons inside a folder
- optional int32 cardinality = 16;
-
- // e.g., (x, y) span of the widget inside homescreen grid system
- optional int32 span_x = 17 [default = 1];
- optional int32 span_y = 18 [default = 1];
-}
-
-/**
- * Logs when Wallpaper or ThemePicker UI has changed.
- *
- * Logged from:
- * packages/apps/ThemePicker
- * packages/apps/WallpaperPicker2
- */
-message StyleUIChanged {
- optional android.stats.style.Action action = 1;
- optional int32 color_package_hash = 2;
- optional int32 font_package_hash = 3;
- optional int32 shape_package_hash = 4;
- optional int32 clock_package_hash = 5;
- optional int32 launcher_grid = 6;
- optional int32 wallpaper_category_hash = 7;
- optional int32 wallpaper_id_hash = 8;
- optional int32 color_preference = 9;
- optional android.stats.style.LocationPreference location_preference = 10;
-}
-
-/**
- * Logs when Settings UI has changed.
- *
- * Logged from:
- * packages/apps/Settings
- */
-message SettingsUIChanged {
- /**
- * Where this SettingsUIChange event comes from. For example, if
- * it's a PAGE_VISIBLE event, where the page is opened from.
- */
- optional android.app.settings.PageId attribution = 1;
-
- /**
- * What the UI action is.
- */
- optional android.app.settings.Action action = 2;
-
- /**
- * Where the action is happening
- */
- optional android.app.settings.PageId page_id = 3;
-
- /**
- * What preference changed in this event.
- */
- optional string changed_preference_key = 4;
-
- /**
- * The new value of the changed preference.
- */
- optional int64 changed_preference_int_value = 5;
-}
-
-/**
- * Logs basic timing information about touch events.
- * Reported at most every 5 minutes while device is being interacted with.
- *
- * Logged from:
- * frameworks/native/services/inputflinger
- */
-message TouchEventReported {
- /**
- * The fields latency_{min|max|mean|stdev} represent minimum, maximum, mean,
- * and the standard deviation of the time spent processing touchscreen events
- * in the kernel and inputflinger. The units are microseconds.
- *
- * On supported devices, the starting point is taken during the hard interrupt inside the
- * kernel touch driver. On all other devices, the starting point is taken inside
- * the kernel's input event subsystem upon receipt of the input event.
- * The ending point is taken inside InputDispatcher, just after the input event
- * is sent to the app.
- */
- // Minimum value
- optional float latency_min_micros = 1;
- // Maximum value
- optional float latency_max_micros = 2;
- // Average value
- optional float latency_mean_micros = 3;
- // Standard deviation
- optional float latency_stdev_micros = 4;
- // Number of touch events (input_event) in this report
- optional int32 count = 5;
-}
-
-/**
- * Logs gesture classification and timing information for touch events.
- *
- * Logged from:
- * frameworks/base/core/java/android/view/GestureDetector.java
- * frameworks/base/core/java/android/view/View.java
- */
-message TouchGestureClassified {
- // The source of the classification (e.g. Java class name).
- optional string source = 1;
-
- enum Classification {
- UNKNOWN_CLASSIFICATION = 0;
- SINGLE_TAP = 1;
- DOUBLE_TAP = 2;
- LONG_PRESS = 3;
- DEEP_PRESS = 4;
- SCROLL = 5;
- }
- // The classification of the gesture.
- optional Classification classification = 2;
-
- // The interval from the start of a touch event stream until the
- // classification was made.
- optional int32 latency_millis = 3;
-
- // The distance from the location of the first touch event to the
- // location of the touch event when the classification was made.
- optional float displacement_px = 4;
-}
-
-/**
- * Logs that a setting was updated.
- * Logged from:
- * frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
- * The tag and is_default allow resetting of settings to default values based on the specified
- * tag. See Settings#putString(ContentResolver, String, String, String, boolean) for more details.
- */
-message SettingChanged {
- // The name of the setting.
- optional string setting = 1;
-
- // The change being imposed on this setting. May represent a number, eg "3".
- optional string value = 2;
-
- // The new value of this setting. For most settings, this is same as value. For some settings,
- // value is +X or -X where X represents an element in a set. For example, if the previous value
- // is A,B,C and value is -B, then new_value is A,C and prev_value is A,B,C.
- // The +/- feature is currently only used for location_providers_allowed.
- optional string new_value = 3;
-
- // The previous value of this setting.
- optional string prev_value = 4;
-
- // The tag used with the is_default for resetting sets of settings. This is generally null.
- optional string tag = 5;
-
- // True if this setting with tag should be resettable.
- optional bool is_default = 6;
-
- // The associated user (for multi-user feature). Defined in android/os/UserHandle.java
- optional int32 user = 7;
-
- enum ChangeReason {
- UPDATED = 1; // Updated can be an insertion or an update.
- DELETED = 2;
- }
- optional ChangeReason reason = 8;
-}
-
-/**
- * Logs activity going to foreground or background
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
- */
-message ActivityForegroundStateChanged {
- optional int32 uid = 1 [(is_uid) = true];
- optional string pkg_name = 2;
- optional string class_name = 3;
-
- enum State {
- BACKGROUND = 0;
- FOREGROUND = 1;
- }
- optional State state = 4;
-}
-
-/**
- * Logs when a volume entered low Storage state.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
- */
-message LowStorageStateChanged {
- // Volume that ran out of storage.
- optional string volume_description = 1;
-
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- }
- optional State state = 2;
-}
-
-/**
- * Logs when an app is downgraded.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java
- */
-message AppDowngraded {
- optional string package_name = 1;
- // Size of the package (all data) before being downgraded.
- optional int64 size_in_bytes_before = 2;
- // Size of the package (all data) after being downgraded.
- optional int64 size_in_bytes_after = 3;
-
- optional bool aggressive = 4;
-}
-
-/**
- * Logs when an app is optimized after being downgraded.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java
- */
-message AppOptimizedAfterDowngraded {
- optional string package_name = 1;
-}
-
-/**
- * Logs whenever an app is installed on external storage.
- * Logged from:
- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- */
-message AppInstallOnExternalStorageReported {
- // The type of external storage.
- optional android.stats.storage.ExternalStorageType storage_type = 1;
- // The name of the package that is installed on the sd card.
- optional string package_name = 2;
-}
-
-/**
- * Logs when an app crashes.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppCrashOccurred {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string event_type = 2;
-
- // The name of the process.
- // system_server if it is not by an app
- optional string process_name = 3;
-
- // The pid if available. -1 means not available.
- optional int32 pid = 4;
-
- optional string package_name = 5;
-
- enum InstantApp {
- UNAVAILABLE = 0;
- FALSE = 1;
- TRUE = 2;
- }
- optional InstantApp is_instant_app = 6;
-
- enum ForegroundState {
- UNKNOWN = 0;
- BACKGROUND = 1;
- FOREGROUND = 2;
- }
- optional ForegroundState foreground_state = 7;
-
- optional android.server.ErrorSource error_source = 8;
-}
-
-/**
- * Logs when a WTF (What a Terrible Failure) happened.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message WTFOccurred {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string tag = 2;
-
- // The name of the process.
- // system_server if it is not by an app
- optional string process_name = 3;
-
- // The pid if available. -1 means not available.
- optional int32 pid = 4;
-
- optional android.server.ErrorSource error_source = 5;
-}
-
-/**
- * Logs when system server reports low memory.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message LowMemReported {
-}
-
-/**
- * Logs when an app ANR (App Not Responding) occurs.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/AppErrors.java
- */
-message ANROccurred {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string process_name = 2;
-
- optional string short_component_name = 3;
-
- optional string reason = 4;
-
- enum InstantApp {
- UNAVAILABLE = 0;
- FALSE = 1;
- TRUE = 2;
- }
- optional InstantApp is_instant_app = 5;
-
- enum ForegroundState {
- UNKNOWN = 0;
- BACKGROUND = 1;
- FOREGROUND = 2;
- }
- optional ForegroundState foreground_state = 6;
-
- optional android.server.ErrorSource error_source = 7;
-
- optional string package_name = 8;
-}
-
-/**
- * Logs when the vibrator state changes.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/VibratorService.java
- */
-message VibratorStateChanged {
- repeated AttributionNode attribution_node = 1;
-
- enum State {
- OFF = 0;
- ON = 1;
- }
- optional State state = 2;
-
- // Duration (in milliseconds) requested to keep the vibrator on.
- // Only applicable for State == ON.
- optional int64 duration_millis = 3;
-}
-
-/*
- * Allows other apps to push events into statsd.
- * Logged from:
- * frameworks/base/core/java/android/util/StatsLog.java
- */
-message AppBreadcrumbReported {
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
-
- // An arbitrary label chosen by the developer. For Android P, the label should be in [0, 16).
- optional int32 label = 2;
-
- // Allows applications to easily use a custom event as start/stop boundaries (ie, define custom
- // predicates for the metrics).
- enum State {
- UNKNOWN = 0;
- UNSPECIFIED = 1; // For events that are known to not represent START/STOP.
- STOP = 2;
- START = 3;
- }
- optional State state = 3;
-}
-
-/**
- * Logs the wall-clock time when a significant wall-clock time shift occurs.
- * For example, this could be due to the user manually changing the time.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/AlarmManagerService.java
- */
-message WallClockTimeShifted {
- // New wall-clock time in milliseconds, according to System.currentTimeMillis().
- optional int64 wall_clock_timestamp_millis = 1;
-}
-
-/**
- * Logs when statsd detects an anomaly.
- *
- * Logged from:
- * frameworks/base/cmds/statsd/src/anomaly/AnomalyTracker.cpp
- */
-message AnomalyDetected {
- // Uid that owns the config whose anomaly detection alert fired.
- optional int32 config_uid = 1 [(is_uid) = true];
-
- // Id of the config whose anomaly detection alert fired.
- optional int64 config_id = 2;
-
- // Id of the alert (i.e. name of the anomaly that was detected).
- optional int64 alert_id = 3;
-}
-
-message AppStartOccurred {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The app package name.
- optional string pkg_name = 2;
-
- enum TransitionType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
- // The transition type.
- optional TransitionType type = 3;
-
- // The activity name.
- optional string activity_name = 4;
-
- // The name of the calling app. Empty if not set.
- optional string calling_pkg_name = 5;
-
- // Whether the app is an instant app.
- optional bool is_instant_app = 6;
-
- // Device uptime when activity started.
- optional int64 activity_start_millis = 7;
-
- optional android.app.AppTransitionReasonEnum reason = 8;
-
- optional int32 transition_delay_millis = 9;
- // -1 if not set.
- optional int32 starting_window_delay_millis = 10;
- // -1 if not set.
- optional int32 bind_application_delay_millis = 11;
- optional int32 windows_drawn_delay_millis = 12;
-
- // Empty if not set.
- optional string launch_token = 13;
-
- // The compiler filter used when when the package was optimized.
- optional int32 package_optimization_compilation_filter = 14;
-
- // The reason why the package was optimized.
- optional int32 package_optimization_compilation_reason = 15;
-}
-
-message AppStartCanceled {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The app package name.
- optional string pkg_name = 2;
-
- enum TransitionType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
- // The transition type.
- optional TransitionType type = 3;
-
- // The activity name.
- optional string activity_name = 4;
-}
-
-message AppStartFullyDrawn {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The app package name.
- optional string pkg_name = 2;
-
- enum TransitionType {
- UNKNOWN = 0;
- WITH_BUNDLE = 1;
- WITHOUT_BUNDLE = 2;
- }
- // The transition type.
- optional TransitionType type = 3;
-
- // The activity name.
- optional string activity_name = 4;
-
- optional bool transition_process_running = 5;
-
- // App startup time (until call to Activity#reportFullyDrawn()).
- optional int64 app_startup_time_millis = 6;
-}
-
-/**
- * Logs a picture-in-picture action
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- * frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
- * frameworks/base/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
- */
-message PictureInPictureStateChanged {
- // -1 if it is not available
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string short_name = 2;
-
- enum State {
- ENTERED = 1;
- EXPANDED_TO_FULL_SCREEN = 2;
- MINIMIZED = 3;
- DISMISSED = 4;
- }
- optional State state = 3;
-}
-
-/**
- * Logs overlay action
- * Logged from:
- * services/core/java/com/android/server/wm/Session.java
- */
-message OverlayStateChanged {
- optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true];
-
- optional string package_name = 2 [(state_field_option).primary_field = true];
-
- optional bool using_alert_window = 3;
-
- enum State {
- ENTERED = 1;
- EXITED = 2;
- }
- optional State state = 4
- [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
-}
-
-/**
- * Logs foreground service starts and stops.
- * Note that this is not when a service starts or stops, but when it is
- * considered foreground.
- * Logged from
- * frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
- */
-message ForegroundServiceStateChanged {
- optional int32 uid = 1 [(is_uid) = true];
- // package_name + "/" + class_name
- optional string short_name = 2;
-
- enum State {
- ENTER = 1;
- EXIT = 2;
- }
- optional State state = 3;
-
- // Whether the fgs is allowed while-in-use permissions, i.e. is considered 'in-use' to the user.
- // (If the fgs was started while the app wasn't TOP it usually will be denied these permissions)
- optional bool allow_while_in_use_permission = 4;
-}
-
-/**
- * Logs the number of times a uid accesses a sensitive AppOp during a foreground service session.
- * A foreground service session is any continuous period during which the uid holds at least one
- * foreground service; the atom will be pushed when the uid no longer holds any foreground services.
- * Accesses initiated while the uid is in the TOP state are ignored.
- * Sessions with no attempted accesses are not logged.
- * Logged from
- * frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
- */
-message ForegroundServiceAppOpSessionEnded {
- optional int32 uid = 1 [(is_uid) = true];
-
- // The operation's name.
- // Only following four ops are logged
- // COARSE_LOCATION = 0
- // FINE_LOCATION = 1
- // CAMERA = 26
- // RECORD_AUDIO = 27
- optional android.app.AppOpEnum app_op_name = 2 [default = APP_OP_NONE];
-
- // The uid's permission mode for accessing the AppOp during this fgs session.
- enum Mode {
- MODE_UNKNOWN = 0;
- MODE_ALLOWED = 1; // Always allowed
- MODE_IGNORED = 2; // Denied
- MODE_FOREGROUND = 3; // Allow-while-in-use (or allowed-one-time)
- }
- optional Mode app_op_mode = 3;
-
- // Number of times this AppOp was requested and allowed.
- optional int32 count_ops_accepted = 4;
- // Number of times this AppOp was requested but denied.
- optional int32 count_ops_rejected = 5;
-}
-
-/**
- * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky
- * behavior in its own uid. However, the metrics of these isolated uid's almost always should be
- * attributed back to the parent (host) uid. One example is Chrome.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message IsolatedUidChanged {
- // The host UID. Generally, we should attribute metrics from the isolated uid to the host uid.
- // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd.
- // This field is ignored when event == REMOVED.
- optional int32 parent_uid = 1;
-
- optional int32 isolated_uid = 2;
-
- // We expect an isolated uid to be removed before if it's used for another parent uid.
- enum Event {
- REMOVED = 0;
- CREATED = 1;
- }
- optional Event event = 3;
-}
-
-/*
- * Logs the reception of an incoming network packet causing the main system to wake up for
- * processing that packet. These events are notified by the kernel via Netlink NFLOG to Netd
- * and processed by WakeupController.cpp.
- */
-message PacketWakeupOccurred {
- // The uid owning the socket into which the packet was delivered, or -1 if the packet was
- // delivered nowhere.
- optional int32 uid = 1 [(is_uid) = true];
- // The interface name on which the packet was received.
- optional string iface = 2;
- // The ethertype value of the packet.
- optional int32 ethertype = 3;
- // String representation of the destination MAC address of the packet.
- optional string destination_hardware_address = 4;
- // String representation of the source address of the packet if this was an IP packet.
- optional string source_ip = 5;
- // String representation of the destination address of the packet if this was an IP packet.
- optional string destination_ip = 6;
- // The value of the protocol field if this was an IPv4 packet or the value of the Next Header
- // field if this was an IPv6 packet. The range of possible values is the same for both IP
- // families.
- optional int32 ip_next_header = 7;
- // The source port if this was a TCP or UDP packet.
- optional int32 source_port = 8;
- // The destination port if this was a TCP or UDP packet.
- optional int32 destination_port = 9;
-}
-
-/*
- * Logs the memory stats for an app on startup.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppStartMemoryStateCaptured {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- optional string process_name = 2;
-
- // The activity name.
- optional string activity_name = 3;
-
- // # of page-faults
- optional int64 page_fault = 4;
-
- // # of major page-faults
- optional int64 page_major_fault = 5;
-
- // RSS
- optional int64 rss_in_bytes = 6;
-
- // CACHE
- optional int64 cache_in_bytes = 7;
-
- // SWAP
- optional int64 swap_in_bytes = 8;
-}
-
-/*
- * Logs the change in Low Memory Killer Daemon (LMKD) state which is used as start/stop boundaries
- * for LMK event.
- * Logged from:
- * system/core/lmkd/lmkd.c
- */
-message LmkStateChanged {
- enum State {
- UNKNOWN = 0;
- START = 1;
- STOP = 2;
- }
- optional State state = 1;
-}
-
-/*
- * Logs the event when Low Memory Killer Daemon (LMKD) kills a process to reduce memory pressure.
- * Logged from:
- * system/core/lmkd/lmkd.c
- */
-message LmkKillOccurred {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- optional string process_name = 2;
-
- // oom adj score.
- optional int32 oom_adj_score = 3;
-
- // # of page-faults
- optional int64 page_fault = 4;
-
- // # of major page-faults
- optional int64 page_major_fault = 5;
-
- // RSS
- optional int64 rss_in_bytes = 6;
-
- // CACHE
- optional int64 cache_in_bytes = 7;
-
- // SWAP
- optional int64 swap_in_bytes = 8;
-
- // The elapsed real time of start of the process.
- optional int64 process_start_time_nanos = 9;
-
- // Min oom adj score considered by lmkd.
- optional int32 min_oom_score = 10;
-}
-
-/*
- * Logs when the ActivityManagerService detects that an app died.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppDied {
- // timestamp(elapsedRealtime) of record creation
- optional uint64 timestamp_millis = 1 [(state_field_option).exclusive_state = true];
-}
-
-/**
- * An atom for generic metrics logging. Available from Android Q.
- */
-message GenericAtom {
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
-
- // An event_id indicates the type of event.
- optional android.stats.EventType event_id = 2;
-}
-
-/**
- * Atom for simple logging of user interaction and impression events, such as "the user touched
- * this button" or "this dialog was displayed".
- * Keep the UI event stream clean: don't use for system or background events.
- * Log using the UiEventLogger wrapper - don't write with the StatsLog API directly.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/
- * frameworks/base/packages/SystemUI/src/com/android/systemui/
- */
-message UiEventReported {
- // The event_id.
- optional int32 event_id = 1;
- // The event's source or target uid and package, if applicable.
- // For example, the package posting a notification, or the destination package of a share.
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
- // An identifier used to disambiguate which logs refer to a particular instance of some
- // UI element. Useful when there might be multiple instances simultaneously active.
- optional int32 instance_id = 4;
-}
-
-/**
- * Reports a notification was created or updated.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/notification/
- */
-message NotificationReported {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The notifying app's uid and package.
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
- // A small system-assigned identifier for the notification.
- // Locally probably-unique, but expect collisions across users and/or days.
- optional int32 instance_id = 4;
- optional int32 notification_id_hash = 5; // Small hash of the app-assigned notif ID + tag
- optional int32 channel_id_hash = 6; // Small hash of app-assigned channel ID
-
- // Grouping information
- optional int32 group_id_hash = 7; // Small hash of the group ID of the notification
- optional int32 group_instance_id = 8; // Instance_id of the group-summary notification
- optional bool is_group_summary = 9; // Tags the group-summary notification
-
- // Attributes
- optional string category = 10; // App-assigned notification category (API-defined strings)
- optional int32 style = 11; // App-assigned notification style
- optional int32 num_people = 12; // Number of Person records attached to the notification
-
- // Ordering, importance and interruptiveness
-
- optional int32 position = 13; // Position in NotificationManager's list
-
- optional android.stats.sysui.NotificationImportance importance = 14;
- optional int32 alerting = 15; // Bitfield, 1=buzz 2=beep 4=blink
-
- enum NotificationImportanceExplanation {
- IMPORTANCE_EXPLANATION_UNKNOWN = 0;
- IMPORTANCE_EXPLANATION_APP = 1; // App-specified channel importance.
- IMPORTANCE_EXPLANATION_USER = 2; // User-specified channel importance.
- IMPORTANCE_EXPLANATION_ASST = 3; // Notification Assistant override.
- IMPORTANCE_EXPLANATION_SYSTEM = 4; // System override.
- // Like _APP, but based on pre-channels priority signal.
- IMPORTANCE_EXPLANATION_APP_PRE_CHANNELS = 5;
- }
-
- optional NotificationImportanceExplanation importance_source = 16;
- optional android.stats.sysui.NotificationImportance importance_initial = 17;
- optional NotificationImportanceExplanation importance_initial_source = 18;
- optional android.stats.sysui.NotificationImportance importance_asst = 19;
- optional int32 assistant_hash = 20;
- optional float assistant_ranking_score = 21;
-}
-
-message Notification {
- // The notifying app's uid and package.
- optional int32 uid = 1 [(is_uid) = true];
- optional string package_name = 2;
- // A small system-assigned identifier for the notification.
- optional int32 instance_id = 3;
-
- // Grouping information.
- optional int32 group_instance_id = 4;
- optional bool is_group_summary = 5;
-
- // The section of the shade that the notification is in.
- // See NotificationSectionsManager.PriorityBucket.
- enum NotificationSection {
- SECTION_UNKNOWN = 0;
- SECTION_HEADS_UP = 1;
- SECTION_MEDIA_CONTROLS = 2;
- SECTION_PEOPLE = 3;
- SECTION_ALERTING = 4;
- SECTION_SILENT = 5;
- }
- optional NotificationSection section = 6;
-}
-
-message NotificationList {
- repeated Notification notifications = 1; // An ordered sequence of notifications.
-}
-
-/**
- * Reports a notification panel was displayed, e.g. from the lockscreen or status bar.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/
- */
-message NotificationPanelReported {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- optional int32 num_notifications = 2;
- // The notifications in the panel, in the order that they appear there.
- optional NotificationList notifications = 3 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Reports a notification channel, or channel group, was created, updated, or deleted.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/notification/
- */
-message NotificationChannelModified {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The notifying app's uid and package.
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
- // Hash of app-assigned notification channel ID or channel-group ID
- optional int32 channel_id_hash = 4;
- // Previous importance setting, if applicable
- optional android.stats.sysui.NotificationImportance old_importance = 5;
- // New importance setting
- optional android.stats.sysui.NotificationImportance importance = 6;
-}
-
-
-/**
- * Logs when a biometric acquire event occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricAcquired {
- // Biometric modality that was acquired.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java.
- optional int32 user = 2;
- // If this acquire is for a crypto operation. e.g. Secure purchases, unlock password storage.
- optional bool is_crypto = 3;
- // Action that the device is performing. Acquired messages are only expected for enroll and
- // authenticate. Other actions may indicate an error.
- optional android.hardware.biometrics.ActionEnum action = 4;
- // The client that this acquisition was received for.
- optional android.hardware.biometrics.ClientEnum client = 5;
- // Acquired constants, e.g. ACQUIRED_GOOD. See constants defined by <Biometric>Manager.
- optional int32 acquire_info = 6;
- // Vendor-specific acquire info. Valid only if acquire_info == ACQUIRED_VENDOR.
- optional int32 acquire_info_vendor = 7;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 8;
-}
-
-/**
- * Logs when a biometric authentication event occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricAuthenticated {
- // Biometric modality that was used.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
- optional int32 user = 2;
- // If this authentication is for a crypto operation. e.g. Secure purchases, unlock password
- // storage.
- optional bool is_crypto = 3;
- // The client that this acquisition was received for.
- optional android.hardware.biometrics.ClientEnum client = 4;
- // If authentication requires user confirmation. See BiometricPrompt's
- // setRequireConfirmation(bool) method.
- optional bool require_confirmation = 5;
-
- enum State {
- UNKNOWN = 0;
- REJECTED = 1;
- PENDING_CONFIRMATION = 2;
- CONFIRMED = 3;
- }
-
- // State of the current auth attempt.
- optional State state = 6;
- // Time it took to authenticate. For BiometricPrompt where setRequireConfirmation(false) is
- // specified and supported by the biometric modality, this is from the first ACQUIRED_GOOD to
- // AUTHENTICATED. for setRequireConfirmation(true), this is from PENDING_CONFIRMATION to
- // CONFIRMED.
- optional int64 latency_millis = 7;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 8;
-}
-
-/**
- * Logs when a biometric error occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricErrorOccurred {
- // Biometric modality that was used.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
- optional int32 user = 2;
- // If this error is for a crypto operation. e.g. Secure purchases, unlock password storage.
- optional bool is_crypto = 3;
- // Action that the device is performing.
- optional android.hardware.biometrics.ActionEnum action = 4;
- // The client that this acquisition was received for.
- optional android.hardware.biometrics.ClientEnum client = 5;
- // Error constants. See constants defined by <Biometric>Manager. Enums won't work since errors
- // are unique to modality.
- optional int32 error_info = 6;
- // Vendor-specific error info. Valid only if acquire_info == ACQUIRED_VENDOR. These are defined
- // by the vendor and not specified by the HIDL interface.
- optional int32 error_info_vendor = 7;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 8;
- // Time spent during the authentication attempt.
- optional int64 latency_millis = 9;
-}
-
-/**
- * Logs when a system health issue is detected.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricSystemHealthIssueDetected {
- // Biometric modality.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // Type of issue detected.
- optional android.hardware.biometrics.IssueEnum issue = 2;
- // Dictates if this message should trigger additional debugging.
- optional bool debug = 3;
-}
-
-/**
- * Logs when a biometric enrollment occurs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/biometrics
- */
-message BiometricEnrolled {
- // Biometric modality that was used.
- optional android.hardware.biometrics.ModalityEnum modality = 1;
- // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
- optional int32 user = 2;
- // The amount of time the enrollment took in milliseconds.
- optional int64 latency_millis = 3;
- // Whether or not the enrollment was successful.
- optional bool success = 4;
-}
-
-/*
- * Logs when a flag flip update occurrs. Used for mainline modules that update via flag flips.
- */
-message FlagFlipUpdateOccurred {
- // If the event is from a flag config package, specify the package name.
- optional string flag_flip_package_name = 1;
-
- // The order id of the package
- optional int64 order_id = 2;
-}
-
-/**
- * Potential experiment ids that goes with a train install.
- * Should be kept in sync with experiment_ids.proto.
- */
-message TrainExperimentIds {
- repeated int64 experiment_id = 1;
-}
-
-/*
- * Logs when a binary push state changes.
- * Logged by the installer via public api.
- */
-message BinaryPushStateChanged {
- // Name of the train.
- optional string train_name = 1;
- // Version code for a "train" of packages that need to be installed atomically
- optional int64 train_version_code = 2;
- // After installation of this package, device requires a restart.
- optional bool requires_staging = 3;
- // Rollback should be enabled for this install.
- optional bool rollback_enabled = 4;
- // Requires low latency monitoring if possible.
- optional bool requires_low_latency_monitor = 5;
-
- enum State {
- UNKNOWN = 0;
- INSTALL_REQUESTED = 1;
- INSTALL_STARTED = 2;
- INSTALL_STAGED_NOT_READY = 3;
- INSTALL_STAGED_READY = 4;
- INSTALL_SUCCESS = 5;
- // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH,
- // and INSTALL_FAILURE_COMMIT.
- INSTALL_FAILURE = 6 [deprecated = true];
- // This enum is for installs that are manually cancelled via the Manual Update UI.
- INSTALL_CANCELLED = 7;
- INSTALLER_ROLLBACK_REQUESTED = 8;
- INSTALLER_ROLLBACK_INITIATED = 9;
- INSTALLER_ROLLBACK_INITIATED_FAILURE = 10;
- INSTALLER_ROLLBACK_STAGED = 11;
- INSTALLER_ROLLBACK_STAGED_FAILURE = 12;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14;
- INSTALLER_ROLLBACK_SUCCESS = 15;
- INSTALLER_ROLLBACK_FAILURE = 16;
- INSTALLER_ROLLBACK_STAGED_CANCEL_REQUESTED = 17;
- INSTALLER_ROLLBACK_STAGED_CANCEL_SUCCESS = 18;
- INSTALLER_ROLLBACK_STAGED_CANCEL_FAILURE = 19;
- INSTALL_STAGED_CANCEL_REQUESTED = 20;
- INSTALL_STAGED_CANCEL_SUCCESS = 21;
- INSTALL_STAGED_CANCEL_FAILURE = 22;
- INSTALL_FAILURE_DOWNLOAD = 23;
- INSTALL_FAILURE_STATE_MISMATCH = 24;
- INSTALL_FAILURE_COMMIT = 25;
- REBOOT_TRIGGERED = 26;
- }
- optional State state = 6;
- // Possible experiment ids for monitoring this push.
- optional TrainExperimentIds experiment_ids = 7 [(log_mode) = MODE_BYTES];
- // user id
- optional int32 user_id = 8;
- optional int32 reason = 9;
- // Whether or not this is a rollback event
- optional bool is_rollback = 10;
-}
-
-/* Test atom, is not logged anywhere */
-message TestAtomReported {
- repeated AttributionNode attribution_node = 1;
- optional int32 int_field = 2;
- optional int64 long_field = 3;
- optional float float_field = 4;
- optional string string_field = 5;
- optional bool boolean_field = 6;
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- }
- optional State state = 7;
- optional TrainExperimentIds bytes_field = 8 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/** Represents USB port overheat event. */
-message UsbPortOverheatEvent {
- /* Temperature of USB port at USB plug event, in 1/10ths of degree C. */
- optional int32 plug_temperature_deci_c = 1;
-
- /* Maximum temperature of USB port during overheat event, in 1/10ths of degree C. */
- optional int32 max_temperature_deci_c = 2;
-
- /* Time between USB plug event and overheat threshold trip, in seconds. */
- optional int32 time_to_overheat_secs = 3;
-
- /* Time between overheat threshold trip and hysteresis, in seconds. */
- optional int32 time_to_hysteresis_secs = 4;
-
- /* Time between hysteresis and active mitigation ending, in seconds. */
- optional int32 time_to_inactive_secs = 5;
-};
-
-/**
- * Logs total effective full charge and discharge cycles on a battery.
- * Here are some examples of one effective cycle:
- * 1) the battery charges from 0% to 100% and drains back to 0%,
- * 2) charging from 50% to 100% and draining back to 50% twice.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message BatteryCycleCount {
- /* Number of total charge and discharge cycles on the system battery. */
- optional int32 cycle_count = 1;
-}
-
-/**
- * Logs that external storage is mounted and information about it, the storage type (sd card/usb/
- * others), its type (public or private) and the size in bytes.
- * Pulled from:
- * StatsCompanionService
- */
-
-message ExternalStorageInfo {
-
- enum VolumeType {
- UNKNOWN = 0;
- PUBLIC = 1;
- PRIVATE = 2;
- OTHER = 3;
- }
-
- // The type of external storage.
- optional android.stats.storage.ExternalStorageType storage_type = 1;
- // Type of the volume: TYPE_PUBLIC if portable and TYPE_PRIVATE if internal.
- optional VolumeType volume_type = 2;
- // Total size of the sd card in bytes.
- optional int64 size_bytes = 3;
-}
-
-/*
- * Logs when a connection becomes available and lost.
- * Logged in StatsCompanionService.java
- */
-message ConnectivityStateChanged {
- // Id of the network.
- optional int32 net_id = 1;
-
- enum State {
- UNKNOWN = 0;
- CONNECTED = 1;
- DISCONNECTED = 2;
- }
- // Connected state of a network.
- optional State state = 2;
-}
-
-/**
- * Logs when a service starts and stops.
- * Logged from:
- * services/core/java/com/android/server/am/ActiveServices.java
- */
-message ServiceStateChanged {
-
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string package_name = 2;
-
- optional string service_name = 3;
-
- enum State {
- START = 1;
- STOP = 2;
- }
-
- optional State state = 4;
-}
-
-/**
- * Logs when a service is launched.
- * Logged from:
- * services/core/java/com/android/server/am/ActiveServices.java
- */
-message ServiceLaunchReported {
-
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string package_name = 2;
-
- optional string service_name = 3;
-}
-
-/**
- * Logs when a hidden API is used.
- *
- * Logged from:
- * libcore/libart/src/main/java/dalvik/system/VMRuntime.java
- */
-message HiddenApiUsed {
- // The uid of the app making the hidden access.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Signature of the method or field accessed.
- optional string signature = 2;
-
- enum AccessMethod {
- NONE = 0;
- REFLECTION = 1;
- JNI = 2;
- LINKING = 3;
- }
-
- // Type of access.
- optional AccessMethod access_method = 3;
-
- // Whether the access was prevented or not.
- optional bool access_denied = 4;
-}
-
-/**
- * Logs user interaction with the Privacy Indicators added in Q. In particular:
- * - When user sees privacy chip
- * - When user clicks privacy chip
- * - How does the user exit the Privacy Dialog
- * Logged from:
- * packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
- */
-message PrivacyIndicatorsInteracted {
-
- enum Type {
- UNKNOWN = 0;
- CHIP_VIEWED = 1;
- CHIP_CLICKED = 2;
- DIALOG_PRIVACY_SETTINGS = 3;
- DIALOG_DISMISS = 4;
- DIALOG_LINE_ITEM = 5;
- }
-
- optional Type type = 1 [(state_field_option).exclusive_state = true];
-
- // Used if the type is LINE_ITEM
- optional string package_name = 2;
-}
-
-/**
- * Logs information about a package that is moved from the internal to external storage and vice
- * versa.
- * It logs the package name, the type of the external storage where the package is installed
- * (if moved to external storage, or UNKNOWN if moved to internal storage),
- * and the move type: if it's from internal to external or the other way around.
- *
- * Logged from:
- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- */
-message AppMovedStorageReported {
- enum MoveType {
- UNKNOWN = 0;
- TO_EXTERNAL = 1;
- TO_INTERNAL = 2;
- }
- // The type of the external storage.
- optional android.stats.storage.ExternalStorageType external_storage_type = 1;
- // The type of move.
- optional MoveType move_type = 2;
- // The name of the package that was moved.
- optional string package_name = 3;
-}
-
-/**
- * Logs when system server watchdog occurs.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/Watchdog.java
- */
-message SystemServerWatchdogOccurred {
- optional string subject = 1;
-}
-
-/**
- * Logs when new file added to tombstones.
- * Logged from:
- * frameworks/base/core/java/com/android/server/BootReceiver.java
- */
-message TombStoneOccurred {
-}
-
-/*
- * Information about a role request
- *
- * Logged from:
- * packages/apps/PermissionController/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java
- */
-message RoleRequestResultReported {
- // UID of application requesting the role
- optional int32 requesting_uid = 1;
-
- // Package name of application requesting the role
- optional string requesting_package_name = 2;
-
- // The role to be granted
- optional string role_name = 3;
-
- // The count of applications qualifying for the role
- optional int32 qualifying_count = 4;
-
- // UID of application current granted the role
- optional int32 current_uid = 5;
-
- // Package name of application current granted the role
- optional string current_package_name = 6;
-
- // UID of another application that user chose to grant the role to, instead of the requesting
- // application
- optional int32 granted_another_uid = 7;
-
- // Package name of another application that user chose to grant the role to, instead of the
- // requesting application
- optional string granted_another_package_name = 8;
-
- enum Result {
- UNDEFINED = 0;
- // role request was ignored
- IGNORED = 1;
- // role request was ignored because it's already granted
- IGNORED_ALREADY_GRANTED = 2;
- // role request was ignored because the application isn't qualified
- IGNORED_NOT_QUALIFIED = 3;
- // role request was ignored because user said it should be always denied
- IGNORED_USER_ALWAYS_DENIED = 4;
- // role was granted by user action
- USER_GRANTED = 5;
- // role was denied by user action
- USER_DENIED = 6;
- // role was denied by user granting another application the role
- USER_DENIED_GRANTED_ANOTHER = 7;
- // role was denied and set to be always denied by the user
- USER_DENIED_WITH_ALWAYS = 8;
- }
- // The result of the role request
- optional Result result = 9;
-}
-
-/**
- * Logs when a Vehicle Maps Service client's connection state has changed
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/stats/VmsClientLog.java
- */
-message VmsClientConnectionStateChanged {
- // The UID of the VMS client app
- optional int32 uid = 1 [(is_uid) = true];
-
- enum State {
- UNKNOWN = 0;
- // Attempting to connect to the client
- CONNECTING = 1;
- // Client connection established
- CONNECTED = 2;
- // Client connection closed unexpectedly
- DISCONNECTED = 3;
- // Client connection closed by VMS
- TERMINATED = 4;
- // Error establishing the client connection
- CONNECTION_ERROR = 5;
- }
-
- optional State state = 2;
-}
-
-message MimeTypes {
- repeated string mime_types = 1;
-}
-
-/**
- * Logs statistics regarding accesses to external storage.
- * All stats are normalized for one day period.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- */
-message GeneralExternalStorageAccessStats {
- optional int32 uid = 1 [(is_uid) = true];
- // Total number of accesses like creation, open, delete and rename/update.
- // Includes file path and ContentResolver accesses
- optional uint32 total_accesses = 2;
- // Number of file path accesses, as opposed to file path and ContentResolver.
- optional uint32 file_path_accesses = 3;
- // Number of accesses on secondary volumes like SD cards.
- // Includes file path and ContentResolver accesses
- optional uint32 secondary_storage_accesses = 4;
- // Comma-separated list of mime types that were accessed.
- optional MimeTypes mime_types_accessed = 5;
-}
-
-/**
- * Logs when MediaProvider has successfully finished scanning a storage volume.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/scan/ModernMediaScanner.java
- */
-message MediaProviderScanOccurred {
- enum Reason {
- // Scan triggered due to unknown reason
- UNKNOWN = 0;
- // Scan triggered due to storage volume being mounted
- MOUNTED = 1;
- // Scan triggered due to explicit user action or app request
- DEMAND = 2;
- // Scan triggered due to idle maintenance
- IDLE = 3;
- }
-
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // Reason why this scan was triggered
- optional Reason reason = 2;
- // Total number of files scanned
- optional int64 item_count = 3;
- // Duration of scan, normalized per file
- optional float normalized_duration_millis = 4;
- // Number of database inserts, normalized per file
- optional float normalized_insert_count = 5;
- // Number of database updates, normalized per file
- optional float normalized_update_count = 6;
- // Number of database deletes, normalized per file
- optional float normalized_delete_count = 7;
-}
-
-/**
- * Logs when an app has asked MediaProvider to delete media belonging to the user.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- */
-message MediaContentDeleted {
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // UID of app that requested deletion
- optional int32 uid = 2 [(is_uid) = true];
- // Number of items that were deleted
- optional int32 item_count = 3;
-}
-
-/**
- * Logs when an app has asked MediaProvider to grant them access to media belonging to the user.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/PermissionActivity.java
- */
-message MediaProviderPermissionRequested {
- enum Result {
- UNKNOWN = 0;
- USER_GRANTED = 1;
- AUTO_GRANTED = 2;
- USER_DENIED = 3;
- USER_DENIED_WITH_PREJUDICE = 4;
- AUTO_DENIED = 5;
- }
-
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // UID of app that requested permission
- optional int32 uid = 2 [(is_uid) = true];
- // Number of items that were requested
- optional int32 item_count = 3;
- // Result of this request
- optional Result result = 4;
-}
-
-/**
- * Logs when MediaProvider has finished upgrading or downgrading its database schema.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/DatabaseHelper.java
- */
-message MediaProviderSchemaChanged {
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
- // Old database version code
- optional int32 version_from = 2;
- // New database version code
- optional int32 version_to = 3;
- // Total number of files in database
- optional int64 item_count = 4;
- // Duration of schema change, normalized per file
- optional float normalized_duration_millis = 5;
-}
-
-/**
- * Logs when MediaProvider has finished an idle maintenance job.
- *
- * Logged from:
- * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- */
-message MediaProviderIdleMaintenanceFinished {
- // Volume type that this event pertains to
- optional android.stats.mediaprovider.VolumeType volume_type = 1;
-
- // Total number of files in database
- optional int64 item_count = 2;
- // Duration of idle maintenance, normalized per file
- optional float normalized_duration_millis = 3;
- // Number of thumbnails found to be stale, normalized per file
- optional float normalized_stale_thumbnails = 4;
- // Number of items found to be expired, normalized per file
- optional float normalized_expired_media = 5;
-}
-
-/**
- * Represents boot time event with duration in ms.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventDuration {
- enum DurationEvent {
- UNKNOWN = 0;
- // Bootloader time excluding BOOTLOADER_UI_WAIT + boot complete time. Logged from bootstat.
- ABSOLUTE_BOOT_TIME = 1;
- // Bootloader's 1st stage execution time.
- // Logged from bootstat.
- BOOTLOADER_FIRST_STAGE_EXEC = 2;
- // Bootloader's 1st stage loading time.
- // Logged from bootstat.
- BOOTLOADER_FIRST_STAGE_LOAD = 3;
- // Bootloader's kernel loading time.
- // Logged from bootstat.
- BOOTLOADER_KERNEL_LOAD = 4;
- // Bootloader's 2nd stage execution time.
- // Logged from bootstat.
- BOOTLOADER_SECOND_STAGE_EXEC = 5;
- // Bootloader's 2nd stage loading time.
- // Logged from bootstat.
- BOOTLOADER_SECOND_STAGE_LOAD = 6;
- // Duration for Bootloader to show unlocked device's warning UI. This should not happen
- // for locked device.
- // Logged from bootstat.
- BOOTLOADER_UI_WAIT = 7;
- // Total time spend in bootloader. This is the sum of all BOOTLOADER_* listed above.
- // Logged from bootstat.
- BOOTLOADER_TOTAL = 8;
- // Shutdown duration inside init for the reboot before the current boot up.
- // Logged from f/b/services/.../BootReceiver.java.
- SHUTDOWN_DURATION = 9;
- // Total time for mounting of disk devices during bootup.
- // Logged from f/b/services/.../BootReceiver.java.
- MOUNT_DEFAULT_DURATION = 10;
- // Total time for early stage mounting of disk devices during bootup.
- // Logged from f/b/services/.../BootReceiver.java.
- MOUNT_EARLY_DURATION = 11;
- // Total time for late stage mounting of disk devices during bootup.
- // Logged from f/b/services/.../BootReceiver.java.
- MOUNT_LATE_DURATION = 12;
- // Average time to scan non-system app after OTA
- // Logged from f/b/services/.../PackageManagerService.java
- OTA_PACKAGE_MANAGER_INIT_TIME = 13;
- // Time to initialize Package manager after OTA
- // Logged from f/b/services/.../PackageManagerService.java
- OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME = 14;
- // Time to scan all system app from Package manager after OTA
- // Logged from f/b/services/.../PackageManagerService.java
- OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME = 15;
- // Init's total time for cold boot stage.
- // Logged from bootstat.
- COLDBOOT_WAIT = 16;
- // Init's total time for initializing selinux.
- // Logged from bootstat.
- SELINUX_INIT = 17;
- // Time since last factory reset.
- // Logged from bootstat.
- FACTORY_RESET_TIME_SINCE_RESET = 18;
- // Init's total time spent for completing the 1st stage.
- // Logged from bootstat.
- ANDROID_INIT_STAGE_1 = 19;
- }
-
- // Type of the event.
- optional DurationEvent event = 1;
- // Duration of the event in ms.
- optional int64 duration_millis = 2;
-}
-
-/**
- * Represents the start of specific boot time event during bootup in ms. This is usually a time
- * since boot-up.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventElapsedTime {
- enum ElapsedTimeEvent {
- UNKNOWN = 0;
- // Time when init starts 1st stage. Logged from bootstat.
- ANDROID_INIT_STAGE_1 = 1;
- // Time when sys.boot_completed prop is set.
- // Logged from bootstat.
- BOOT_COMPLETE = 2;
- // BOOT_COMPLETE for encrypted device.
- BOOT_COMPLETE_ENCRYPTION = 3;
- // BOOT_COMPLETE for device with no encryption.
- BOOT_COMPLETE_NO_ENCRYPTION = 4;
- // Adjusted BOOT_COMPLETE for encrypted device extracting decryption time.
- BOOT_COMPLETE_POST_DECRYPT = 5;
- // BOOT_COMPLETE after factory reset.
- FACTORY_RESET_BOOT_COMPLETE = 6;
- // BOOT_COMPLETE_NO_ENCRYPTION after factory reset.
- FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION = 7;
- // BOOT_COMPLETE_POST_DECRYPT after factory reset.
- FACTORY_RESET_BOOT_COMPLETE_POST_DECRYPT = 8;
- // BOOT_COMPLETE after OTA.
- OTA_BOOT_COMPLETE = 9;
- // BOOT_COMPLETE_NO_ENCRYPTION after OTA.
- OTA_BOOT_COMPLETE_NO_ENCRYPTION = 10;
- // BOOT_COMPLETE_POST_DECRYPT after OTA.
- OTA_BOOT_COMPLETE_POST_DECRYPT = 11;
- // Time when the system starts sending LOCKED_BOOT_COMPLETED broadcast.
- // Logged from f/b/services/.../UserController.java
- FRAMEWORK_LOCKED_BOOT_COMPLETED = 12;
- // Time when the system starts sending BOOT_COMPLETED broadcast.
- // Logged from f/b/services/.../UserController.java
- FRAMEWORK_BOOT_COMPLETED = 13;
- // Time when the package manager starts init.
- // Logged from f/b/services/.../SystemServer.java
- PACKAGE_MANAGER_INIT_START = 14;
- // Time when package manager is ready
- // Logged from f/b/services/.../SystemServer.java
- PACKAGE_MANAGER_INIT_READY = 15;
- // Represents the time when user has entered unlock credential for system with user pin.
- // Logged from bootstat.
- POST_DECRYPT = 16;
- // Represents the start of zygote's init.
- // Logged from zygote itself.
- ZYGOTE_INIT_START = 17;
- // Represents the start of secondary zygote's init.
- // TODO: add logging to zygote
- SECONDARY_ZYGOTE_INIT_START = 18;
- // Represents the start of system server's init.
- // Logged from f/b/services/.../SystemServer.java
- SYSTEM_SERVER_INIT_START = 19;
- // Represents the completion of system server's init.
- // Logged from f/b/services/.../SystemServer.java
- SYSTEM_SERVER_READY = 20;
- // Represents the start of launcher during boot-up.
- // TODO: add logging
- LAUNCHER_START = 21;
- // Represents the completion of launcher's initial rendering. User can use other apps from
- // launcher from this point.
- // TODO: add logging
- LAUNCHER_SHOWN = 22;
- }
-
- // Type of the event.
- optional ElapsedTimeEvent event = 1;
- // Time since bootup for the event.
- // It should be acquired from SystemClock elapsedRealtime() call or equivalent.
- optional int64 time_millis = 2;
-}
-
-/**
- * Boot time events with UTC time.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventUtcTime {
- enum UtcTimeEvent {
- UNKNOWN = 0;
- // Time of the bootstat's marking of 1st boot after the last factory reset.
- // Logged from bootstat.
- FACTORY_RESET_RESET_TIME = 1;
- // The time when bootstat records FACTORY_RESET_* events. This is close to
- // BOOT_COMPLETE time for the current bootup.
- // Logged from bootstat.
- FACTORY_RESET_CURRENT_TIME = 2;
- // DUplicate of FACTORY_RESET_RESET_TIME added for debugging purpose.
- // Logged from bootstat.
- FACTORY_RESET_RECORD_VALUE = 3;
- }
-
- // Type of the event.
- optional UtcTimeEvent event = 1;
- // UTC time for the event.
- optional int64 utc_time_secs = 2;
-}
-
-/**
- * Boot time events representing specific error code during bootup.
- * Meaning of error code can be different per each event type.
- *
- * Logged from: bootstat and various system server components. Check each enums for details.
- */
-message BootTimeEventErrorCode {
- enum ErrorCodeEvent {
- UNKNOWN = 0;
- // Linux error code for time() call to get the current UTC time.
- // Logged from bootstat.
- FACTORY_RESET_CURRENT_TIME_FAILURE = 1;
- // Represents UmountStat before the reboot for the current boot up. Error codes defined
- // as UMOUNT_STAT_* from init/reboot.cpp.
- // Logged from f/b/services/.../BootReceiver.java.
- SHUTDOWN_UMOUNT_STAT = 2;
- // Reprepsents fie system mounting error code of /data partition for the current boot.
- // Error codes defined as combination of FsStatFlags from system/core/fs_mgr/fs_mgr.cpp.
- // Logged from f/b/services/.../BootReceiver.java.
- FS_MGR_FS_STAT_DATA_PARTITION = 3;
- }
-
- // Type of the event.
- optional ErrorCodeEvent event = 1;
- // error code defined per each event type.
- // For example, this can have a value of FsStatFlags.FS_STAT_FULL_MOUNT_FAILED for the event of
- // FS_MGR_FS_STAT.
- optional int32 error_code = 2;
-}
-
-/**
- * Collects Virtual A/B statistics related to the use of dm-snapshot performed
- * after an OTA.
- *
- * Logged from:
- * - system/update_engine/cleanup_previous_update_action.cc
- */
-message SnapshotMergeReported {
- // Keep in sync with
- // system/core/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
- enum UpdateState {
- // No update or merge is in progress.
- NONE = 0;
- // An update is applying; snapshots may already exist.
- INITIATED = 1;
- // An update is pending, but has not been successfully booted yet.
- UNVERIFIED = 2;
- // The kernel is merging in the background.
- MERGING = 3;
- // Post-merge cleanup steps could not be completed due to a transient
- // error, but the next reboot will finish any pending operations.
- MERGE_NEEDS_REBOOT = 4;
- // Merging is complete, and needs to be acknowledged.
- MERGE_COMPLETED = 5;
- // Merging failed due to an unrecoverable error.
- MERGE_FAILED = 6;
- // The update was implicitly cancelled, either by a rollback or a flash
- // operation via fastboot. This state can only be returned by WaitForMerge.
- CANCELLED = 7;
- };
-
- // Status of the update after the merge attempts.
- optional UpdateState final_state = 1;
-
- // Time to complete a merge operation in milliseconds.
- // A negative value corresponds to the case in which the merge operation
- // was interrupted and resumed (e.g. in case of a system reboot during the
- // merge).
- optional int64 duration_millis = 2;
-
- // Number of reboots that occurred after issuing and before completing the
- // merge of all the snapshot devices.
- optional int32 intermediate_reboots = 3;
-
- // The device has been upgraded to Virtual A/B.
- optional bool is_vab_retrofit = 4;
-
- // Space that has been temporarily allocated in the /data partition
- // containing the dm-snapshot's copy-on-write data generated during a
- // Virtual A/B update.
- optional int64 cow_file_size_bytes = 5;
-}
-
-/**
- * Event representing when BlobStoreManager.Session#commit() is called
- *
- * Logged from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobCommitted {
- // Uid of the Blob committer
- optional int32 uid = 1 [(is_uid) = true];
-
- // Id of the Blob committed
- optional int64 blob_id = 2;
-
- // Size of the Blob
- optional int64 size = 3;
-
- enum Result {
- UNKNOWN = 0;
- // Commit Succeeded
- SUCCESS = 1;
- // Commit Failed: Error occurred during commit
- ERROR_DURING_COMMIT = 2;
- // Commit Failed: Digest of the data did not match Blob digest
- DIGEST_MISMATCH = 3;
- // Commit Failed: Allowed count limit exceeded
- COUNT_LIMIT_EXCEEDED = 4;
- }
- optional Result result = 4;
-}
-
-/**
- * Event representing when BlobStoreManager#acquireLease() is called
- *
- * Logged from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobLeased{
- // Uid of the Blob leasee
- optional int32 uid = 1 [(is_uid) = true];
-
- // Id of the Blob leased or 0 if the Blob does not exist
- optional int64 blob_id = 2;
-
- // Size of the Blob or 0 if the Blob does not exist
- optional int64 size = 3;
-
- enum Result {
- UNKNOWN = 0;
- // Lease Succeeded
- SUCCESS = 1;
- // Lease Failed: Blob does not exist
- BLOB_DNE = 2;
- // Lease Failed: Leasee does not have access to the Blob
- ACCESS_NOT_ALLOWED = 3;
- // Lease Failed: Leasee requested an invalid expiry duration
- LEASE_EXPIRY_INVALID = 4;
- // Lease Failed: Leasee has exceeded the total data lease limit
- DATA_SIZE_LIMIT_EXCEEDED = 5;
- // Leasee Failed: Allowed count limit exceeded
- COUNT_LIMIT_EXCEEDED = 6;
- }
- optional Result result = 4;
-}
-
-/**
- * Event representing when BlobStoreManager#openBlob() is called
- *
- * Logged from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobOpened{
- // Uid of the Blob opener
- optional int32 uid = 1 [(is_uid) = true];
-
- // Id of the Blob opened or 0 if the Blob does not exist
- optional int64 blob_id = 2;
-
- // Size of the Blob or 0 if the Blob does not exist
- optional int64 size = 3;
-
- enum Result {
- UNKNOWN = 0;
- // Open Succeeded
- SUCCESS = 1;
- // Open Failed: Blob does not exist
- BLOB_DNE = 2;
- // Open Failed: Opener does not have access to the Blob
- ACCESS_NOT_ALLOWED = 3;
- }
- optional Result result = 4;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Pulled atoms below this line //
-//////////////////////////////////////////////////////////////////////
-
-/**
- * Pulls bytes transferred via wifi (Sum of foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are wifi)
- */
-message WifiBytesTransfer {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-}
-
-/**
- * Pulls bytes transferred via wifi (separated by foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are wifi)
- */
-message WifiBytesTransferByFgBg {
- optional int32 uid = 1 [(is_uid) = true];
-
- // 1 denotes foreground and 0 denotes background. This is called Set in NetworkStats.
- optional bool is_foreground = 2;
-
- optional int64 rx_bytes = 3;
-
- optional int64 rx_packets = 4;
-
- optional int64 tx_bytes = 5;
-
- optional int64 tx_packets = 6;
-}
-
-/**
- * Pulls bytes transferred via mobile networks (Sum of foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
- */
-message MobileBytesTransfer {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-}
-
-/**
- * Pulls bytes transferred via mobile networks (separated by foreground and background usage).
- *
- * Pulled from:
- * StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
- */
-message MobileBytesTransferByFgBg {
- optional int32 uid = 1 [(is_uid) = true];
-
- // 1 denotes foreground and 0 denotes background. This is called Set in
- // NetworkStats.
- optional bool is_foreground = 2;
-
- optional int64 rx_bytes = 3;
-
- optional int64 rx_packets = 4;
-
- optional int64 tx_bytes = 5;
-
- optional int64 tx_packets = 6;
-}
-
-/**
- * Used for pull network statistics via mobile|wifi networks, and sliced by interesting dimensions.
- * Note that the data is expected to be sliced into more dimensions in future. In other words,
- * the caller must not assume any row of data is one full report when filtering with a set of
- * matching conditions, because future data may represent with multiple rows what is currently
- * represented by one.
- * To avoid being broken by future slicing, callers must take care to aggregate rows even if they
- * query all the existing columns.
- *
- * Pulled from:
- * StatsPullAtomService (using NetworkStatsService to get NetworkStats)
- */
-message DataUsageBytesTransfer {
- // State of this record. Should be NetworkStats#SET_DEFAULT or NetworkStats#SET_FOREGROUND to
- // indicate the foreground state, or NetworkStats#SET_ALL to indicate the record is for all
- // states combined, not including debug states. See NetworkStats#SET_*.
- optional int32 state = 1;
-
- optional int64 rx_bytes = 2;
-
- optional int64 rx_packets = 3;
-
- optional int64 tx_bytes = 4;
-
- optional int64 tx_packets = 5;
-
- // Radio Access Technology (RAT) type of this record, should be one of
- // TelephonyManager#NETWORK_TYPE_* constants, or NetworkTemplate#NETWORK_TYPE_ALL to indicate
- // the record is for all rat types combined.
- optional int32 rat_type = 6;
-
- // Mcc/Mnc read from sim if the record is for a specific subscription, null indicates the
- // record is combined across subscriptions.
- optional string sim_mcc = 7;
- optional string sim_mnc = 8;
-
- // Allows mobile virtual network operators (MVNOs) to be identified with individual IDs.
- // See TelephonyManager#getSimCarrierId.
- optional int32 carrier_id = 9;
-
- // Enumeration of opportunistic states with an additional ALL state indicates the record is
- // combined regardless of the boolean value in its field.
- enum DataSubscriptionState {
- UNKNOWN = 0; // For server side backward compatibility.
- ALL = 1;
- OPPORTUNISTIC = 2;
- NOT_OPPORTUNISTIC = 3;
- }
- // Mark whether the subscription is an opportunistic data subscription, and ALL indicates the
- // record is combined across opportunistic data subscriptions.
- // See {@link SubscriptionManager#setOpportunistic}.
- optional DataSubscriptionState opportunistic_data_sub = 10;
-
- // Indicate whether NR is connected, server side could use this with RAT type to determine if
- // the record is for 5G NSA (Non Stand Alone) mode, where the primary cell is still LTE and
- // network allocates a secondary 5G cell so telephony reports RAT = LTE along with NR state as
- // connected.
- optional bool is_nr_connected = 11;
-}
-
-/**
- * Pulls bytes transferred via bluetooth. It is pulled from Bluetooth controller.
- *
- * Pulled from:
- * StatsCompanionService
- */
-message BluetoothBytesTransfer {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional int64 rx_bytes = 2;
-
- optional int64 tx_bytes = 3;
-}
-
-/**
- * Pulls the kernel wakelock durations. This atom is adapted from
- * android/internal/os/KernelWakelockStats.java
- *
- * Pulled from:
- * StatsCompanionService using KernelWakelockReader.
- */
-message KernelWakelock {
- optional string name = 1;
-
- optional int32 count = 2;
-
- optional int32 version = 3;
-
- optional int64 time_micros = 4;
-}
-
-/**
- * Pulls low power state information. If power.stats HAL is not available, this
- * includes platform and subsystem sleep state information,
- * PowerStatePlatformSleepState, PowerStateVoter or PowerStateSubsystemSleepState
- * as defined in:
- * hardware/interfaces/power/1.0/types.hal
- * hardware/interfaces/power/1.1/types.hal
- * If power.stats HAL is available, this includes PowerEntityStateResidencyResult
- * as defined in:
- * hardware/interfaces/power/stats/1.0/types.hal
- */
-message SubsystemSleepState {
- // Subsystem name
- optional string subsystem_name = 1;
- // For PlatformLowPowerStats (hal 1.0), this is the voter name, which could be empty.
- // For SubsystemLowPowerStats (hal 1.1), this is the sleep state name.
- // For PowerEntityStateResidencyResult (hal power/stats/1.0) this is the
- // powerEntityStateName from the corresponding PowerEntityStateInfo.
- optional string subname = 2;
- // The number of times it entered, or voted for entering the sleep state
- optional uint64 count = 3;
- // The length of time spent in, or spent voting for, the sleep state
- optional uint64 time_millis = 4;
-}
-
-/**
- * Pulls on-device power measurement information.
- * Data defined by hardware/interfaces/power/stats/1.0/types.hal.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/PowerStatsPuller.cpp
- */
-message OnDevicePowerMeasurement {
- // Name of the subsystem (to which the rail belongs).
- optional string subsystem_name = 1;
-
- // Rail name. The rail lies within the subsystem.
- optional string rail_name = 2;
-
- // Time (in ms since boot) at which the rail energy value was measured.
- // This may differ slightly from the time that statsd logs this information.
- optional uint64 measurement_timestamp_millis = 3;
-
- // Accumulated energy used via the rail since device boot in uWs.
- optional uint64 energy_microwatt_secs = 4;
-}
-
-/**
- * Pulls Cpu time per frequency.
- * Pulls the time the cpu spend on the frequency index. Frequency index
- * starts from highest to lowest. The value should be monotonically
- * increasing since boot. However, if there is a cpu
- * hotplug event, the value would be reset as well.
- */
-message CpuTimePerFreq {
- optional uint32 cluster = 1;
- optional uint32 freq_index = 2;
- optional uint64 time_millis = 3;
-}
-
-/**
- * Pulls Cpu Time Per Uid.
- * Note that isolated process uid time should be attributed to host uids.
- */
-message CpuTimePerUid {
- optional int32 uid = 1 [(is_uid) = true];
- optional uint64 user_time_micros = 2;
- optional uint64 sys_time_micros = 3;
-}
-
-/**
- * Pulls Cpu Time Per Uid per frequency.
- * Note that isolated process uid time should be attributed to host uids.
- * For each uid, we order the time by descending frequencies.
- */
-message CpuTimePerUidFreq {
- optional int32 uid = 1 [(is_uid) = true];
- optional uint32 freq_index = 2;
- optional uint64 time_millis = 3;
-}
-
-/**
- * Pulls Wifi Controller Activity Energy Info
- */
-message WifiActivityInfo {
- // timestamp(wall clock) of record creation
- optional uint64 timestamp_millis = 1;
- // stack reported state
- // TODO: replace this with proto enum
- optional int32 stack_state = 2;
- // tx time in millis
- optional uint64 controller_tx_time_millis = 3;
- // rx time in millis
- optional uint64 controller_rx_time_millis = 4;
- // idle time in millis
- optional uint64 controller_idle_time_millis = 5;
- // product of current(mA), voltage(V) and time(ms)
- optional uint64 controller_energy_used = 6;
-}
-
-/**
- * Pulls Modem Activity Energy Info
- */
-message ModemActivityInfo {
- // timestamp(wall clock) of record creation
- optional uint64 timestamp_millis = 1;
- // sleep time in millis.
- optional uint64 sleep_time_millis = 2;
- // idle time in millis
- optional uint64 controller_idle_time_millis = 3;
- /**
- * Tx power index
- * index 0 = tx_power < 0dBm
- * index 1 = 0dBm < tx_power < 5dBm
- * index 2 = 5dBm < tx_power < 15dBm
- * index 3 = 15dBm < tx_power < 20dBm
- * index 4 = tx_power > 20dBm
- */
- // tx time in ms at power level 0
- optional uint64 controller_tx_time_pl0_millis = 4;
- // tx time in ms at power level 1
- optional uint64 controller_tx_time_pl1_millis = 5;
- // tx time in ms at power level 2
- optional uint64 controller_tx_time_pl2_millis = 6;
- // tx time in ms at power level 3
- optional uint64 controller_tx_time_pl3_millis = 7;
- // tx time in ms at power level 4
- optional uint64 controller_tx_time_pl4_millis = 8;
- // rx time in ms at power level 5
- optional uint64 controller_rx_time_millis = 9;
- // product of current(mA), voltage(V) and time(ms)
- optional uint64 energy_used = 10 [deprecated=true];
-}
-
-/**
- * Pulls Bluetooth Activity Energy Info
- * Note: BluetoothBytesTransfer is pulled at the same time from the controller.
- */
-message BluetoothActivityInfo {
- // timestamp(wall clock) of record creation
- optional uint64 timestamp_millis = 1;
- // bluetooth stack state
- optional int32 bluetooth_stack_state = 2;
- // tx time in millis
- optional uint64 controller_tx_time_millis = 3;
- // rx time in millis
- optional uint64 controller_rx_time_millis = 4;
- // idle time in millis
- optional uint64 controller_idle_time_millis = 5;
- // product of current(mA), voltage(V) and time(ms)
- optional uint64 energy_used = 6;
-}
-
-/*
- * Logs the memory stats for a process.
- *
- * Pulled from StatsCompanionService for all managed processes (from ActivityManagerService).
- */
-message ProcessMemoryState {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- // Usually package name, "system" for system server.
- // Provided by ActivityManagerService.
- optional string process_name = 2;
-
- // Current OOM score adjustment. Value read from ProcessRecord.
- optional int32 oom_adj_score = 3;
-
- // # of page-faults
- optional int64 page_fault = 4;
-
- // # of major page-faults
- optional int64 page_major_fault = 5;
-
- // RSS
- // Value is read from memory.stat, field total_rss if per-app memory
- // cgroups are enabled. Otherwise, value from /proc/pid/stat.
- optional int64 rss_in_bytes = 6;
-
- // CACHE
- // Value is read from memory.stat, field total_cache if per-app memory
- // cgroups are enabled. Otherwise, 0.
- optional int64 cache_in_bytes = 7;
-
- // SWAP
- // Value is read from memory.stat, field total_swap if per-app memory
- // cgroups are enabled. Otherwise, 0.
- optional int64 swap_in_bytes = 8;
-
- // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always -1.
- optional int64 rss_high_watermark_in_bytes = 9 [deprecated = true];
-
- // Deprecated: use ProcessMemorySnapshot atom instead. Always -1.
- optional int64 start_time_nanos = 10 [deprecated = true];
-
- // Deprecated: use ProcessMemorySnapshot atom instead. Always -1.
- optional int32 anon_rss_and_swap_in_kilobytes = 11 [deprecated = true];
-}
-
-/*
- * Logs the memory high-water mark for a process.
- *
- * Pulled from StatsCompanionService for all managed processes (from ActivityManagerServie)
- * and for selected native processes.
- *
- * Pulling this atom resets high-water mark counters for all processes.
- */
-message ProcessMemoryHighWaterMark {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- // Usually package name or process cmdline.
- // Provided by ActivityManagerService or read from /proc/PID/cmdline.
- optional string process_name = 2;
-
- // Deprecated: use rss_high_water_mark_in_kilobytes instead. This field is
- // computed by converting kilobytes to bytes.
- optional int64 rss_high_water_mark_in_bytes = 3 [deprecated = true];
-
- // RSS high-water mark. Peak RSS usage of the process. Read from the VmHWM field in
- // /proc/PID/status.
- optional int32 rss_high_water_mark_in_kilobytes = 4;
-}
-
-/*
- * Logs the memory stats for a process.
- *
- * Pulled from StatsCompanionService for all managed processes (from ActivityManagerService)
- * and for selected native processes.
- */
-message ProcessMemorySnapshot {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name.
- // Usually package name or process cmdline.
- // Provided by ActivityManagerService or read from /proc/PID/cmdline.
- optional string process_name = 2;
-
- // The pid of the process.
- // Allows to disambiguate instances of the process.
- optional int32 pid = 3;
-
- // The current OOM score adjustment value.
- // Read from ProcessRecord for managed processes.
- // Placeholder -1001 (OOM_SCORE_ADJ_MIN - 1, outside of allowed range) for native ones.
- optional int32 oom_score_adj = 4;
-
- // The current RSS of the process.
- // VmRSS from /proc/pid/status.
- optional int32 rss_in_kilobytes = 5;
-
- // The current anon RSS of the process.
- // RssAnon from /proc/pid/status.
- optional int32 anon_rss_in_kilobytes = 6;
-
- // The current swap size of the process.
- // VmSwap from /proc/pid/status.
- optional int32 swap_in_kilobytes = 7;
-
- // The sum of rss_in_kilobytes and swap_in_kilobytes.
- optional int32 anon_rss_and_swap_in_kilobytes = 8;
-}
-
-/*
- * Elapsed real time from SystemClock.
- */
-message SystemElapsedRealtime {
- optional uint64 time_millis = 1;
-}
-
-/*
- * Up time from SystemClock.
- */
-message SystemUptime {
- // Milliseconds since the system was booted.
- // This clock stops when the system enters deep sleep (CPU off, display dark, device waiting
- // for external input).
- // It is not affected by clock scaling, idle, or other power saving mechanisms.
- optional uint64 uptime_millis = 1;
-}
-
-/*
- * Reads from /proc/uid_concurrent_active_time which has the format:
- * active: X (X is # cores)
- * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores)
- * [uid1]: [time-0] [time-1] [time-2] ... ...
- * ...
- * Time-N means the CPU time a UID spent running concurrently with N other processes.
- * The file contains a monotonically increasing count of time for a single boot.
- */
-message CpuActiveTime {
- optional int32 uid = 1 [(is_uid) = true];
- optional uint64 time_millis = 2;
-}
-
-/**
- * Reads from /proc/uid_concurrent_policy_time which has the format:
- * policy0: X policy4: Y (there are X cores on policy0, Y cores on policy4)
- * [uid0]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ...
- * [uid1]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ...
- * ...
- * Time-X-Y means the time a UID spent on clusterX running concurrently with Y other processes.
- * The file contains a monotonically increasing count of time for a single boot.
- */
-message CpuClusterTime {
- optional int32 uid = 1 [(is_uid) = true];
- optional int32 cluster_index = 2;
- optional uint64 time_millis = 3;
-}
-
-/*
- * Pulls free disk space, for data, system partition and temporary directory.
- */
-message DiskSpace {
- // available bytes in data partition
- optional uint64 data_available_bytes = 1;
- // available bytes in system partition
- optional uint64 system_available_bytes = 2;
- // available bytes in download cache or temp directories
- optional uint64 temp_available_bytes = 3;
-}
-
-/**
- * Pulls battery coulomb counter, which is the remaining battery charge in uAh.
- *
- * Pulled from StatsCompanionService.java
- */
-message RemainingBatteryCapacity {
- optional int32 charge_micro_ampere_hour = 1;
-}
-
-/**
- * Pulls battery capacity, which is the battery capacity when full in uAh.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message FullBatteryCapacity {
- optional int32 capacity_micro_ampere_hour = 1;
-}
-
-/**
- * Pulls battery voltage.
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message BatteryVoltage {
- // The voltage of the battery, in millivolts.
- optional int32 voltage_millivolt = 1;
-}
-
-/**
- * Pulls battery level (percent full, from 0 to 100).
- *
- * Pulled from:
- * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
- */
-message BatteryLevel {
- // Battery level. Should be in [0, 100].
- optional int32 battery_level = 1;
-}
-
-/**
- * Pulls the temperature of various parts of the device.
- * The units are tenths of a degree Celsius. Eg: 30.3C is reported as 303.
- *
- * Pulled from StatsCompanionService.java
- */
-message Temperature {
- // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY, BCL_.
- optional android.os.TemperatureTypeEnum sensor_location = 1;
-
- // The name of the temperature source. Eg. CPU0
- optional string sensor_name = 2;
-
- // Temperature in tenths of a degree C.
- // For BCL, it is decimillivolt, decimilliamps, and percentage * 10.
- optional int32 temperature_deci_celsius = 3;
-
- // Relative severity of the throttling, see enum definition.
- optional android.os.ThrottlingSeverityEnum severity = 4;
-}
-
-/**
- * Pulls the statistics of calls to Binder.
- *
- * Binder stats will be reset every time the data is pulled. It means it can only be pulled by one
- * config on the device.
- *
- * Next tag: 15
- */
-message BinderCalls {
- // UID of the process responsible for the binder transaction. It will be set if the process
- // executing the binder transaction attribute the transaction to another uid using
- // Binder.setThreadWorkSource().
- //
- // If not set, the value will be -1.
- optional int32 uid = 1 [(is_uid) = true];
- // UID of the process executing the binder transaction.
- optional int32 direct_caller_uid = 14;
- // Fully qualified class name of the API call.
- //
- // This is a system server class name.
- //
- // TODO(gaillard): figure out if binder call stats includes data from isolated uids, if a uid
- // gets recycled and we have isolated uids, we might attribute the data incorrectly.
- // TODO(gaillard): there is a high dimensions cardinality, figure out if we should drop the less
- // commonly used APIs.
- optional string service_class_name = 2;
- // Method name of the API call. It can also be a transaction code if we cannot
- // resolve it to a name. See Binder#getTransactionName.
- //
- // This is a system server method name.
- optional string service_method_name = 3;
- // Total number of API calls.
- optional int64 call_count = 4;
- // True if the screen was interactive PowerManager#isInteractive at the end of the call.
- optional bool screen_interactive = 13;
- // Total number of API calls we have data recorded for. If we collected data for all the calls,
- // call_count will be equal to recorded_call_count.
- //
- // If recorded_call_count is different than call_count, it means data collection has been
- // sampled. All the fields below will be sampled in this case.
- optional int64 recorded_call_count = 12;
- // Number of exceptions thrown by the API.
- optional int64 recorded_exception_count = 5;
- // Total latency of all API calls.
- // Average can be computed using total_latency_micros / recorded_call_count.
- optional int64 recorded_total_latency_micros = 6;
- // Maximum latency of one API call.
- optional int64 recorded_max_latency_micros = 7;
- // Total CPU usage of all API calls.
- // Average can be computed using total_cpu_micros / recorded_call_count.
- // Total can be computed using total_cpu_micros / recorded_call_count * call_count.
- optional int64 recorded_total_cpu_micros = 8;
- // Maximum CPU usage of one API call.
- optional int64 recorded_max_cpu_micros = 9;
- // Maximum parcel reply size of one API call.
- optional int64 recorded_max_reply_size_bytes = 10;
- // Maximum parcel request size of one API call.
- optional int64 recorded_max_request_size_bytes = 11;
-}
-
-/**
- * Pulls the statistics of exceptions during calls to Binder.
- *
- * Binder stats are cumulative from boot unless somebody reset the data using
- * > adb shell dumpsys binder_calls_stats --reset
- */
-message BinderCallsExceptions {
- // Exception class name, e.g. java.lang.IllegalArgumentException.
- //
- // This is an exception class name thrown by the system server.
- optional string exception_class_name = 1;
- // Total number of exceptions.
- optional int64 exception_count = 2;
-}
-
-/**
- * Pulls the statistics of message dispatching on HandlerThreads.
- *
- * Looper stats will be reset every time the data is pulled. It means it can only be pulled by one
- * config on the device.
- *
- * Next tag: 11
- */
-message LooperStats {
- // The uid that made a call to the System Server and caused the message to be enqueued.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Fully qualified class name of the handler target class.
- //
- // This field does not contain PII. This is a system server class name.
- optional string handler_class_name = 2;
-
- // The name of the thread that runs the Looper.
- //
- // This field does not contain PII. This is a system server thread name.
- optional string looper_thread_name = 3;
-
- // The name of the dispatched message.
- //
- // This field does not contain PII. This is a system server constant or class
- // name.
- optional string message_name = 4;
-
- // Total number of successfully dispatched messages.
- optional int64 message_count = 5;
-
- // Total number of messages that failed dispatching.
- optional int64 exception_count = 6;
-
- // Total number of processed messages we have data recorded for. If we
- // collected data for all the messages, message_count will be equal to
- // recorded_message_count.
- //
- // If recorded_message_count is different than message_count, it means data
- // collection has been sampled. The fields below will be sampled in this case.
- optional int64 recorded_message_count = 7;
-
- // Total latency of all processed messages.
- // Average can be computed using recorded_total_latency_micros /
- // recorded_message_count.
- optional int64 recorded_total_latency_micros = 8;
-
- // Total CPU usage of all processed message.
- // Average can be computed using recorded_total_cpu_micros /
- // recorded_message_count. Total can be computed using
- // recorded_total_cpu_micros / recorded_message_count * message_count.
- optional int64 recorded_total_cpu_micros = 9;
-
- // True if the screen was interactive PowerManager#isInteractive at the end of the call.
- optional bool screen_interactive = 10;
-
- // Max recorded CPU usage of all processed messages.
- optional int64 recorded_max_cpu_micros = 11;
-
- // Max recorded latency of all processed messages.
- optional int64 recorded_max_latency_micros = 12;
-
- // Total number of messages we tracked the dispatching delay for. If we
- // collected data for all the messages, message_count will be equal to
- // recorded_delay_message_count.
- //
- // If recorded_delay_message_count is different than message_count, it means data
- // collection has been sampled or/and not all messages specified the target dispatch time.
- // The fields below will be sampled in this case.
- optional int64 recorded_delay_message_count = 13;
-
- // Total dispatching delay of all processed messages.
- // Calculated as a difference between the target dispatching time (Message.when)
- // and the actual dispatching time.
- // Average can be computed using recorded_total_delay_millis / recorded_delay_message_count.
- optional int64 recorded_total_delay_millis = 14;
-
- // Max dispatching delay of all processed messages.
- // Calculated as a difference between the target dispatching time (Message.when)
- // and the actual dispatching time.
- optional int64 recorded_max_delay_millis = 15;
-}
-
-/**
- * Pulls disk information, such as write speed and latency.
- */
-message DiskStats {
- // Time taken to open, write 512B to, and close a file.
- // -1 if error performing the check.
- optional int64 data_write_latency_millis = 1;
-
- optional bool file_based_encryption = 2;
-
- // Recent disk write speed in kB/s.
- // -1 if error querying storageed.
- // 0 if data is unavailable.
- optional int32 recent_disk_write_speed = 3;
-}
-
-
-/**
- * Free and total bytes of the Data, Cache, and System partition.
- */
-message DirectoryUsage {
- enum Directory {
- UNKNOWN = 0;
- DATA = 1;
- CACHE = 2;
- SYSTEM = 3;
- }
- optional Directory directory = 1;
- optional int64 free_bytes = 2;
- optional int64 total_bytes = 3;
-}
-
-
-/**
- * Size of an application: apk size, data size, and cache size.
- * Reads from a cached file produced daily by DiskStatsLoggingService.java.
- * Information is only reported for apps with the primary user (user 0).
- * Sizes are aggregated by package name.
- */
-message AppSize {
- // Including uids will involve modifying diskstats logic.
- optional string package_name = 1;
- // App size in bytes. -1 if unavailable.
- optional int64 app_size_bytes = 2;
- // App data size in bytes. -1 if unavailable.
- optional int64 app_data_size_bytes = 3;
- // App cache size in bytes. -1 if unavailable.
- optional int64 app_cache_size_bytes = 4;
- // Time that the cache file was produced.
- // Uses System.currentTimeMillis(), which is wall clock time.
- optional int64 cache_time_millis = 5;
-}
-
-
-/**
- * Size of a particular category. Eg: photos, videos.
- * Reads from a cached file produced daily by DiskStatsLoggingService.java.
- */
-message CategorySize {
- enum Category {
- UNKNOWN = 0;
- APP_SIZE = 1;
- APP_DATA_SIZE = 2;
- APP_CACHE_SIZE = 3;
- PHOTOS = 4;
- VIDEOS = 5;
- AUDIO = 6;
- DOWNLOADS = 7;
- SYSTEM = 8;
- OTHER = 9;
- }
- optional Category category = 1;
- // Category size in bytes.
- optional int64 size_bytes = 2;
- // Time that the cache file was produced.
- // Uses System.currentTimeMillis(), which is wall clock time.
- optional int64 cache_time_millis = 3;
-}
-
-/**
- * Pulls per uid I/O stats. The stats are cumulative since boot.
- *
- * Read/write bytes are I/O events from a storage device
- * Read/write chars are data requested by read/write syscalls, and can be
- * satisfied by caching.
- *
- * Pulled from StatsCompanionService, which reads proc/uid_io/stats.
- */
-message DiskIo {
- optional int32 uid = 1 [(is_uid) = true];
- optional int64 fg_chars_read = 2;
- optional int64 fg_chars_write = 3;
- optional int64 fg_bytes_read = 4;
- optional int64 fg_bytes_write = 5;
- optional int64 bg_chars_read = 6;
- optional int64 bg_chars_write = 7;
- optional int64 bg_bytes_read = 8;
- optional int64 bg_bytes_write = 9;
- optional int64 fg_fsync = 10;
- optional int64 bg_fsync= 11;
-}
-
-
-/**
- * Pulls the number of fingerprints for each user.
- *
- * Pulled from StatsCompanionService, which queries <Biometric>Manager.
- */
-message NumFingerprintsEnrolled {
- // The associated user. Eg: 0 for owners, 10+ for others.
- // Defined in android/os/UserHandle.java
- optional int32 user = 1;
- // Number of fingerprints registered to that user.
- optional int32 num_fingerprints_enrolled = 2;
-}
-
-/**
- * Pulls the number of faces for each user.
- *
- * Pulled from StatsCompanionService, which queries <Biometric>Manager.
- */
-message NumFacesEnrolled {
- // The associated user. Eg: 0 for owners, 10+ for others.
- // Defined in android/os/UserHandle.java
- optional int32 user = 1;
- // Number of faces registered to that user.
- optional int32 num_faces_enrolled = 2;
-}
-/**
- * A mapping of role holder -> role
- */
-message RoleHolder {
- // uid of the role holder
- optional int32 uid = 1 [(is_uid) = true];
-
- // package name of the role holder
- optional string package_name = 2;
-
- // the role held
- optional string role = 3;
-}
-
-message AggStats {
- // These are all in byte resolution.
- optional int64 min = 1 [deprecated = true];
- optional int64 average = 2 [deprecated = true];
- optional int64 max = 3 [deprecated = true];
-
- // These are all in kilobyte resolution. Can fit in int32, so smaller on the wire than the above
- // int64 fields.
- optional int32 mean_kb = 4;
- optional int32 max_kb = 5;
-}
-
-// A reduced subset of process states; reducing the number of possible states allows more
-// aggressive device-side aggregation of statistics and hence reduces metric upload size.
-enum ProcessStateAggregated {
- PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process.
- PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity.
- PROCESS_STATE_TOP = 2;
- // Process binding to top or a foreground service.
- PROCESS_STATE_BOUND_TOP_OR_FGS = 3;
- // Processing running a foreground service.
- PROCESS_STATE_FGS = 4;
- // Important foreground process (ime, wallpaper, etc).
- PROCESS_STATE_IMPORTANT_FOREGROUND = 5;
- // Important background process.
- PROCESS_STATE_BACKGROUND = 6;
- // Process running a receiver.
- PROCESS_STATE_RECEIVER = 7;
- // All kinds of cached processes.
- PROCESS_STATE_CACHED = 8;
-}
-
-// Next tag: 13
-message ProcessStatsStateProto {
- optional android.service.procstats.ScreenState screen_state = 1;
-
- optional android.service.procstats.MemoryState memory_state = 2 [deprecated = true];
-
- // this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
- // and not frameworks/base/core/java/android/app/ActivityManager.java
- optional android.service.procstats.ProcessState process_state = 3 [deprecated = true];
-
- optional ProcessStateAggregated process_state_aggregated = 10;
-
- // Millisecond uptime duration spent in this state
- optional int64 duration_millis = 4 [deprecated = true];
- // Same as above, but with minute resolution so it fits into an int32.
- optional int32 duration_minutes = 11;
-
- // Millisecond elapsed realtime duration spent in this state
- optional int64 realtime_duration_millis = 9 [deprecated = true];
- // Same as above, but with minute resolution so it fits into an int32.
- optional int32 realtime_duration_minutes = 12;
-
- // # of samples taken
- optional int32 sample_size = 5;
-
- // PSS is memory reserved for this process
- optional AggStats pss = 6 [deprecated = true];
-
- // USS is memory shared between processes, divided evenly for accounting
- optional AggStats uss = 7 [deprecated = true];
-
- // RSS is memory resident for this process
- optional AggStats rss = 8;
-}
-
-// Next Tag: 8
-message ProcessStatsProto {
- // Name of process.
- optional string process = 1;
-
- // Uid of the process.
- optional int32 uid = 2 [(is_uid) = true];
-
- // Information about how often kills occurred
- message Kill {
- // Count of excessive CPU kills
- optional int32 cpu = 1;
-
- // Count of kills when cached
- optional int32 cached = 2;
-
- // PSS stats during cached kill
- optional AggStats cached_pss = 3;
- }
- optional Kill kill = 3 [deprecated = true];
-
- // Time and memory spent in various states.
- repeated ProcessStatsStateProto states = 5;
-
- // Total time process has been running... screen_state, memory_state, and process_state
- // will not be set.
- optional ProcessStatsStateProto total_running_state = 6;
-
- // Association data for this process in this state;
- // each entry here is one association.
- repeated ProcessStatsAssociationProto assocs = 7;
-}
-
-// Next Tag: 6
-message ProcessStatsAssociationProto {
- // Procss Name of the associated process (client process of service binding)
- optional string assoc_process_name = 1;
-
- // Package Name of the associated package (client package of service binding)
- optional string assoc_package_name = 2 [deprecated = true];
-
- // UID of the associated process/package (client package of service binding)
- optional int32 assoc_uid = 5 [(is_uid) = true];
-
- // Total count of the times this association (service binding) appeared.
- optional int32 total_count = 3;
-
- // Uptime total duration in seconds this association (service binding) was around.
- optional int32 total_duration_secs = 4;
-}
-
-message PackageServiceOperationStatsProto {
- // Operate enum: Started, Foreground, Bound, Executing
- optional android.service.procstats.ServiceOperationState operation = 1;
-
- // Number of times the service was in this operation.
- optional int32 count = 2;
-
- // Information about a state the service can be in.
- message StateStats {
- // Screen state enum.
- optional android.service.procstats.ScreenState screen_state = 1;
- // Memory state enum.
- optional android.service.procstats.MemoryState memory_state = 2;
-
- // duration in milliseconds.
- optional int64 duration_millis = 3;
- // Millisecond elapsed realtime duration spent in this state
- optional int64 realtime_duration_millis = 4;
- }
- repeated StateStats state_stats = 3;
-}
-
-message PackageServiceStatsProto {
- // Name of service component.
- optional string service_name = 1;
-
- // The operation stats.
- // The package_name, package_uid, package_version, service_name will not be set to save space.
- repeated PackageServiceOperationStatsProto operation_stats = 2;
-}
-
-message PackageAssociationSourceProcessStatsProto {
- // Uid of the process.
- optional int32 process_uid = 1;
- // Process name.
- optional string process_name = 2;
- // Package name.
- optional string package_name = 7;
- // Total count of the times this association appeared.
- optional int32 total_count = 3;
-
- // Millisecond uptime total duration this association was around.
- optional int64 total_duration_millis = 4;
-
- // Total count of the times this association became actively impacting its target process.
- optional int32 active_count = 5;
-
- // Information on one source in this association.
- message StateStats {
- // Process state enum.
- optional android.service.procstats.ProcessState process_state = 1;
- // Millisecond uptime duration spent in this state
- optional int64 duration_millis = 2;
- // Millisecond elapsed realtime duration spent in this state
- optional int64 realtime_duration_mmillis = 3;
- }
- repeated StateStats active_state_stats = 6;
-}
-
-message PackageAssociationProcessStatsProto {
- // Name of the target component.
- optional string component_name = 1;
- // Information on one source in this association.
- repeated PackageAssociationSourceProcessStatsProto sources = 2;
-}
-
-
-message ProcessStatsPackageProto {
- // Name of package.
- optional string package = 1;
-
- // Uid of the package.
- optional int32 uid = 2;
-
- // Version of the package.
- optional int64 version = 3;
-
- // Stats for each process running with the package loaded in to it.
- repeated ProcessStatsProto process_stats = 4;
-
- // Stats for each of the package's services.
- repeated PackageServiceStatsProto service_stats = 5;
-
- // Stats for each association with the package.
- repeated PackageAssociationProcessStatsProto association_stats = 6;
-}
-
-message ProcessStatsSectionProto {
- // Elapsed realtime at start of report.
- optional int64 start_realtime_millis = 1;
-
- // Elapsed realtime at end of report.
- optional int64 end_realtime_millis = 2;
-
- // CPU uptime at start of report.
- optional int64 start_uptime_millis = 3;
-
- // CPU uptime at end of report.
- optional int64 end_uptime_millis = 4;
-
- // System runtime library. e.g. "libdvm.so", "libart.so".
- optional string runtime = 5;
-
- // whether kernel reports swapped pss.
- optional bool has_swapped_pss = 6;
-
- // Data completeness. e.g. "complete", "partial", shutdown", or "sysprops".
- enum Status {
- STATUS_UNKNOWN = 0;
- STATUS_COMPLETE = 1;
- STATUS_PARTIAL = 2;
- STATUS_SHUTDOWN = 3;
- STATUS_SYSPROPS = 4;
- }
- repeated Status status = 7;
-
- // Number of pages available of various types and sizes, representation fragmentation.
- repeated ProcessStatsAvailablePagesProto available_pages = 10;
-
- // Stats for each process.
- repeated ProcessStatsProto process_stats = 8;
-
- // Stats for each package.
- repeated ProcessStatsPackageProto package_stats = 9;
-}
-
-message ProcessStatsAvailablePagesProto {
- // Node these pages are in (as per /proc/pagetypeinfo)
- optional int32 node = 1;
-
- // Zone these pages are in (as per /proc/pagetypeinfo)
- optional string zone = 2;
-
- // Label for the type of these pages (as per /proc/pagetypeinfo)
- optional string label = 3;
-
- // Distribution of number of pages available by order size. First entry in array is
- // order 0, second is order 1, etc. Each order increase is a doubling of page size.
- repeated int32 pages_per_order = 4;
-}
-
-/**
- * Pulled from ProcessStatsService.java
- */
-message ProcStats {
- optional ProcessStatsSectionProto proc_stats_section = 1;
- // Data pulled from device into this is sometimes sharded across multiple atoms to work around
- // a size limit. When this happens, this shard ID will contain an increasing 1-indexed integer
- // with the number of this shard.
- optional int32 shard_id = 2;
-}
-
-/**
- * Pulled from ProcessStatsService.java
- */
-message ProcStatsPkgProc {
- optional ProcessStatsSectionProto proc_stats_section = 1;
-}
-
-// Next Tag: 2
-message PackageRemoteViewInfoProto {
- optional string package_name = 1;
- // add per-package additional info here (like channels)
-}
-
-// Next Tag: 2
-message NotificationRemoteViewsProto {
- repeated PackageRemoteViewInfoProto package_remote_view_info = 1;
-}
-
-/**
- * Pulled from NotificationManagerService.java
- */
-message NotificationRemoteViews {
- optional NotificationRemoteViewsProto notification_remote_views = 1;
-}
-
-/**
- * Atom that contains a list of a package's preferences, pulled from NotificationManagerService.java
- */
-message PackageNotificationPreferences {
- // Uid under which the package is installed.
- optional int32 uid = 1 [(is_uid) = true];
- // Notification importance, which specifies when and how a notification is displayed.
- // Specified under core/java/android/app/NotificationManager.java.
- optional int32 importance = 2;
- // Lockscreen visibility as set by the user.
- optional int32 visibility = 3;
- // Bitfield mask indicating what fields were locked by the user (see LockableAppfields in
- // PreferencesHelper.java)
- optional int32 user_locked_fields = 4;
-}
-
-/**
- * Atom that contains a list of a package's channel preferences, pulled from
- * NotificationManagerService.java.
- */
-message PackageNotificationChannelPreferences {
- // Uid under which the package is installed.
- optional int32 uid = 1 [(is_uid) = true];
- // Channel's ID. Should always be available.
- optional string channel_id = 2;
- // Channel's name. Should always be available.
- optional string channel_name = 3;
- // Channel's description. Optionally set by the channel creator.
- optional string description = 4;
- // Notification importance, which specifies when and how a notification is displayed. Specified
- // under core/java/android/app/NotificationManager.java.
- optional int32 importance = 5;
- // Bitmask representing which fields have been set by the user. See field bitmask descriptions
- // at core/java/android/app/NotificationChannel.java
- optional int32 user_locked_fields = 6;
- // Indicates if the channel was deleted by the app.
- optional bool is_deleted = 7;
- // Indicates if the channel was marked as a conversation by the app.
- optional bool is_conversation = 8;
- // Indicates if the channel is a conversation that was demoted by the user.
- optional bool is_demoted_conversation = 9;
- // Indicates if the channel is a conversation that was marked as important by the user.
- optional bool is_important_conversation = 10;
-}
-
-/**
- * Atom that represents an item in the list of Do Not Disturb rules, pulled from
- * NotificationManagerService.java.
- */
-message DNDModeProto {
- enum Mode {
- ROOT_CONFIG = -1; // Used to distinguish the config (one per user) from the rules.
- ZEN_MODE_OFF = 0;
- ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1;
- ZEN_MODE_NO_INTERRUPTIONS = 2;
- ZEN_MODE_ALARMS = 3;
- }
- optional int32 user = 1; // Android user ID (0, 1, 10, ...)
- optional bool enabled = 2; // true for ROOT_CONFIG if a manualRule is enabled
- optional bool channels_bypassing = 3; // only valid for ROOT_CONFIG
- optional Mode zen_mode = 4;
- // id is one of the system default rule IDs, or empty
- // May also be "MANUAL_RULE" to indicate app-activation of the manual rule.
- optional string id = 5;
- optional int32 uid = 6 [(is_uid) = true]; // currently only SYSTEM_UID or 0 for other
- optional DNDPolicyProto policy = 7;
-}
-
-/**
- * Atom that represents a Do Not Disturb policy, an optional detail proto for DNDModeProto.
- */
-message DNDPolicyProto {
- enum State {
- STATE_UNSET = 0;
- STATE_ALLOW = 1;
- STATE_DISALLOW = 2;
- }
- optional State calls = 1;
- optional State repeat_callers = 2;
- optional State messages = 3;
- optional State conversations = 4;
- optional State reminders = 5;
- optional State events = 6;
- optional State alarms = 7;
- optional State media = 8;
- optional State system = 9;
- optional State fullscreen = 10;
- optional State lights = 11;
- optional State peek = 12;
- optional State status_bar = 13;
- optional State badge = 14;
- optional State ambient = 15;
- optional State notification_list = 16;
-
- enum PeopleType {
- PEOPLE_UNSET = 0;
- PEOPLE_ANYONE = 1;
- PEOPLE_CONTACTS = 2;
- PEOPLE_STARRED = 3;
- PEOPLE_NONE = 4;
- }
-
- optional PeopleType allow_calls_from = 17;
- optional PeopleType allow_messages_from = 18;
-
- enum ConversationType {
- CONV_UNSET = 0;
- CONV_ANYONE = 1;
- CONV_IMPORTANT = 2;
- CONV_NONE = 3;
- }
-
- optional ConversationType allow_conversations_from = 19;
-}
-
-/**
- * Atom that contains a list of a package's channel group preferences, pulled from
- * NotificationManagerService.java.
- */
-message PackageNotificationChannelGroupPreferences {
- // Uid under which the package is installed.
- optional int32 uid = 1 [(is_uid) = true];
- // Channel Group's ID. Should always be available.
- optional string group_id = 2;
- // Channel Group's name. Should always be available.
- optional string group_name = 3;
- // Channel Group's description. Optionally set by group creator.
- optional string description = 4;
- // Indicates if notifications from this channel group are blocked.
- optional bool is_blocked = 5;
- // Bitmask representing which fields have been set by the user. See field bitmask descriptions
- // at core/java/android/app/NotificationChannelGroup.java
- optional int32 user_locked_fields = 6;
-}
-
-message PowerProfileProto {
- optional double cpu_suspend = 1;
-
- optional double cpu_idle = 2;
-
- optional double cpu_active = 3;
-
- message CpuCluster {
- optional int32 id = 1;
- optional double cluster_power = 2;
- optional int32 cores = 3;
- repeated int64 speed = 4;
- repeated double core_power = 5;
- }
-
- repeated CpuCluster cpu_cluster = 40;
-
- optional double wifi_scan = 4;
-
- optional double wifi_on = 5;
-
- optional double wifi_active = 6;
-
- optional double wifi_controller_idle = 7;
-
- optional double wifi_controller_rx = 8;
-
- optional double wifi_controller_tx = 9;
-
- repeated double wifi_controller_tx_levels = 10;
-
- optional double wifi_controller_operating_voltage = 11;
-
- optional double bluetooth_controller_idle = 12;
-
- optional double bluetooth_controller_rx = 13;
-
- optional double bluetooth_controller_tx = 14;
-
- optional double bluetooth_controller_operating_voltage = 15;
-
- optional double modem_controller_sleep = 16;
-
- optional double modem_controller_idle = 17;
-
- optional double modem_controller_rx = 18;
-
- repeated double modem_controller_tx = 19;
-
- optional double modem_controller_operating_voltage = 20;
-
- optional double gps_on = 21;
-
- repeated double gps_signal_quality_based = 22;
-
- optional double gps_operating_voltage = 23;
-
- optional double bluetooth_on = 24;
-
- optional double bluetooth_active = 25;
-
- optional double bluetooth_at_cmd = 26;
-
- optional double ambient_display = 27;
-
- optional double screen_on = 28;
-
- optional double radio_on = 29;
-
- optional double radio_scanning = 30;
-
- optional double radio_active = 31;
-
- optional double screen_full = 32;
-
- optional double audio = 33;
-
- optional double video = 34;
-
- optional double flashlight = 35;
-
- optional double memory = 36;
-
- optional double camera = 37;
-
- optional double wifi_batched_scan = 38;
-
- optional double battery_capacity = 39;
-}
-
-/**
- * power_profile.xml and other constants for power model calculations.
- * Pulled from PowerProfile.java
- */
-message PowerProfile {
- optional PowerProfileProto power_profile = 1;
-}
-
-/**
- * Logs when a user restriction was added or removed.
- *
- * Logged from:
- * frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
- */
-message UserRestrictionChanged {
- // The raw string of the user restriction as defined in UserManager.
- // Allowed values are defined in UserRestrictionsUtils#USER_RESTRICTIONS.
- optional string restriction = 1;
- // Whether the restriction is enabled or disabled.
- optional bool enabled = 2;
-}
-
-/**
- * Pulls process user time and system time. Puller takes a snapshot of all pids
- * in the system and returns cpu stats for those that are working at the time.
- * Dead pids will be dropped. Kernel processes are excluded.
- * Min cool-down is 5 sec.
- */
-message ProcessCpuTime {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string process_name = 2;
- // Process cpu time in user space, cumulative from boot/process start
- optional int64 user_time_millis = 3;
- // Process cpu time in system space, cumulative from boot/process start
- optional int64 system_time_millis = 4;
-}
-
-/**
- * Pulls the CPU usage for each thread.
- *
- * Read from /proc/$PID/task/$TID/time_in_state files.
- *
- * TODO(mishaw): This is an experimental atom. Issues with big/little CPU frequencies, and
- * time_in_state files not being present on some phones, have not been addressed. These should be
- * considered before a public release.
- */
-message CpuTimePerThreadFreq {
- // UID that owns the process.
- optional int32 uid = 1 [(is_uid) = true];
- // ID of the process.
- optional int32 process_id = 2;
- // ID of the thread.
- optional int32 thread_id = 3;
- // Name of the process taken from `/proc/$PID/cmdline`.
- optional string process_name = 4;
- // Name of the thread taken from `/proc/$PID/task/$TID/comm`
- optional string thread_name = 5;
-
- // Report eight different frequencies, and how much time is spent in each frequency. Frequencies
- // are given in KHz, and time is given in milliseconds since the thread started. All eight
- // frequencies are given here as the alternative is sending eight separate atoms. This method
- // significantly reduces the amount of data created
- optional int32 frequency1_khz = 6;
- optional int32 time1_millis = 7;
- optional int32 frequency2_khz = 8;
- optional int32 time2_millis = 9;
- optional int32 frequency3_khz = 10;
- optional int32 time3_millis = 11;
- optional int32 frequency4_khz = 12;
- optional int32 time4_millis = 13;
- optional int32 frequency5_khz = 14;
- optional int32 time5_millis = 15;
- optional int32 frequency6_khz = 16;
- optional int32 time6_millis = 17;
- optional int32 frequency7_khz = 18;
- optional int32 time7_millis = 19;
- optional int32 frequency8_khz = 20;
- optional int32 time8_millis = 21;
-}
-
-/**
- * Pulls information about the device's build.
- */
-message BuildInformation {
- // Build.FINGERPRINT. A string that uniquely identifies this build. Do not parse.
- // E.g. may be composed of the brand, product, device, release, id, incremental, type, and tags.
- optional string fingerprint = 1;
-
- // Build.BRAND. The consumer-visible brand with which the product/hardware will be associated.
- optional string brand = 2;
-
- // Build.PRODUCT. The name of the overall product.
- optional string product = 3;
-
- // Build.DEVICE. The name of the industrial design.
- optional string device = 4;
-
- // Build.VERSION.RELEASE. The user-visible version string. E.g., "1.0" or "3.4b5" or "bananas".
- optional string version_release = 5;
-
- // Build.ID. E.g. a label like "M4-rc20".
- optional string id = 6;
-
- // Build.VERSION.INCREMENTAL. The internal value used by the underlying source control to
- // represent this build.
- optional string version_incremental = 7;
-
- // Build.TYPE. The type of build, like "user" or "eng".
- optional string type = 8;
-
- // Build.TAGS. Comma-separated tags describing the build, like "unsigned,debug".
- optional string tags = 9;
-}
-
-/**
- * Logs information about mismatched caller for content capture.
- *
- * Logged from:
- * frameworks/base/core/java/android/service/contentcapture/ContentCaptureService.java
- */
-message ContentCaptureCallerMismatchReported {
- optional string intended_package = 1;
- optional string calling_package = 2;
-}
-
-/**
- * Logs information about content capture service events.
- *
- * Logged from:
- * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java
- */
-message ContentCaptureServiceEvents {
- // The type of event.
- enum Event {
- UNKNOWN = 0;
- ON_CONNECTED = 1;
- ON_DISCONNECTED = 2;
- SET_WHITELIST = 3;
- SET_DISABLED = 4;
- ON_USER_DATA_REMOVED = 5;
- ON_DATA_SHARE_REQUEST = 6;
- ACCEPT_DATA_SHARE_REQUEST = 7;
- REJECT_DATA_SHARE_REQUEST = 8;
- DATA_SHARE_WRITE_FINISHED = 9;
- DATA_SHARE_ERROR_IOEXCEPTION = 10;
- DATA_SHARE_ERROR_EMPTY_DATA = 11;
- DATA_SHARE_ERROR_CLIENT_PIPE_FAIL = 12;
- DATA_SHARE_ERROR_SERVICE_PIPE_FAIL = 13;
- DATA_SHARE_ERROR_CONCURRENT_REQUEST = 14;
- DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED = 15;
- }
- optional Event event = 1;
- // component/package of content capture service.
- optional string service_info = 2;
- // component/package of target.
- // it's a concatenated list of component/package for SET_WHITELIST event
- // separated by " ".
- optional string target_info = 3;
-}
-
-/**
- * Logs information about content capture session events.
- *
- * Logged from:
- * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java
- */
-message ContentCaptureSessionEvents {
- // The type of event.
- enum Event {
- UNKNOWN = 0;
- ON_SESSION_STARTED = 1;
- ON_SESSION_FINISHED = 2;
- SESSION_NOT_CREATED = 3;
- }
- optional int32 session_id = 1;
- optional Event event = 2;
- // (n/a on session finished)
- optional int32 state_flags = 3;
- // component/package of content capture service.
- optional string service_info = 4;
- // component/package of app.
- // (n/a on session finished)
- optional string app_info = 5;
- optional bool is_child_session = 6;
-}
-
-/**
- * Logs information about session being flushed.
- *
- * Logged from:
- * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java
- */
-message ContentCaptureFlushed {
- optional int32 session_id = 1;
- // component/package of content capture service.
- optional string service_info = 2;
- // component/package of app.
- optional string app_info = 3;
- // session start/finish events
- optional int32 child_session_started = 4;
- optional int32 child_session_finished = 5;
- // count of view events.
- optional int32 view_appeared_count = 6;
- optional int32 view_disappeared_count = 7;
- optional int32 view_text_changed_count = 8;
-
- // Flush stats.
- optional int32 max_events = 9;
- optional int32 idle_flush_freq = 10;
- optional int32 text_flush_freq = 11;
- optional int32 flush_reason = 12;
-}
-
-/**
- * Pulls on-device BatteryStats power use calculations for the overall device.
- */
-message DeviceCalculatedPowerUse {
- // Power used by the device in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since
- // BatteryStats last reset (i.e. roughly since device was last significantly charged).
- // Currently, this is from BatteryStatsHelper.getComputedPower() (not getTotalPower()).
- optional int64 computed_power_nano_amp_secs = 1;
-}
-
-/**
- * Pulls on-device BatteryStats power use calculations broken down by uid.
- * This atom should be complemented by DeviceCalculatedPowerBlameOther, which contains the power use
- * that is attributed to non-uid items. They must all be included to get the total power use.
- */
-message DeviceCalculatedPowerBlameUid {
- // Uid being blamed. Note: isolated uids have already been mapped to host uid.
- optional int32 uid = 1 [(is_uid) = true];
-
- // Power used by this uid in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since
- // BatteryStats last reset (i.e. roughly since device was last significantly charged).
- optional int64 power_nano_amp_secs = 2;
-}
-
-/**
- * Pulls on-device BatteryStats power use calculations that are not due to a uid, broken down by
- * drain type.
- * This atom should be complemented by DeviceCalculatedPowerBlameUid, which contains the blame that
- * is attributed uids. They must all be included to get the total power use.
- */
-message DeviceCalculatedPowerBlameOther {
- // The type of item whose power use is being reported.
- enum DrainType {
- AMBIENT_DISPLAY = 0;
- // reserved 1; reserved "APP"; // Logged instead in DeviceCalculatedPowerBlameUid.
- BLUETOOTH = 2;
- CAMERA = 3;
- // Cell-standby
- CELL = 4;
- FLASHLIGHT = 5;
- IDLE = 6;
- MEMORY = 7;
- // Amount that total computed drain exceeded the drain estimated using the
- // battery level changes and capacity.
- OVERCOUNTED = 8;
- PHONE = 9;
- SCREEN = 10;
- // Amount that total computed drain was below the drain estimated using the
- // battery level changes and capacity.
- UNACCOUNTED = 11;
- // reserved 12; reserved "USER"; // Entire drain for a user. This is NOT supported.
- WIFI = 13;
- }
- optional DrainType drain_type = 1;
-
- // Power used by this item in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since
- // BatteryStats last reset (i.e. roughly since device was last significantly charged).
- optional int64 power_nano_amp_secs = 2;
-}
-
-/**
- * Logs device policy features.
- *
- * Logged from:
- * frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
- * packages/apps/ManagedProvisioning/src/com/android/managedprovisioning/
- */
-message DevicePolicyEvent {
- // The event id - unique for each event.
- optional android.stats.devicepolicy.EventId event_id = 1;
- // The admin package name.
- optional string admin_package_name = 2;
- // A generic integer parameter.
- optional int32 integer_value = 3;
- // A generic boolean parameter.
- optional bool boolean_value = 4;
- // A parameter specifying a time period in milliseconds.
- optional uint64 time_period_millis = 5;
- // A parameter specifying a list of package names, bundle extras or string parameters.
- optional android.stats.devicepolicy.StringList string_list_value = 6 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Logs when DocumentsUI is started, and how. Call this when DocumentsUI first starts up.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUILaunchReported {
- optional android.stats.docsui.LaunchAction launch_action = 1;
- optional bool has_initial_uri = 2;
- optional android.stats.docsui.MimeType mime_type = 3;
- optional android.stats.docsui.Root initial_root = 4;
-}
-
-/**
- * Logs root/app visited event in file managers/picker. Call this when the user
- * taps on root/app in hamburger menu.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIRootVisitedReported {
- optional android.stats.docsui.ContextScope scope = 1;
- optional android.stats.docsui.Root root = 2;
-}
-
-/**
- * Logs file operation stats. Call this when a file operation has completed.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIFileOperationReported {
- optional android.stats.docsui.Provider provider = 1;
- optional android.stats.docsui.FileOperation file_op = 2;
-}
-
-/**
- * Logs file operation stats. Call this when a copy/move operation has completed with a specific
- * mode.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIFileOperationCopyMoveModeReported {
- optional android.stats.docsui.FileOperation file_op = 1;
- optional android.stats.docsui.CopyMoveOpMode mode = 2;
-}
-
-
-/**
- * Logs file sub operation stats. Call this when a file operation has failed.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIFileOperationFailureReported {
- optional android.stats.docsui.Authority authority = 1;
- optional android.stats.docsui.SubFileOperation sub_op = 2;
-}
-
-/**
-* Logs the cancellation of a file operation. Call this when a job is canceled
-*
-* Logged from:
-* package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
-*/
-message DocsUIFileOperationCanceledReported {
- optional android.stats.docsui.FileOperation file_op = 1;
-}
-
-/**
- * Logs startup time in milliseconds.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIStartupMsReported {
- optional int32 startup_millis = 1;
-}
-
-/**
- * Logs the action that was started by user.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIUserActionReported {
- optional android.stats.docsui.UserAction action = 1;
-}
-
-/**
- * Logs the invalid type when invalid scoped access is requested.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/ScopedAccessMetrics.java
- */
-message DocsUIInvalidScopedAccessRequestReported {
- optional android.stats.docsui.InvalidScopedAccess type = 1;
-}
-
-/**
- * Logs the package name that launches docsui picker mode.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIPickerLaunchedFromReported {
- optional string package_name = 1;
-}
-
-/**
- * Logs the search type.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUISearchTypeReported {
- optional android.stats.docsui.SearchType search_type = 1;
-}
-
-/**
- * Logs the search mode.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUISearchModeReported {
- optional android.stats.docsui.SearchMode search_mode = 1;
-}
-
-/**
- * Logs the pick result information.
- *
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIPickResultReported {
- optional int32 total_action_count = 1;
- optional int64 duration_millis = 2;
- optional int32 file_count= 3;
- optional bool is_searching = 4;
- optional android.stats.docsui.Root picked_from = 5;
- optional android.stats.docsui.MimeType mime_type = 6;
- optional int32 repeatedly_pick_times = 7;
-}
-
-/** Logs the drag and drop of files.
-
- * Logged from:
- * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java
- */
-message DocsUIDragAndDropReported {
- optional bool drag_initiated_from_docsui = 1;
-}
-
-/**
- * Logs when an app's memory is compacted.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- */
-message AppCompacted {
- // The pid of the process being compacted.
- optional int32 pid = 1;
-
- // The name of the process being compacted.
- optional string process_name = 2;
-
- // The type of compaction.
- enum Action {
- UNKNOWN = 0;
- SOME = 1;
- FULL = 2;
- PERSISTENT = 3;
- BFGS = 4;
- }
- optional Action action = 3;
-
- // Total RSS in kilobytes consumed by the process prior to compaction.
- optional int64 before_rss_total_kilobytes = 4;
-
- // File RSS in kilobytes consumed by the process prior to compaction.
- optional int64 before_rss_file_kilobytes = 5;
-
- // Anonymous RSS in kilobytes consumed by the process prior to compaction.
- optional int64 before_rss_anon_kilobytes = 6;
-
- // Swap in kilobytes consumed by the process prior to compaction.
- optional int64 before_swap_kilobytes = 7;
-
- // Total RSS in kilobytes consumed by the process after compaction.
- optional int64 after_rss_total_kilobytes = 8;
-
- // File RSS in kilobytes consumed by the process after compaction.
- optional int64 after_rss_file_kilobytes = 9;
-
- // Anonymous RSS in kilobytes consumed by the process after compaction.
- optional int64 after_rss_anon_kilobytes = 10;
-
- // Swap in kilobytes consumed by the process after compaction.
- optional int64 after_swap_kilobytes = 11;
-
- // The time taken to perform compaction in milliseconds.
- optional int64 time_to_compact_millis = 12;
-
- // The last compaction action performed for this app.
- optional Action last_action = 13;
-
- // The last time that compaction was attempted on this process in milliseconds
- // since boot, not including sleep (see SystemClock.uptimeMillis()).
- optional int64 last_compact_timestamp_ms_since_boot = 14;
-
- // The "setAdj" (i.e. previous) oom_score_adj at the time of compaction.
- optional int32 oom_score_adj = 15;
-
- // The process state at the time of compaction.
- optional android.app.ProcessStateEnum process_state = 16 [default = PROCESS_STATE_UNKNOWN];
-
- // Free ZRAM in kilobytes before compaction.
- optional int64 before_zram_free_kilobytes = 17;
-
- // Free ZRAM in kilobytes after compaction.
- optional int64 after_zram_free_kilobytes = 18;
-}
-
-/**
- * Logs when a Tethering event occurs.
- *
- */
-message NetworkTetheringReported {
- // tethering error code
- optional android.stats.connectivity.ErrorCode error_code = 1;
-
- // tethering downstream type
- optional android.stats.connectivity.DownstreamType downstream_type = 2;
-
- // transport type of upstream network
- optional android.stats.connectivity.UpstreamType upstream_type = 3;
-
- // The user type of Tethering
- optional android.stats.connectivity.UserType user_type= 4;
-}
-
-/**
- * Logs a DNS lookup operation initiated by the system resolver on behalf of an application
- * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName().
- *
- * The NetworkDnsEventReported message represents the entire lookup operation, which may
- * result one or more queries to the recursive DNS resolvers. Those are individually logged
- * in DnsQueryEvents to enable computing error rates and network latency and timeouts
- * broken up by query type, transport, network interface, etc.
- */
-message NetworkDnsEventReported {
- optional android.stats.dnsresolver.EventType event_type = 1;
-
- optional android.stats.dnsresolver.ReturnCode return_code = 2;
-
- // The latency in microseconds of the entire DNS lookup operation.
- optional int32 latency_micros = 3;
-
- // Only valid for event_type = EVENT_GETADDRINFO.
- optional int32 hints_ai_flags = 4;
-
- // Flags passed to android_res_nsend() defined in multinetwork.h
- // Only valid for event_type = EVENT_RESNSEND.
- optional int32 res_nsend_flags = 5;
-
- optional android.stats.dnsresolver.NetworkType network_type = 6;
-
- // The DNS over TLS mode on a specific netId.
- optional android.stats.dnsresolver.PrivateDnsModes private_dns_modes = 7;
-
- // Additional pass-through fields opaque to statsd.
- // The DNS resolver Mainline module can add new fields here without requiring an OS update.
- optional android.stats.dnsresolver.DnsQueryEvents dns_query_events = 8 [(log_mode) = MODE_BYTES];
-
- // The sample rate of DNS stats (to statsd) is 1/sampling_rate_denom.
- optional int32 sampling_rate_denom = 9;
-}
-
-/**
- * logs the CapportApiData info
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message CapportApiData {
- // The TTL of the network connection provided by captive portal
- optional int32 remaining_ttl_secs = 1;
-
- // The limit traffic data of the network connection provided by captive portal
- optional int32 remaining_bytes = 2;
-
- // Is portal url option included in the DHCP packet (Yes, No)
- optional bool has_portal_url = 3;
-
- // Is venue info (e.g. store info, maps, flight status) included (Yes, No)
- optional bool has_venue_info = 4;
-}
-
-/**
- * logs a network Probe Event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message ProbeEvent {
- // The probe type (http or https, or captive portal API...)
- optional android.stats.connectivity.ProbeType probe_type = 1;
-
- // The latency in microseconds of the probe event
- optional int32 latency_micros = 2;
-
- // The result of the probe event
- optional android.stats.connectivity.ProbeResult probe_result = 3;
-
- // The CaptivePortal API info
- optional CapportApiData capport_api_data = 4;
-}
-
-/**
- * log each ProbeEvent in ProbeEvents
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message ProbeEvents {
- // Record probe event during the validation
- repeated ProbeEvent probe_event = 1;
-}
-
-/**
- * The DHCP (Dynamic Host Configuration Protocol) session info
- * Logged from:
- * packages/modules/NetworkStack/src/android/net/dhcp/DhcpClient.java
- */
-message DhcpSession {
- // The DHCP Feature(s) enabled in this session
- repeated android.stats.connectivity.DhcpFeature used_features = 1;
-
- // The discover packet (re)transmit count
- optional int32 discover_count = 2;
-
- // The request packet (re)transmit count
- optional int32 request_count = 3;
-
- // The IPv4 address conflict count
- // (only be meaningful when duplicate address detection is enabled)
- optional int32 conflict_count = 4;
-
- // The DHCP packet parsing error code in this session
- // (defined in android.net.metrics.DhcpErrorEvent)
- repeated android.stats.connectivity.DhcpErrorCode error_code = 5;
-
- // The result of DHCP hostname transliteration
- optional android.stats.connectivity.HostnameTransResult ht_result = 6;
-}
-
-/**
- * Logs Network IP provisioning event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/networkstack/metrics/NetworkIpProvisioningMetrics.java
- */
-message NetworkIpProvisioningReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // The latency in microseconds of IP Provisioning over IPV4
- optional int32 ipv4_latency_micros = 2;
-
- // The latency in microseconds of IP Provisioning over IPV6
- optional int32 ipv6_latency_micros = 3;
-
- // The time duration between provisioning start and end (success or failure)
- optional int64 provisioning_duration_micros = 4;
-
- // The specific disconnect reason for this IP provisioning
- optional android.stats.connectivity.DisconnectCode disconnect_code = 5;
-
- // Log DHCP session info (Only valid for IPv4)
- optional DhcpSession dhcp_session = 6 [(log_mode) = MODE_BYTES];
-
- // The random number between 0 ~ 999 for sampling
- optional int32 random_number = 7;
-}
-
-/**
- * Logs Network DHCP Renew event
- * Logged from:
- * packages/modules/NetworkStack/src/android/net/dhcp/DhcpClient.java
- */
-message NetworkDhcpRenewReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // The request packet (re)transmit count
- optional int32 request_count = 2;
-
- // The latency in microseconds of DHCP Renew
- optional int32 latency_micros = 3;
-
- // The DHCP error code is defined in android.net.metrics.DhcpErrorEvent
- optional android.stats.connectivity.DhcpErrorCode error_code = 4;
-
- // The result of DHCP renew
- optional android.stats.connectivity.DhcpRenewResult renew_result = 5;
-
- // The random number between 0 ~ 999 for sampling
- optional int32 random_number = 6;
-}
-
-/**
- * Logs Network Validation event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message NetworkValidationReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // Record each probe event
- optional ProbeEvents probe_events = 2 [(log_mode) = MODE_BYTES];
-
- // The result of the network validation
- optional android.stats.connectivity.ValidationResult validation_result = 3;
-
- // The latency in microseconds of network validation
- optional int32 latency_micros = 4;
-
- // The validation index (the first validation attempt or second, third...)
- optional int32 validation_index = 5;
-
- // The random number between 0 ~ 999 for sampling
- optional int32 random_number = 6;
-}
-
-/**
- * Logs NetworkStack Quirk event
- * Logged from:
- * packages/modules/NetworkStack/src/com/android/networkstack/
- */
-message NetworkStackQuirkReported {
- // Transport type (WIFI, CELLULAR, BLUETOOTH, ..)
- optional android.stats.connectivity.TransportType transport_type = 1;
-
- // Record each Quirk event
- optional android.stats.connectivity.NetworkQuirkEvent event = 2;
-}
-
-/**
- * Logs when a data stall event occurs.
- *
- * Log from:
- * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- */
-message DataStallEvent {
- // Data stall evaluation type.
- // See packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
- // Refer to the definition of DATA_STALL_EVALUATION_TYPE_*.
- optional int32 evaluation_type = 1;
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.ProbeResult validation_result = 2;
- // See definition in data_stall_event.proto.
- optional android.net.NetworkCapabilitiesProto.Transport network_type = 3;
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.WifiData wifi_info = 4 [(log_mode) = MODE_BYTES];
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.CellularData cell_info = 5 [(log_mode) = MODE_BYTES];
- // See definition in data_stall_event.proto.
- optional com.android.server.connectivity.DnsEvent dns_event = 6 [(log_mode) = MODE_BYTES];
- // The tcp packets fail rate from the latest tcp polling.
- optional int32 tcp_fail_rate = 7;
- // Number of packets sent since the last received packet.
- optional int32 tcp_sent_since_last_recv = 8;
-}
-
-/*
- * Logs when RescueParty resets some set of experiment flags.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/RescueParty.java
- */
-message RescuePartyResetReported {
- // The rescue level of this reset. A value of 0 indicates missing or unknown level information.
- optional int32 rescue_level = 1;
-}
-
-/**
- * Logs when signed config is received from an APK, and if that config was applied successfully.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/signedconfig/SignedConfigService.java
- */
-message SignedConfigReported {
- enum Type {
- UNKNOWN_TYPE = 0;
- GLOBAL_SETTINGS = 1;
- }
- optional Type type = 1;
-
- // The final status of the signed config received.
- enum Status {
- UNKNOWN_STATUS = 0;
- APPLIED = 1;
- BASE64_FAILURE_CONFIG = 2;
- BASE64_FAILURE_SIGNATURE = 3;
- SECURITY_EXCEPTION = 4;
- INVALID_CONFIG = 5;
- OLD_CONFIG = 6;
- SIGNATURE_CHECK_FAILED = 7;
- NOT_APPLICABLE = 8;
- SIGNATURE_CHECK_FAILED_PROD_KEY_ABSENT = 9;
- }
- optional Status status = 2;
-
- // The version of the signed config processed.
- optional int32 version = 3;
-
- // The package name that the config was extracted from.
- optional string from_package = 4;
-
- enum Key {
- NO_KEY = 0;
- DEBUG = 1;
- PRODUCTION = 2;
- }
- // Which key was used to verify the config.
- optional Key verified_with = 5;
-}
-
-/*
- * Logs GNSS Network-Initiated (NI) location events.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java
- */
-message GnssNiEventReported {
- // The type of GnssNiEvent.
- enum EventType {
- UNKNOWN = 0;
- NI_REQUEST = 1;
- NI_RESPONSE = 2;
- }
- optional EventType event_type = 1;
-
- // An ID generated by HAL to associate NI notifications and UI responses.
- optional int32 notification_id = 2;
-
- // A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc.
- optional android.server.location.GnssNiType ni_type = 3;
-
- // NI requires notification.
- optional bool need_notify = 4;
-
- // NI requires verification.
- optional bool need_verify = 5;
-
- // NI requires privacy override, no notification/minimal trace.
- optional bool privacy_override = 6;
-
- // Timeout period to wait for user response. Set to 0 for no timeout limit. Specified in
- // seconds.
- optional int32 timeout = 7;
-
- // Default response when timeout.
- optional android.server.location.GnssUserResponseType default_response = 8;
-
- // String representing the requester of the network inititated location request.
- optional string requestor_id = 9;
-
- // Notification message text string representing the service(for eg. SUPL-service) who sent the
- // network initiated location request.
- optional string text = 10;
-
- // requestorId decoding scheme.
- optional android.server.location.GnssNiEncodingType requestor_id_encoding = 11;
-
- // Notification message text decoding scheme.
- optional android.server.location.GnssNiEncodingType text_encoding = 12;
-
- // True if SUPL ES is enabled.
- optional bool is_supl_es_enabled = 13;
-
- // True if GNSS location is enabled.
- optional bool is_location_enabled = 14;
-
- // GNSS NI responses which define the response in NI structures.
- optional android.server.location.GnssUserResponseType user_response = 15;
-}
-
-/**
- * Logs GNSS non-framework (NFW) location notification.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java
- */
-message GnssNfwNotificationReported {
- // Package name of the Android proxy application representing the non-framework entity that
- // requested location. Set to empty string if unknown.
- optional string proxy_app_package_name = 1;
-
- // Protocol stack that initiated the non-framework location request.
- optional android.server.location.NfwProtocolStack protocol_stack = 2;
-
- // Name of the protocol stack if protocol_stack field is set to OTHER_PROTOCOL_STACK. Otherwise,
- // set to empty string. This field is opaque to the framework and used for logging purposes.
- optional string other_protocol_stack_name = 3;
-
- // Source initiating/receiving the location information.
- optional android.server.location.NfwRequestor requestor = 4;
-
- // Identity of the endpoint receiving the location information. For example, carrier name, OEM
- // name, SUPL SLP/E-SLP FQDN, chipset vendor name, etc. This field is opaque to the framework
- // and used for logging purposes.
- optional string requestor_id = 5;
-
- // Indicates whether location information was provided for this request.
- optional android.server.location.NfwResponseType response_type = 6;
-
- // True if the device is in user initiated emergency session.
- optional bool in_emergency_mode = 7;
-
- // True if cached location is provided.
- optional bool is_cached_location = 8;
-
- // True if proxy app permission mismatch between framework and GNSS HAL.
- optional bool is_permission_mismatched = 9;
-}
-
-/**
- * Logs GNSS configuration as defined in IGnssConfiguration.hal.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/location/GnssConfiguration.java
- */
-message GnssConfigurationReported {
- // SUPL host name.
- optional string supl_host = 1;
-
- // SUPL port number.
- optional int32 supl_port = 2;
-
- // C2K host name.
- optional string c2k_host = 3;
-
- // C2K port number.
- optional int32 c2k_port = 4;
-
- // The SUPL version requested by Carrier.
- optional int32 supl_ver = 5;
-
- // The SUPL mode.
- optional android.server.location.SuplMode supl_mode = 6;
-
- // True if NI emergency SUPL restrictions is enabled.
- optional bool supl_es = 7;
-
- // LTE Positioning Profile settings
- optional android.server.location.LppProfile lpp_profile = 8;
-
- // Positioning protocol on A-Glonass system.
- optional android.server.location.GlonassPosProtocol a_glonass_pos_protocol_select = 9;
-
- // True if emergency PDN is used. Otherwise, regular PDN is used.
- optional bool use_emergency_pdn_for_emergency_supl= 10;
-
- // Configurations of how GPS functionalities should be locked when user turns off GPS On setting.
- optional android.server.location.GpsLock gps_lock = 11;
-
- // Number of seconds to extend the emergency session duration post emergency call.
- optional int32 es_extension_sec = 12;
-
- // The full list of package names of proxy Android applications representing the non-framework
- // location access entities (on/off the device) for which the framework user has granted
- // non-framework location access permission. The package names are concatenated in one string
- // with spaces as separators.
- optional string enabled_proxy_app_package_name_list = 13;
-}
-
-/**
- * Logs when a NFC device's error occurred.
- * Logged from:
- * system/nfc/src/nfc/nfc/nfc_ncif.cc
- * packages/apps/Nfc/src/com/android/nfc/cardemulation/AidRoutingManager.java
- */
-message NfcErrorOccurred {
- enum Type {
- UNKNOWN = 0;
- CMD_TIMEOUT = 1;
- ERROR_NOTIFICATION = 2;
- AID_OVERFLOW = 3;
- }
- optional Type type = 1;
- // If it's nci cmd timeout, log the timeout command.
- optional uint32 nci_cmd = 2;
-
- optional uint32 error_ntf_status_code = 3;
-}
-
-/**
- * Logs when a NFC device's state changed event
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/NfcService.java
- */
-message NfcStateChanged {
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- ON_LOCKED = 3; // Secure Nfc enabled.
- CRASH_RESTART = 4; // NfcService watchdog timeout restart.
- }
- optional State state = 1;
-}
-
-/**
- * Logs when a NFC Beam Transaction occurred.
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/P2pLinkManager.java
- */
-message NfcBeamOccurred {
- enum Operation {
- UNKNOWN = 0;
- SEND = 1;
- RECEIVE = 2;
- }
- optional Operation operation = 1;
-}
-
-/**
- * Logs when a NFC Card Emulation Transaction occurred.
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/cardemulation/HostEmulationManager.java
- * packages/apps/Nfc/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java
- */
-message NfcCardemulationOccurred {
- enum Category {
- UNKNOWN = 0;
- HCE_PAYMENT = 1;
- HCE_OTHER = 2;
- OFFHOST = 3;
- }
- // Transaction belongs to HCE payment or HCE other category, or offhost.
- optional Category category = 1;
- // SeName from transaction: SIMx, eSEx, HCE, HCEF.
- optional string se_name = 2;
-}
-
-/**
- * Logs when a NFC Tag event occurred.
- * Logged from:
- * packages/apps/Nfc/src/com/android/nfc/NfcDispatcher.java
- */
-message NfcTagOccurred {
- enum Type {
- UNKNOWN = 0;
- URL = 1;
- BT_PAIRING = 2;
- PROVISION = 3;
- WIFI_CONNECT = 4;
- APP_LAUNCH = 5;
- OTHERS = 6;
- }
- optional Type type = 1;
-}
-
-/**
- * Logs when Hce transaction triggered
- * Logged from:
- * system/nfc/src/nfc/nfc/nfc_ncif.cc
- */
-message NfcHceTransactionOccurred {
- // The latency period(in microseconds) it took for the first HCE data
- // exchange.
- optional uint32 latency_micros = 1;
-}
-
-/**
- * Logs when SecureElement state event changed
- * Logged from:
- * packages/apps/SecureElement/src/com/android/se/Terminal.java
- */
-message SeStateChanged {
- enum State {
- UNKNOWN = 0;
- INITIALIZED = 1;
- DISCONNECTED = 2;
- CONNECTED = 3;
- HALCRASH = 4;
- }
- optional State state = 1;
-
- optional string state_change_reason = 2;
- // SIMx or eSEx.
- optional string terminal = 3;
-}
-
-/**
- * Information about a permission grant request
- */
-message PermissionGrantRequestResultReported {
- // unique value identifying an API call. A API call might result in multiple of these atoms
- optional int64 request_id = 1;
-
- // UID of package requesting the permission grant
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package requesting the permission grant
- optional string package_name = 3;
-
- // The permission to be granted
- optional string permission_name = 4;
-
- // If the permission was explicitly requested via the API or added by the system
- optional bool is_implicit = 5;
-
- enum Result {
- UNDEFINED = 0;
- // permission request was ignored
- IGNORED = 1;
- // permission request was ignored because it was user fixed
- IGNORED_USER_FIXED = 2;
- // permission request was ignored because it was policy fixed
- IGNORED_POLICY_FIXED = 3;
- // permission was granted by user action
- USER_GRANTED = 4;
- // permission was automatically granted
- AUTO_GRANTED = 5;
- // permission was denied by user action
- USER_DENIED = 6;
- // permission was denied with prejudice by the user
- USER_DENIED_WITH_PREJUDICE = 7;
- // permission was automatically denied
- AUTO_DENIED = 8;
- // permission request was ignored because permission is restricted
- IGNORED_RESTRICTED_PERMISSION = 9;
- // one time permission was granted by user action
- USER_GRANTED_ONE_TIME = 10;
- // user ignored request by leaving the request screen without choosing any option
- USER_IGNORED = 11;
- // user granted the permission after being linked to settings
- USER_GRANTED_IN_SETTINGS = 12;
- // user denied the permission after being linked to settings
- USER_DENIED_IN_SETTINGS = 13;
- // user denied the permission with prejudice after being linked to settings
- USER_DENIED_WITH_PREJUDICE_IN_SETTINGS = 14;
- // permission was automatically revoked after one-time permission expired
- AUTO_ONE_TIME_PERMISSION_REVOKED = 15;
- // permission was automatically revoked for unused app
- AUTO_UNUSED_APP_PERMISSION_REVOKED = 16;
- }
- // The result of the permission grant
- optional Result result = 6;
-}
-
-/**
- * Logs when Omapi API used
- * Logged from:
- * packages/apps/SecureElement/src/com/android/se/Terminal.java
- */
-message SeOmapiReported {
- enum Operation {
- UNKNOWN = 0;
- OPEN_CHANNEL = 1;
- }
- optional Operation operation = 1;
- // SIMx or eSEx.
- optional string terminal = 2;
-
- optional string package_name = 3;
-}
-
-/**
- * Logs the dispatch latency of a broadcast during processing of BOOT_COMPLETED.
- * The dispatch latency is the dispatchClockTime - enqueueClockTime.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
- */
-message BroadcastDispatchLatencyReported {
- optional int64 dispatch_latency_millis = 1;
-}
-
-/**
- * Logs AttentionManagerService attention check result.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/attention/AttentionManagerService.java
- */
-message AttentionManagerServiceResultReported {
- // See core/java/android/service/attention/AttentionService.java
- enum AttentionCheckResult {
- UNKNOWN = 20;
- ATTENTION_SUCCESS_ABSENT = 0;
- ATTENTION_SUCCESS_PRESENT = 1;
- ATTENTION_FAILURE_UNKNOWN = 2;
- ATTENTION_FAILURE_CANCELLED = 3;
- ATTENTION_FAILURE_PREEMPTED = 4;
- ATTENTION_FAILURE_TIMED_OUT = 5;
- ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6;
- }
- optional AttentionCheckResult attention_check_result = 1 [default = UNKNOWN];
-}
-
-/**
- * Logs when an adb connection changes state.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java
- */
-message AdbConnectionChanged {
- // The last time this system connected via adb, or 0 if the 'always allow' option was not
- // previously selected for this system.
- optional int64 last_connection_time_millis = 1;
-
- // The time in ms within which a subsequent connection from an 'always allow' system is allowed
- // to reconnect via adb without user interaction.
- optional int64 auth_window_millis = 2;
-
- // The state of the adb connection from frameworks/base/core/proto/android/debug/enums.proto.
- optional android.debug.AdbConnectionStateEnum state = 3;
-
- // True if the 'always allow' option was selected for this system.
- optional bool always_allow = 4;
-}
-
-/*
- * Logs the reported speech DSP status.
- *
- * Logged from:
- * Vendor audio implementation.
- */
-message SpeechDspStatReported {
- // The total Speech DSP uptime in milliseconds.
- optional int32 total_uptime_millis = 1;
- // The total Speech DSP downtime in milliseconds.
- optional int32 total_downtime_millis = 2;
- optional int32 total_crash_count = 3;
- optional int32 total_recover_count = 4;
-}
-
-/**
- * Logs USB connector contaminant status.
- *
- * Logged from: USB Service.
- */
-message UsbContaminantReported {
- optional string id = 1;
- optional android.service.usb.ContaminantPresenceStatus status = 2;
-}
-
-/**
- * This atom is for debugging purpose.
- */
-message DebugElapsedClock {
- // Monotically increasing value for each pull.
- optional int64 pull_count = 1;
- // Time from System.elapsedRealtime.
- optional int64 elapsed_clock_millis = 2;
- // Time from System.elapsedRealtime.
- optional int64 same_elapsed_clock_millis = 3;
- // Diff between current elapsed time and elapsed time from previous pull.
- optional int64 elapsed_clock_diff_millis = 4;
-
- enum Type {
- TYPE_UNKNOWN = 0;
- ALWAYS_PRESENT = 1;
- PRESENT_ON_ODD_PULLS = 2;
- }
- // Type of behavior for the pulled data.
- optional Type type = 5;
-}
-
-/**
- * This atom is for debugging purpose.
- */
-message DebugFailingElapsedClock {
- // Monotically increasing value for each pull.
- optional int64 pull_count = 1;
- // Time from System.elapsedRealtime.
- optional int64 elapsed_clock_millis = 2;
- // Time from System.elapsedRealtime.
- optional int64 same_elapsed_clock_millis = 3;
- // Diff between current elapsed time and elapsed time from previous pull.
- optional int64 elapsed_clock_diff_millis = 4;
-}
-
-/** Logs System UI bubbles event changed.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles
- */
-message BubbleUIChanged {
-
- // The app package that is posting the bubble.
- optional string package_name = 1;
-
- // The notification channel that is posting the bubble.
- optional string notification_channel = 2;
-
- // The notification id associated with the posted bubble.
- optional int32 notification_id = 3;
-
- // The position of the bubble within the bubble stack.
- optional int32 position = 4;
-
- // The total number of bubbles within the bubble stack.
- optional int32 total_number = 5;
-
- // User interactions with the bubble.
- enum Action {
- UNKNOWN = 0;
- POSTED = 1;
- UPDATED = 2;
- EXPANDED = 3;
- COLLAPSED = 4;
- DISMISSED = 5;
- STACK_DISMISSED = 6;
- STACK_MOVED = 7;
- HEADER_GO_TO_APP = 8;
- HEADER_GO_TO_SETTINGS = 9;
- PERMISSION_OPT_IN = 10;
- PERMISSION_OPT_OUT = 11;
- PERMISSION_DIALOG_SHOWN = 12;
- SWIPE_LEFT = 13;
- SWIPE_RIGHT = 14;
- STACK_EXPANDED = 15;
- FLYOUT = 16;
- }
- optional Action action = 6;
-
- // Normalized screen position of the bubble stack. The range is between 0 and 1.
- optional float normalized_x_position = 7;
- optional float normalized_y_position = 8;
-
- // Whether the bubble is unread. If it is unread, a dot is shown in the bubble stack icon.
- optional bool is_unread = 9;
-
- // Whether the bubble is an on-going one.
- optional bool is_ongoing = 10;
-
- // Whether the bubble is produced by an app running in foreground.
- // This is deprecated and the value should be ignored.
- optional bool is_foreground = 11 [deprecated = true];
-}
-
-/**
- * Logs System UI bubbles developer errors.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
- */
-message BubbleDeveloperErrorReported {
-
- // The app package that is posting the bubble.
- optional string package_name = 1;
-
- // Bubble developer error type enums.
- enum Error {
- UNKNOWN = 0;
- ACTIVITY_INFO_MISSING = 1;
- ACTIVITY_INFO_NOT_RESIZABLE = 2;
- DOCUMENT_LAUNCH_NOT_ALWAYS = 3;
- }
- optional Error error = 2 [default = UNKNOWN];
-}
-
-/**
- * Logs that a constraint for a scheduled job has changed.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
- */
-message ScheduledJobConstraintChanged {
- repeated AttributionNode attribution_node = 1;
-
- // Name of the job.
- optional string job_name = 2;
-
- optional com.android.server.job.ConstraintEnum constraint = 3;
-
- enum State {
- UNKNOWN = 0;
- UNSATISFIED = 1;
- SATISFIED = 2;
- }
- optional State state = 4;
-}
-
-/**
- * Logs PowerManagerService screen timeout resets (extensions) that happen when an attention check
- * returns true.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
- */
-message ScreenTimeoutExtensionReported {
- // Describes how many times in a row did the power manager reset the screen off timeout.
- optional uint32 consecutive_timeout_extended_count = 1;
-}
-
-/*
-* Logs number of milliseconds it takes to start a process.
-* The definition of app process start time is from the app launch time to
-* the time that Zygote finished forking the app process and loaded the
-* application package's java classes.
-
-* This metric is different from AppStartOccurred which is for foreground
-* activity only.
-
-* ProcessStartTime can report all processes (both foreground and background)
-* start time.
-*
-* Logged from:
-* frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
-*/
-message ProcessStartTime {
- // The uid of the ProcessRecord.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process pid.
- optional int32 pid = 2;
-
- // The process name.
- // Usually package name, "system" for system server.
- // Provided by ActivityManagerService.
- optional string process_name = 3;
-
- enum StartType {
- UNKNOWN = 0;
- WARM = 1;
- HOT = 2;
- COLD = 3;
- }
-
- // The start type.
- optional StartType type = 4;
-
- // The elapsed realtime at the start of the process.
- optional int64 process_start_time_millis = 5;
-
- // Number of milliseconds it takes to reach bind application.
- optional int32 bind_application_delay_millis = 6;
-
- // Number of milliseconds it takes to finish start of the process.
- optional int32 process_start_delay_millis = 7;
-
- // hostingType field in ProcessRecord, the component type such as "activity",
- // "service", "content provider", "broadcast" or other strings.
- optional string hosting_type = 8;
-
- // hostingNameStr field in ProcessRecord. The component class name that runs
- // in this process.
- optional string hosting_name = 9;
-}
-
-/**
- * Track Media Codec usage
- * Logged from:
- * frameworks/av/media/libstagefright/MediaCodec.cpp
- * frameworks/av/services/mediaanalytics/statsd_codec.cpp
- */
-message MediametricsCodecReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.CodecData codec_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track Media Extractor (pulling video/audio streams out of containers) usage
- * Logged from:
- * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp
- * frameworks/av/services/mediaanalytics/statsd_extractor.cpp
- */
-message MediametricsExtractorReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.ExtractorData extractor_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track MediaParser (parsing video/audio streams from containers) usage
- * Logged from:
- *
- * frameworks/av/services/mediametrics/statsd_mediaparser.cpp
- * frameworks/base/apex/media/framework/jni/android_media_MediaParserJNI.cpp
- */
-message MediametricsMediaParserReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
-
- // MediaParser specific data.
- /**
- * The name of the parser selected for parsing the media, or an empty string
- * if no parser was selected.
- */
- optional string parser_name = 4;
- /**
- * Whether the parser was created by name. 1 represents true, and 0
- * represents false.
- */
- optional int32 created_by_name = 5;
- /**
- * The parser names in the sniffing pool separated by "|".
- */
- optional string parser_pool = 6;
- /**
- * The fully qualified name of the last encountered exception, or an empty
- * string if no exception was encountered.
- */
- optional string last_exception = 7;
- /**
- * The size of the parsed media in bytes, or -1 if unknown. Note this value
- * contains intentional random error to prevent media content
- * identification.
- */
- optional int64 resource_byte_count = 8;
- /**
- * The duration of the media in milliseconds, or -1 if unknown. Note this
- * value contains intentional random error to prevent media content
- * identification.
- */
- optional int64 duration_millis = 9;
- /**
- * The MIME types of the tracks separated by "|".
- */
- optional string track_mime_types = 10;
- /**
- * The tracks' RFC 6381 codec strings separated by "|".
- */
- optional string track_codecs = 11;
- /**
- * Concatenation of the parameters altered by the client, separated by "|".
- */
- optional string altered_parameters = 12;
- /**
- * The video width in pixels, or -1 if unknown or not applicable.
- */
- optional int32 video_width = 13;
- /**
- * The video height in pixels, or -1 if unknown or not applicable.
- */
- optional int32 video_height = 14;
-}
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp
- */
-message MediametricsAudiopolicyReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioPolicyData audiopolicy_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone requests.
- * Logged from
- * frameworks/av/media/libaudioclient/AudioRecord.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp
- */
-message MediametricsAudiorecordReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioRecordData audiorecord_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/media/libnblog/ReportPerformance.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp
- */
-message MediametricsAudiothreadReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioThreadData audiothread_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/media/libaudioclient/AudioTrack.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp
- */
-message MediametricsAudiotrackReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.AudioTrackData audiotrack_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track information about DRM framework performance
- * Logged from
- * frameworks/av/drm/libmediadrm/DrmHal.cpp
- * frameworks/av/services/mediaanalytics/statsd_drm.cpp
- */
-message MediametricsMediadrmReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- // vendor+description tell about which DRM plugin is in use on this device
- optional string vendor = 5;
- optional string description = 6;
- // from frameworks/av/drm/libmediadrm/protos/metrics.proto
- optional bytes framework_stats = 7 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track information about the widevine DRM plugin performance
- * Logged from
- * vendor/widevine/libwvdrmengine/cdm/metrics
- * frameworks/av/services/mediaanalytics/statsd_drm.cpp
- */
-message MediametricsDrmWidevineReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional bytes vendor_specific_stats = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track information about recordings (e.g. camcorder)
- * Logged from
- * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp
- * frameworks/av/services/mediaanalytics/statsd_recorder.cpp
- */
-message MediametricsRecorderReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.RecorderData recorder_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track Media Player usage
- * Logged from:
- * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
- * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp
- */
-message MediametricsNuPlayerReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- optional android.stats.mediametrics.NuPlayerData nuplayer_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Track Legacy DRM usage
- * Logged from
- * frameworks/av/drm/drmserver/DrmManager.cpp
- */
-message MediametricsDrmManagerReported {
- optional int64 timestamp_nanos = 1;
- optional string package_name = 2;
- optional int64 package_version_code = 3;
- optional int64 media_apex_version = 4;
-
- enum Method {
- METHOD_NOT_FOUND = -1;
- GET_CONSTRAINTS = 0;
- GET_METADATA = 1;
- CAN_HANDLE = 2;
- PROCESS_DRM_INFO = 3;
- ACQUIRE_DRM_INFO = 4;
- SAVE_RIGHTS = 5;
- GET_ORIGINAL_MIME_TYPE = 6;
- GET_DRM_OBJECT_TYPE = 7;
- CHECK_RIGHTS_STATUS = 8;
- REMOVE_RIGHTS = 9;
- REMOVE_ALL_RIGHTS = 10;
- OPEN_CONVERT_SESSION = 11;
- OPEN_DECRYPT_SESSION = 12;
- }
-
- // plugin_id+description inform which Legacy DRM plugins are still in use on device
- optional string plugin_id = 5;
- optional string description = 6;
- optional Method method = 7;
- optional string mime_types = 8;
-
- optional int64 get_constraints_count = 9;
- optional int64 get_metadata_count = 10;
- optional int64 can_handle_count = 11;
- optional int64 process_drm_info_count = 12;
- optional int64 acquire_drm_info_count = 13;
- optional int64 save_rights_count = 14;
- optional int64 get_original_mime_type_count = 15;
- optional int64 get_drm_object_type_count = 16;
- optional int64 check_rights_status_count = 17;
- optional int64 remove_rights_count = 18;
- optional int64 remove_all_rights_count = 19;
- optional int64 open_convert_session_count = 20;
- optional int64 open_decrypt_session_count = 21;
-}
-
-/**
- * State of a dangerous permission requested by a package
- * Pulled from: StatsCompanionService
-*/
-message DangerousPermissionState {
- // Name of the permission
- optional string permission_name = 1;
-
- // Uid of the package
- optional int32 uid = 2 [(is_uid) = true];
-
- // Package requesting the permission
- optional string package_name = 3;
-
- // If the permission is granted to the uid
- optional bool is_granted = 4;
-
- // Permission flags as per android.content.pm.PermissionFlags
- optional int32 permission_flags = 5;
-}
-
-/**
- * Logs when a package is denied access to a device identifier based on the new access requirements.
- *
- * Logged from:
- * frameworks/base/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
- */
-message DeviceIdentifierAccessDenied {
- // The name of the package denied access to the requested device identifier.
- optional string package_name = 1;
-
- // The name of the device identifier method the package attempted to invoke.
- optional string method_name = 2;
-
- // True if the package is preinstalled.
- // Starting from Android 11, this boolean is not set and will always be false.
- optional bool is_preinstalled = 3 [deprecated = true];
-
- // True if the package is privileged.
- // Starting from Android 11, this boolean is not set and will always be false.
- optional bool is_priv_app = 4 [deprecated = true];
-}
-
-/**
- * Pulls the ongoing mainline install train version code.
- * Pulled from StatsCompanionService
- */
-message TrainInfo {
- optional int64 train_version_code = 1;
-
- optional TrainExperimentIds train_experiment_id = 2;
-
- optional string train_name = 3;
-
- enum Status {
- UNKNOWN = 0;
- INSTALL_REQUESTED = 1;
- INSTALL_STARTED = 2;
- INSTALL_STAGED_NOT_READY = 3;
- INSTALL_STAGED_READY = 4;
- INSTALL_SUCCESS = 5;
- // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH,
- // and INSTALL_FAILURE_COMMIT.
- INSTALL_FAILURE = 6 [deprecated = true];
- // This enum is for installs that are manually cancelled via the Manual Update UI.
- INSTALL_CANCELLED = 7;
- INSTALLER_ROLLBACK_REQUESTED = 8;
- INSTALLER_ROLLBACK_INITIATED = 9;
- INSTALLER_ROLLBACK_INITIATED_FAILURE = 10;
- INSTALLER_ROLLBACK_STAGED = 11;
- INSTALLER_ROLLBACK_STAGED_FAILURE = 12;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13;
- INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14;
- INSTALLER_ROLLBACK_SUCCESS = 15;
- INSTALLER_ROLLBACK_FAILURE = 16;
- INSTALLER_ROLLBACK_STAGED_CANCEL_REQUESTED = 17;
- INSTALLER_ROLLBACK_STAGED_CANCEL_SUCCESS = 18;
- INSTALLER_ROLLBACK_STAGED_CANCEL_FAILURE = 19;
- INSTALL_STAGED_CANCEL_REQUESTED = 20;
- INSTALL_STAGED_CANCEL_SUCCESS = 21;
- INSTALL_STAGED_CANCEL_FAILURE = 22;
- INSTALL_FAILURE_DOWNLOAD = 23;
- INSTALL_FAILURE_STATE_MISMATCH = 24;
- INSTALL_FAILURE_COMMIT = 25;
- REBOOT_TRIGGERED = 26;
- }
- optional Status status = 4;
-}
-
-/**
- * Logs the gesture stage changed event.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/
- */
-message AssistGestureStageReported {
- optional android.hardware.sensor.assist.AssistGestureStageEnum gesture_stage = 1;
-}
-
-/**
- * Logs the feedback type.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/
- */
-message AssistGestureFeedbackReported {
- // Whether or not the gesture was used.
- optional android.hardware.sensor.assist.AssistGestureFeedbackEnum feedback_type = 1;
-}
-
-/**
- * Logs the progress.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/
- */
-message AssistGestureProgressReported {
- // [0,100] progress for the assist gesture.
- optional int32 progress = 1;
-}
-
-/*
- * Information about the time zone data on a device.
- */
-message TimeZoneDataInfo {
- // A version identifier for the data set on device. e.g. "2018i"
- optional string tzdb_version = 1;
-}
-
-/**
- * Logs the GPU stats global health information.
- *
- * Logged from:
- * frameworks/native/services/gpuservice/gpustats/
- */
-message GpuStatsGlobalInfo {
- // Package name of the gpu driver.
- optional string driver_package_name = 1;
-
- // Version name of the gpu driver.
- optional string driver_version_name = 2;
-
- // Version code of the gpu driver.
- optional int64 driver_version_code = 3;
-
- // Build time of the gpu driver in UTC as seconds since January 1, 1970.
- optional int64 driver_build_time = 4;
-
- // Total count of the gl driver gets loaded.
- optional int64 gl_loading_count = 5;
-
- // Total count of the gl driver fails to be loaded.
- optional int64 gl_loading_failure_count = 6;
-
- // Total count of the Vulkan driver gets loaded.
- optional int64 vk_loading_count = 7;
-
- // Total count of the Vulkan driver fails to be loaded.
- optional int64 vk_loading_failure_count = 8;
-
- // Api version of the system Vulkan driver.
- optional int32 vulkan_version = 9;
-
- // Api version of the system CPU Vulkan driver.
- optional int32 cpu_vulkan_version = 10;
-
- // Api version of the system GLES driver.
- optional int32 gles_version = 11;
-
- // Total count of the angle driver gets loaded.
- optional int64 angle_loading_count = 12;
-
- // Total count of the angle driver fails to be loaded.
- optional int64 angle_loading_failure_count = 13;
-}
-
-/**
- * GPU driver loading time info.
- */
-message GpuDriverLoadingTime {
- // List of all the driver loading times for this app. The list size is
- // capped at 50.
- repeated int64 driver_loading_time = 1;
-}
-
-/**
- * Logs the GPU stats per app health information.
- *
- * Logged from:
- * frameworks/native/services/gpuservice/gpustats/
- */
-message GpuStatsAppInfo {
- // Package name of the application that loads the gpu driver. Total number
- // of different packages is capped at 100.
- optional string app_package_name = 1;
-
- // Version code of the gpu driver this app loads.
- optional int64 driver_version_code = 2;
-
- // gl driver loading time info.
- optional GpuDriverLoadingTime gl_driver_loading_time = 3
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // Vulkan driver loading time info.
- optional GpuDriverLoadingTime vk_driver_loading_time = 4
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // Angle driver loading time info.
- optional GpuDriverLoadingTime angle_driver_loading_time = 5
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // CPU Vulkan implementation is in use.
- optional bool cpu_vulkan_in_use = 6;
-
- // App is not doing pre-rotation correctly.
- optional bool false_prerotation = 7;
-
- // App creates GLESv1 context.
- optional bool gles_1_in_use = 8;
-}
-
-/*
- * Logs the size of the system ion heap.
- *
- * Pulled from StatsCompanionService.
- */
-message SystemIonHeapSize {
- // Deprecated due to limited support of ion stats in debugfs.
- // Use `IonHeapSize` instead.
- option deprecated = true;
-
- // Size of the system ion heap in bytes.
- // Read from debugfs.
- optional int64 size_in_bytes = 1;
-}
-
-/*
- * Logs the total size of the ion heap.
- *
- * Pulled from StatsCompanionService.
- */
-message IonHeapSize {
- // Total size of all ion heaps in kilobytes.
- // Read from: /sys/kernel/ion/total_heaps_kb.
- optional int32 total_size_kb = 1;
-}
-
-/*
- * Logs the per-process size of the system ion heap.
- *
- * Pulled from StatsCompanionService.
- */
-message ProcessSystemIonHeapSize {
- // The uid if available. -1 means not available.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The process name (from /proc/PID/cmdline).
- optional string process_name = 2;
-
- // Sum of sizes of all allocations.
- optional int32 total_size_in_kilobytes = 3;
-
- // Number of allocations.
- optional int32 allocation_count = 4;
-
- // Size of the largest allocation.
- optional int32 max_size_in_kilobytes = 5;
-}
-
-/**
- * Push network stack events.
- *
- * Log from:
- * frameworks/base/packages/NetworkStack/
- */
-message NetworkStackReported {
- // The id that indicates the event reported from NetworkStack.
- optional int32 event_id = 1;
- // The data for the reported events.
- optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES];
-}
-
-/**
- * Logs the apps that are installed on the external storage.
- * Pulled from:
- * StatsCompanionService
- */
-message AppsOnExternalStorageInfo {
- // The type of the external storage.
- optional android.stats.storage.ExternalStorageType external_storage_type = 1;
- // The name of the package that is installed on the external storage.
- optional string package_name = 2;
-}
-
-/**
- * Logs the settings related to Face.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/stats
- */
-message FaceSettings {
- // Whether or not face unlock is allowed on Keyguard.
- optional bool unlock_keyguard_enabled = 1;
- // Whether or not face unlock dismisses the Keyguard.
- optional bool unlock_dismisses_keyguard = 2;
- // Whether or not face unlock requires attention.
- optional bool unlock_attention_required = 3;
- // Whether or not face unlock is allowed for apps (through BiometricPrompt).
- optional bool unlock_app_enabled = 4;
- // Whether or not face unlock always requires user confirmation.
- optional bool unlock_always_require_confirmation = 5;
- // Whether or not a diverse set of poses are required during enrollment.
- optional bool unlock_diversity_required = 6;
-}
-
-/**
- * Logs cooling devices maintained by the kernel.
- *
- * Pulled from StatsCompanionService.java
- */
-message CoolingDevice {
- // The type of cooling device being reported. Eg. CPU, GPU...
- optional android.os.CoolingTypeEnum device_location = 1;
- // The name of the cooling device source. Eg. CPU0
- optional string device_name = 2;
- // Current throttle state of the cooling device. The value can any unsigned
- // integer between 0 and max_state defined in its driver. 0 means device is
- // not in throttling, higher value means deeper throttling.
- optional int32 state = 3;
-}
-
-/**
- * Intelligence has several counter-type events that don't warrant a
- * full separate atom. These are primarily API call counters but also include
- * counters for feature usage and specific failure modes.
- *
- * Logged from the Intelligence mainline module.
- */
-message IntelligenceEventReported {
- // The event type.
- optional android.stats.intelligence.EventType event_id = 1;
- // Success, failure.
- optional android.stats.intelligence.Status status = 2;
- // How many times the event occured (to report a batch of high frequency events).
- optional int32 count = 3;
- // How long the event took (sum of durations if count > 1)
- optional int64 duration_millis = 4;
-}
-
-/**
- * Logs when Car Power state changed.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/CarStatsLog.java
- */
-message CarPowerStateChanged {
- // States come from CpmsState in CarPowerManagementService.java.
- enum State {
- WAIT_FOR_VHAL = 0;
- ON = 1;
- SHUTDOWN_PREPARE = 2;
- WAIT_FOR_FINISH = 3;
- SUSPEND = 4;
- SIMULATE_SLEEP = 5;
- }
- optional State state = 1;
-}
-
-/**
- * Logs when Car User Hal is requested to switch/create/remove user.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalModifyUserRequestReported {
- // Request id for the request.
- optional int32 request_id = 1;
- // Request type.
- enum RequestType {
- UNKNOWN = 0;
- // Car user manager requested user switch.
- SWITCH_REQUEST_ANDROID = 1;
- // OEM requested User switch.
- SWITCH_REQUEST_OEM = 2;
- // Hal switch requested after android switch using activity manager.
- SWITCH_REQUEST_LEGACY = 3;
- // Create User
- CREATE_REQUEST = 4;
- // Remove User
- REMOVE_REQUEST = 5;
- }
- optional RequestType request_type = 2;
- // Android User id of the current user which can only be 0, 10, 11 and so on.
- // -1 if not available.
- optional int32 user_id = 3;
- // VHAL flags of the current user. (-1 if not available)
- optional int32 user_flags = 4;
- // Android User id of the target user for switch/create/remove. It can only
- // be 0, 10, 11 and so on. -1 if not available.
- optional int32 target_user_id = 5;
- // VHAL flags of the target user for switch/create/remove. (-1 if not available)
- optional int32 target_user_flags = 6;
- // Request timeout Milliseconds (-1 if not available)
- optional int32 timeout_millis = 7;
-}
-
-/**
- * Logs when Car User Hal responds to switch/create user request.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalModifyUserResponseReported {
- // Request id of the request associated with the response.
- optional int32 request_id = 1;
- // Car user hal callback status.
- enum CallbackStatus {
- UNKNOWN = 0;
- // Hal response was invalid.
- INVALID = 1;
- // Hal response was ok.
- OK = 2;
- // Hal timeout during set call.
- HAL_SET_TIMEOUT = 3;
- // Hal response timeout.
- HAL_RESPONSE_TIMEOUT = 4;
- // Hal responded with wrong info.
- WRONG_HAL_RESPONSE = 5;
- // Hal is processing multiple requests simultaneously.
- CONCURRENT_OPERATION = 6;
- }
- optional CallbackStatus callback_status = 2;
-
- // Hal request status for user switch/create/remove.
- enum HalRequestStatus {
- UNSPECIFIED = 0;
- // Hal request for user switch/create is successful.
- SUCCESS = 1;
- // Hal request for user switch/create failed.
- FAILURE = 2;
- }
- optional HalRequestStatus request_status = 3;
-}
-
-/**
- * Logs when post switch response is posted to Car User Hal.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalPostSwitchResponseReported {
- // Request id.
- optional int32 request_id = 1;
-
- // Android user switch status.
- enum UserSwitchStatus {
- UNKNOWN = 0;
- // Android user switch is successful.
- SUCCESS = 1;
- // Android user switch failed.
- FAILURE = 2;
- }
- optional UserSwitchStatus switch_status = 2;
-}
-
-/**
- * Logs when initial user information is requested from Car User Hal.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalInitialUserInfoRequestReported {
- // Request id for the request.
- optional int32 request_id = 1;
-
- // Request type for initial user information.
- enum InitialUserInfoRequestType {
- UNKNOWN = 0;
- // At the first time Android was booted (or after a factory reset).
- FIRST_BOOT = 1;
- // At the first time Android was booted after the system was updated.
- FIRST_BOOT_AFTER_OTA = 2;
- // When Android was booted "from scratch".
- COLD_BOOT = 3;
- // When Android was resumed after the system was suspended to memory.
- RESUME = 4;
- }
- optional InitialUserInfoRequestType request_type = 2;
- // Request timeout Milliseconds (-1 if not available)
- optional int32 timeout_millis = 3;
-}
-
-/**
- * Logs when Car User Hal responds to initial user information requests.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalInitialUserInfoResponseReported {
- // Request id of the request associated with the response.
- optional int32 request_id = 1;
- // Car user hal callback status.
- enum CallbackStatus {
- UNKNOWN = 0;
- // Hal response was invalid.
- INVALID = 1;
- // Hal response was ok.
- OK = 2;
- // Hal timeout during set call.
- HAL_SET_TIMEOUT = 3;
- // Hal response timeout.
- HAL_RESPONSE_TIMEOUT = 4;
- // Hal responded with wrong info.
- WRONG_HAL_RESPONSE = 5;
- // Hal is processing multiple requests simultaneously.
- CONCURRENT_OPERATION = 6;
- }
- optional CallbackStatus callback_status = 2;
- // Response for initial user information request.
- enum InitialUserInfoResponseAction {
- UNSPECIFIED = 0;
- // Let the Android System decide what to do.
- DEFAULT = 1;
- // Switch to an existing Android user.
- SWITCH = 2;
- // Create a new Android user (and switch to it).
- CREATE = 3;
- }
- optional InitialUserInfoResponseAction response_action = 3;
- // Android User id of the target user which can only be 0, 10, 11 and so on.
- // -1 if not available.
- optional int32 target_user = 4;
- // VHAL flags of the current user. (-1 if not available)
- optional int32 target_user_flags = 5;
- // User locales
- optional string user_locales = 6;
-}
-
-/**
- * Logs when set user association is requested from Car User Hal.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalUserAssociationRequestReported {
- // Request id for the request.
- optional int32 request_id = 1;
- // Request type.
- enum RequestType {
- UNKNOWN = 0;
- // For setting user association information.
- SET = 1;
- // For getting user association information.
- GET = 2;
- }
- optional RequestType request_type = 2;
- // Android User id of the current user which can only be 0, 10, 11 and so on.
- // -1 if not available.
- optional int32 current_user_id = 3;
- // VHAL flags of the current user. (-1 if not available)
- optional int32 current_user_flags = 4;
- // Number of the set associations requested.
- optional int32 number_associations = 5;
- // Concatenated string for the types from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_types = 6;
- // Concatenated string for the values from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_values = 7;
-}
-
-/**
- * Logs when Car User Hal responds to set user association requests.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/hal/UserHalService.java
- */
-message CarUserHalSetUserAssociationResponseReported {
- // Request id of the request associated with the response.
- optional int32 request_id = 1;
- // Car user hal callback status.
- enum CallbackStatus {
- UNKNOWN = 0;
- // Hal response was invalid.
- INVALID = 1;
- // Hal response was ok.
- OK = 2;
- // Hal timeout during set call.
- HAL_SET_TIMEOUT = 3;
- // Hal response timeout.
- HAL_RESPONSE_TIMEOUT = 4;
- // Hal responded with wrong info.
- WRONG_HAL_RESPONSE = 5;
- // Hal is processing multiple requests simultaneously.
- CONCURRENT_OPERATION = 6;
- }
- optional CallbackStatus callback_status = 2;
- // Number of the set associations in the response.
- optional int32 number_associations = 3;
- // Concatenated string for the types from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_types = 4;
- // Concatenated string for the values from set associations request.
- // This is a string converted from an array of integers.
- optional string user_identification_association_values = 5;
-}
-
-/**
- * Logs whether GarageMode is entered.
- *
- * Logged from:
- * packages/services/Car/service/src/com/android/car/CarStatsLog.java
- */
-message GarageModeInfo {
- // Whether GarageMode is entered.
- optional bool is_garage_mode = 1;
-}
-
-/**
- * Historical app ops data per package.
- */
-message AppOps {
- // Uid of the package requesting the op
- optional int32 uid = 1 [(is_uid) = true];
-
- // Name of the package performing the op
- optional string package_name = 2;
-
- // operation id
- optional android.app.AppOpEnum op_id = 3 [default = APP_OP_NONE];
-
- // The number of times the op was granted while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_granted_count = 4;
-
- // The number of times the op was granted while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_granted_count = 5;
-
- // The number of times the op was rejected while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_rejected_count = 6;
-
- // The number of times the op was rejected while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_rejected_count = 7;
-
- // For long-running operations, total duration of the operation
- // while the app was in the foreground (only for trusted requests)
- optional int64 trusted_foreground_duration_millis = 8;
-
- // For long-running operations, total duration of the operation
- // while the app was in the background (only for trusted requests)
- optional int64 trusted_background_duration_millis = 9;
-
- // Whether AppOps is guarded by Runtime permission
- optional bool is_runtime_permission = 10;
-}
-
-/**
- * Historical app ops data per package and attribution tag.
- */
-message AttributedAppOps {
- // Uid of the package requesting the op
- optional int32 uid = 1 [(is_uid) = true];
-
- // Name of the package performing the op
- optional string package_name = 2;
-
- // tag; provided by developer when accessing related API, limited at 50 chars by API.
- // Attributions must be provided through manifest using <attribution> tag available in R and
- // above.
- optional string tag = 3;
-
- // operation id
- optional android.app.AppOpEnum op = 4 [default = APP_OP_NONE];
-
- // The number of times the op was granted while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_granted_count = 5;
-
- // The number of times the op was granted while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_granted_count = 6;
-
- // The number of times the op was rejected while the app was in the
- // foreground (only for trusted requests)
- optional int64 trusted_foreground_rejected_count = 7;
-
- // The number of times the op was rejected while the app was in the
- // background (only for trusted requests)
- optional int64 trusted_background_rejected_count = 8;
-
- // For long-running operations, total duration of the operation
- // while the app was in the foreground (only for trusted requests)
- optional int64 trusted_foreground_duration_millis = 9;
-
- // For long-running operations, total duration of the operation
- // while the app was in the background (only for trusted requests)
- optional int64 trusted_background_duration_millis = 10;
-
- // Whether AppOps is guarded by Runtime permission
- optional bool is_runtime_permission = 11;
-
- // Sampling rate used on device, from 0 to 100
- optional int32 sampling_rate = 12;
-}
-
-/**
- * Location Manager API Usage information(e.g. API under usage,
- * API call's parameters).
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/LocationManagerService.java
- */
-message LocationManagerApiUsageReported {
-
- // Indicating if usage starts or usage ends.
- optional android.stats.location.UsageState state = 1;
-
- // LocationManagerService's API in use.
- // We can identify which API from LocationManager is
- // invoking current LMS API by the combination of
- // API parameter(e.g. is_listener_null, is_intent_null,
- // is_location_request_null)
- optional android.stats.location.LocationManagerServiceApi api_in_use = 2;
-
- // Name of the package calling the API.
- optional string calling_package_name = 3;
-
- // Type of the location provider.
- optional android.stats.location.ProviderType provider = 4;
-
- // Quality of the location request
- optional android.stats.location.LocationRequestQuality quality = 5;
-
- // The desired interval for active location updates, in milliseconds.
- // Bucketized to reduce cardinality.
- optional android.stats.location.LocationRequestIntervalBucket bucketized_interval = 6;
-
- // Minimum distance between location updates, in meters.
- // Bucketized to reduce cardinality.
- optional android.stats.location.SmallestDisplacementBucket
- bucketized_smallest_displacement = 7;
-
- // The number of location updates.
- optional int64 num_updates = 8;
-
- // The request expiration time, in millisecond since boot.
- // Bucketized to reduce cardinality.
- optional android.stats.location.ExpirationBucket
- bucketized_expire_in = 9;
-
- // Type of Callback passed in for this API.
- optional android.stats.location.CallbackType callback_type = 10;
-
- // The radius of the central point of the alert
- // region, in meters. Only for API REQUEST_GEOFENCE.
- // Bucketized to reduce cardinality.
- optional android.stats.location.GeofenceRadiusBucket bucketized_radius = 11;
-
- // Activity Importance of API caller.
- // Categorized to 3 types that are interesting from location's perspective.
- optional android.stats.location.ActivityImportance activiy_importance = 12;
-}
-
-/**
- * Information about a permission grant or denial made by user inside ReviewPermissionsFragment
- */
-message ReviewPermissionsFragmentResultReported {
- // unique value identifying a permission group change. A permission group change might result
- // in multiple of these atoms
- optional int64 change_id = 1;
-
- // UID of package the permission belongs to
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package the permission belongs to
- optional string package_name = 3;
-
- // The permission to be granted
- optional string permission_name = 4;
-
- // The result of the permission grant
- optional bool permission_granted = 5;
-}
-
-/**
-* Information about results of permission upgrade by RuntimePermissionsUpgradeController
-* Logged from: RuntimePermissionUpdgradeController
-*/
-message RuntimePermissionsUpgradeResult {
- // Permission granted as result of upgrade
- optional string permission_name = 1;
-
- // UID of package granted permission
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package granted permission
- optional string package_name = 3;
-}
-
-/**
-* Information about a buttons presented in GrantPermissionsActivty and choice made by user
-*/
-message GrantPermissionsActivityButtonActions {
- // Permission granted as result of upgrade
- optional string permission_group_name = 1;
-
- // UID of package granted permission
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package requesting permission
- optional string package_name = 3;
-
- // Buttons presented in the dialog - bit flags, bit numbers are in accordance with
- // LABEL_ constants in GrantPermissionActivity.java
- optional int32 buttons_presented = 4;
-
- // Button clicked by user - same as bit flags in buttons_presented with only single bit set
- optional int32 button_clicked = 5;
-
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 6;
-}
-
-/**
- * Information about LocationAccessCheck notification presented to user
- */
-message LocationAccessCheckNotificationAction {
-
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // Uid of package for which location access check is presented
- optional int32 package_uid = 2;
-
- // Name of package for which location access check is presented
- optional string package_name = 3;
-
- enum Result {
- UNDEFINED = 0;
- // notification was presented to the user
- NOTIFICATION_PRESENTED = 1;
- // notification was declined by the user
- NOTIFICATION_DECLINED = 2;
- // notification was clicked by the user
- NOTIFICATION_CLICKED = 3;
- }
-
- // View / interaction recorded
- optional Result result = 4;
-}
-
-/**
- * Information about a permission grant or revoke made by user inside AppPermissionFragment
- */
-message AppPermissionFragmentActionReported {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // unique value identifying a permission group change. A permission group change might result
- // in multiple of these atoms
- optional int64 change_id = 2;
-
- // UID of package the permission belongs to
- optional int32 uid = 3 [(is_uid) = true];
-
- // Name of package the permission belongs to
- optional string package_name = 4;
-
- // The permission to be granted
- optional string permission_name = 5;
-
- // The result of the permission grant
- optional bool permission_granted = 6;
-
- // State of Permission Flags after grant as per android.content.pm.PermissionFlags
- optional int32 permission_flags = 7;
-
- enum Button {
- UNDEFINED = 0;
- // Allow button
- ALLOW = 1;
- // Deny button
- DENY = 2;
- // Ask every time button
- ASK_EVERY_TIME = 3;
- // Allow all the time button
- ALLOW_ALWAYS = 4;
- // Allow only while using the app button
- ALLOW_FOREGROUND = 5;
- // Same is Deny button but shown in while in use dialog
- DENY_FOREGROUND = 6;
- }
-
- // Button pressed in the dialog
- optional Button button_pressed = 8;
-}
-
-/**
-* Information about a AppPermissionFragment viewed by user
-*/
-message AppPermissionFragmentViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- // Permission group viewed
- optional string permission_group_name = 4;
-}
-
-/**
-* Information about a AppPermissionGroupsFragment viewed by user. Fragment has been renamed, but
-* the log retains the old fragment name.
-*/
-message AppPermissionsFragmentViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // id which identifies single view as every view might have several logging records
- // with different package information attached
- optional int64 view_id = 2;
-
- // Permission group viewed
- optional string permission_group_name = 3;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 4 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 5;
-
- // Category in which permission is included
- enum Category {
- UNDEFINED = 0;
- ALLOWED = 1;
- ALLOWED_FOREGROUND = 2;
- DENIED = 3;
- }
- optional Category category = 6;
-}
-/**
-* Information about a PermissionAppsFragment viewed by user.
-* Logged from ui/handheld/PermissionAppsFragment.java
-*/
-message PermissionAppsFragmentViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // id which identifies single view as every view might have several logging records
- // with different package information attached
- optional int64 view_id = 2;
-
- // Permission group viewed
- optional string permission_group_name = 3;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 4 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 5;
-
- // Category in which app is included
- enum Category {
- UNDEFINED = 0;
- ALLOWED = 1;
- ALLOWED_FOREGROUND = 2;
- DENIED = 3;
- }
- optional Category category = 6;
-}
-
-/**
-* Log that the Auto Revoke notification has been clicked
-* Logged from ui/ManagePermissionsActivity
-*/
-message AutoRevokeNotificationClicked {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-}
-
-/**
-* Log that an app has been displayed on the auto revoke page, and lists one permission that was
-* auto revoked for it.
-* Logged from ui/handheld/AutoRevokeFragment
-*/
-message AutoRevokeFragmentAppViewed {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- // The name of a permission group that has been revoked
- optional string permission_group_name = 4;
-
- // The age of the app- more than three months old, or more than six months
- enum Age {
- UNDEFINED = 0;
- NEWER_BUCKET = 1;
- OLDER_BUCKET = 2;
- }
-
- // How long the app has been unused. Currently, newer bucket is 3 months, older is 6 months
- optional Age age = 5;
-}
-
-/**
-* Log that the user has interacted with an app on the auto revoke fragment
-* Logged from ui/handheld/AutoRevokeFragment
-*/
-message AutoRevokedAppInteraction {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- enum Action {
- UNDEFINED = 0;
- REMOVE = 1;
- OPEN = 2;
- APP_INFO = 3;
- PERMISSIONS = 4;
- REMOVE_IN_SETTINGS = 5;
- OPEN_IN_SETTINGS = 6;
- }
-
- // The action the user took to interact with the app
- optional Action action = 4;
-}
-
-/**
-* Log that the AppPermissionGroupsFragment has been interacted with for the possible purposes of
-* auto revoke, or that the auto revoke switch has been changed
-* Logged from ui/handheld/AppPermissionGroupsFragment
- */
-message AppPermissionGroupsFragmentAutoRevokeAction {
- // id which identifies single session of user interacting with permission controller
- optional int64 session_id = 1;
-
- // UID of package for which permissions are viewed
- optional int32 uid = 2 [(is_uid) = true];
-
- // Name of package for which permissions are viewed
- optional string package_name = 3;
-
- enum Action {
- UNDEFINED = 0;
- OPENED_FOR_AUTO_REVOKE = 1;
- OPENED_FROM_INTENT = 2;
- SWITCH_ENABLED = 3;
- SWITCH_DISABLED = 4;
- }
-
- // The action the user took to interact with the fragment
- optional Action action = 4;
-}
-
-/**
- * Logs when there is a smart selection related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message TextSelectionEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the annotator model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // Index of this event in a session.
- optional int32 event_index = 5;
-
- // Entity type that is involved.
- optional string entity_type = 6;
-
- // Relative word index of the start of the selection.
- optional int32 relative_word_start_index = 7;
-
- // Relative word (exclusive) index of the end of the selection.
- optional int32 relative_word_end_index = 8;
-
- // Relative word index of the start of the smart selection.
- optional int32 relative_suggested_word_start_index = 9;
-
- // Relative word (exclusive) index of the end of the smart selection.
- optional int32 relative_suggested_word_end_index = 10;
-
- // Name of source package.
- optional string package_name = 11;
-
- // Name of the LangID model that is involved in this event.
- optional string langid_model_name = 12;
-}
-
-/**
- * Logs when there is a smart linkify related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message TextLinkifyEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the annotator model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // Index of this event in a session.
- optional int32 event_index = 5;
-
- // Entity type that is involved.
- optional string entity_type = 6;
-
- // Number of links detected.
- optional int32 num_links = 7;
-
- // The total length of all links.
- optional int32 linked_text_length = 8;
-
- // Length of input text.
- optional int32 text_length = 9;
-
- // Time spent on generating links in ms.
- optional int64 latency_millis = 10;
-
- // Name of source package.
- optional string package_name = 11;
-
- // Name of the LangID model that is involved in this event.
- optional string langid_model_name = 12;
-}
-
-/**
- * Logs when there is a conversation actions related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message ConversationActionsEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the actions model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // The first entity type that is involved.
- optional string first_entity_type = 5;
-
- // The second entity type that is involved.
- optional string second_entity_type = 6;
-
- // The third entity type that is involved.
- optional string third_entity_type = 7;
-
- // The score of the first entity type.
- optional float score = 8;
-
- // Name of source package.
- optional string package_name = 9;
-
- // Name of the annotator model that is involved in this event.
- optional string annotator_model_name = 10;
-
- // Name of the LangID model that is involved in this event.
- optional string langid_model_name = 11;
-}
-
-/**
- * Logs when there is a language detection related event.
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java
- * Logged from: TextClassifierEventLogger.java
- */
-message LanguageDetectionEvent {
- // A session ID.
- optional string session_id = 1;
-
- // Event type of this event.
- optional android.stats.textclassifier.EventType event_type = 2;
-
- // Name of the language detection model that is involved in this event.
- optional string model_name = 3;
-
- // Type of widget that was involved in triggering this event.
- optional android.stats.textclassifier.WidgetType widget_type = 4;
-
- // Detected language.
- optional string language_tag = 5;
-
- // Score of the detected language.
- optional float score = 6;
-
- // Position of this action.
- optional int32 action_index = 7;
-
- // Name of source package.
- optional string package_name = 8;
-}
-
-/**
- * Information about an OTA update attempt by update_engine.
- * Logged from platform/system/update_engine/metrics_reporter_android.cc
- */
-message UpdateEngineUpdateAttemptReported {
- // The number of attempts for the update engine to apply a given payload.
- optional int32 attempt_number = 1;
-
- optional android.stats.otaupdate.PayloadType payload_type = 2;
-
- // The total time in minutes for the update engine to apply a given payload.
- // The time is calculated by calling clock_gettime() / CLOCK_BOOTTIME; and
- // it's increased when the system is sleeping.
- optional int32 duration_boottime_in_minutes = 3;
-
- // The total time in minutes for the update engine to apply a given payload.
- // The time is calculated by calling clock_gettime() / CLOCK_MONOTONIC_RAW;
- // and it's not increased when the system is sleeping.
- optional int32 duration_monotonic_in_minutes = 4;
-
- // The size of the payload in MiBs.
- optional int32 payload_size_mib = 5;
-
- // The attempt result reported by the update engine for an OTA update.
- optional android.stats.otaupdate.AttemptResult attempt_result = 6;
-
- // The error code reported by the update engine after an OTA update attempt
- // on A/B devices.
- optional android.stats.otaupdate.ErrorCode error_code = 7;
-
- // The build fingerprint of the source system. The value is read from a
- // system property when the device takes the update. e.g.
- // Android/aosp_sailfish/sailfish:10/QP1A.190425.004/5507117:userdebug/test-keys
- optional string source_fingerprint = 8;
-
- // Size of super partition.
- optional int64 super_partition_size_bytes = 9;
-
- // Size of current slot within the super partition.
- optional int64 slot_size_bytes = 10;
-
- // Free space available in the super partition.
- optional int64 super_free_space_bytes = 11;
-}
-
-/**
- * Information about all the attempts the device make before finishing the
- * successful update.
- * Logged from platform/system/update_engine/metrics_reporter_android.cc
- */
-message UpdateEngineSuccessfulUpdateReported {
- // The number of attempts for the update engine to apply the payload for a
- // successful update.
- optional int32 attempt_count = 1;
-
- optional android.stats.otaupdate.PayloadType payload_type = 2;
-
- optional int32 payload_size_mib = 3;
-
- // The total number of bytes downloaded by update_engine since the last
- // successful update.
- optional int32 total_bytes_downloaded_mib = 4;
-
- // The ratio in percentage of the over-downloaded bytes compared to the
- // total bytes needed to successfully install the update. e.g. 200 if we
- // download 200MiB in total for a 100MiB package.
- optional int32 download_overhead_percentage = 5;
-
- // The total time in minutes for the update engine to apply the payload for a
- // successful update.
- optional int32 total_duration_minutes = 6;
-
- // The number of reboot of the device during a successful update.
- optional int32 reboot_count = 7;
-}
-
-/**
- * Reported when the RebootEscrow HAL has attempted to recover the escrowed
- * key to indicate whether it was successful or not.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
- */
-message RebootEscrowRecoveryReported {
- optional bool successful = 1;
-}
-
-/**
- * Global display pipeline metrics reported by SurfaceFlinger.
- * Pulled from:
- * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
- */
-message SurfaceflingerStatsGlobalInfo {
- // Total number of frames presented during the tracing period
- optional int64 total_frames = 1;
- // Total number of frames missed
- optional int64 missed_frames = 2;
- // Total number of frames that fell back to client composition
- optional int64 client_composition_frames = 3;
- // Total time the display was turned on
- optional int64 display_on_millis = 4;
- // Total time that was spent performing animations.
- // This is derived from the present-to-present layer histogram
- optional int64 animation_millis = 5;
- // Total number of event connections tracked by SurfaceFlinger at the time
- // of this pull. If this number grows prohibitively large, then this can
- // cause jank due to resource contention.
- optional int32 event_connection_count = 6;
- // Set of timings measured from when SurfaceFlinger began compositing a
- // frame, until the frame was requested to be presented to the display. This
- // measures SurfaceFlinger's total CPU walltime on the critical path per
- // frame.
- optional FrameTimingHistogram frame_duration = 7
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when SurfaceFlinger first began using the
- // GPU to composite a frame, until the GPU has finished compositing that
- // frame. This measures the total additional time SurfaceFlinger needed to
- // perform due to falling back into GPU composition.
- optional FrameTimingHistogram render_engine_timing = 8
- [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-/**
- * Per-layer display pipeline metrics reported by SurfaceFlinger.
- * The number of layers uploaded will be restricted due to size limitations.
- * Pulled from:
- * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
- */
-message SurfaceflingerStatsLayerInfo {
- // The layer for this set of metrics
- // For now we can infer that the package name is included in the layer
- // name.
- optional string layer_name = 1;
- // Total number of frames presented
- optional int64 total_frames = 2;
- // Total number of dropped frames while latching a buffer for this layer.
- optional int64 dropped_frames = 3;
- // Set of timings measured between successive presentation timestamps.
- optional FrameTimingHistogram present_to_present = 4
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when an app queued a buffer for
- // presentation, until the buffer was actually presented to the
- // display.
- optional FrameTimingHistogram post_to_present = 5
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when a buffer is ready to be presented,
- // until the buffer was actually presented to the display.
- optional FrameTimingHistogram acquire_to_present = 6
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when a buffer was latched by
- // SurfaceFlinger, until the buffer was presented to the display
- optional FrameTimingHistogram latch_to_present = 7
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from the desired presentation to the actual
- // presentation time
- optional FrameTimingHistogram desired_to_present = 8
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Set of timings measured from when an app queued a buffer for
- // presentation, until the buffer was ready to be presented.
- optional FrameTimingHistogram post_to_acquire = 9
- [(android.os.statsd.log_mode) = MODE_BYTES];
- // Frames missed latch because the acquire fence didn't fire
- optional int64 late_acquire_frames = 10;
- // Frames latched early because the desired present time was bad
- optional int64 bad_desired_present_frames = 11;
-}
-
-/**
- * Histogram of frame counts bucketed by time in milliseconds.
- * Because of size limitations, we hard-cap the number of buckets, with
- * buckets for corresponding to larger milliseconds being less precise.
- */
-message FrameTimingHistogram {
- // Timings in milliseconds that describes a set of histogram buckets
- repeated int32 time_millis_buckets = 1;
- // Number of frames that match to each time_millis, i.e. the bucket
- // contents
- // It's required that len(time_millis) == len(frame_count)
- repeated int64 frame_counts = 2;
-}
-
-/**
- * Janky event as reported by SurfaceFlinger.
- * This event is intended to be consumed by a Perfetto subscriber for
- * automated trace collection.
- *
- * Logged from:
- * frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
- */
-message DisplayJankReported {
- // Informational field for how long the janky event lasted in milliseconds
- optional int64 event_duration_millis = 1;
- // Number of frame deadlines missed, where SurfaceFlinger failed to update
- // the display on time.
- optional int32 present_deadlines_missed = 2;
-}
-
-/**
- * Information about camera facing and API level usage.
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java
- */
-message CameraActionEvent {
- // Camera session duration
- optional int64 duration_millis = 1;
-
- // Camera API level used
- optional int32 api_level = 2;
-
- // Name of client package
- optional string package_name = 3;
-
- // Camera facing
- enum Facing {
- UNKNOWN = 0;
- BACK = 1;
- FRONT = 2;
- EXTERNAL = 3;
- }
- optional Facing facing = 4;
-}
-
-/**
- * Logs when a compatibility change is affecting an app.
- *
- * Logged from:
- * frameworks/base/core/java/android/app/AppCompatCallbacks.java and
- * frameworks/base/services/core/java/com/android/server/compat/PlatformCompat.java
- */
-message AppCompatibilityChangeReported {
- // The UID of the app being affected by the compatibilty change.
- optional int32 uid = 1 [(is_uid) = true];
-
- // The ID of the change affecting the app.
- optional int64 change_id = 2;
-
- enum State {
- UNKNOWN_STATE = 0;
- ENABLED = 1;
- DISABLED = 2;
- LOGGED = 3;
- }
-
- // The state of the change - if logged from gating whether it was enabled or disabled, or just
- // logged otherwise.
- optional State state = 3;
-
- enum Source {
- UNKNOWN_SOURCE = 0;
- APP_PROCESS = 1;
- SYSTEM_SERVER = 2;
- }
-
- // Where it was logged from.
- optional Source source = 4;
-
-}
-
-/**
- * Logged from
- * external/perfetto/src/perfetto_cmd/perfetto_cmd.cc
- */
-message PerfettoUploaded {
- enum Event {
- PERFETTO_UNDEFINED = 0;
- PERFETTO_TRACE_BEGIN = 1;
- PERFETTO_BACKGROUND_TRACE_BEGIN = 2;
- PERFETTO_ON_CONNECT = 3;
- PERFETTO_ON_TRACING_DISABLED = 4;
- PERFETTO_UPLOAD_DROPBOX_BEGIN = 5;
- PERFETTO_UPLOAD_DROPBOX_SUCCESS = 6;
- PERFETTO_UPLOAD_DROPBOX_FAILURE = 7;
- PERFETTO_UPLOAD_INCIDENT_BEGIN = 8;
- PERFETTO_UPLOAD_INCIDENT_SUCCESS = 9;
- PERFETTO_UPLOAD_INCIDENT_FAILURE = 10;
- PERFETTO_FINALIZE_TRACE_AND_EXIT = 11;
- PERFETTO_TRIGGER_BEGIN = 12;
- PERFETTO_TRIGGER_SUCCESS = 13;
- PERFETTO_TRIGGER_FAILURE = 14;
- PERFETTO_HIT_GUARDRAILS = 15;
- PERFETTO_ON_TIMEOUT = 16;
- PERFETTO_NOT_UPLOADING_EMPTY_TRACE = 17;
- }
-
- // Which stage of the pipeline we are reporting from.
- optional Event event = 1;
-
- // UUID matching the one set inside the SystemInfo trace packet.
- optional int64 trace_uuid_lsb = 2;
- optional int64 trace_uuid_msb = 3;
-}
-
-/**
- * Pulls client metrics on data transferred via Vehicle Maps Service.
- * Metrics are keyed by uid + layer.
- *
- * Pulled from:
- * packages/services/Car/service/src/com/android/car/stats/CarStatsService.java
- */
-message VmsClientStats {
- // UID of the VMS client app
- optional int32 uid = 1 [(is_uid) = true];
-
- // VMS layer definition
- optional int32 layer_type = 2;
- optional int32 layer_channel = 3;
- optional int32 layer_version = 4;
-
- // Bytes and packets sent by the client for the layer
- optional int64 tx_bytes = 5;
- optional int64 tx_packets = 6;
-
- // Bytes and packets received by the client for the layer
- optional int64 rx_bytes = 7;
- optional int64 rx_packets = 8;
-
- // Bytes and packets dropped due to client error
- optional int64 dropped_bytes = 9;
- optional int64 dropped_packets = 10;
-}
-
-/**
- * State of a dangerous permission requested by a package - sampled
- * Pulled from: StatsCompanionService.java with data obtained from PackageManager API
-*/
-message DangerousPermissionStateSampled {
- // Name of the permission
- optional string permission_name = 1;
-
- // Uid of the package
- optional int32 uid = 2 [(is_uid) = true];
-
- // If the permission is granted to the uid
- optional bool is_granted = 3;
-
- // Permission flags as per android.content.pm.PermissionFlags
- optional int32 permission_flags = 4;
-}
-
-/**
- * HWUI stats for a given app.
- */
-message GraphicsStats {
- // The package name of the app
- optional string package_name = 1;
-
- // The version code of the app
- optional int64 version_code = 2;
-
- // The start & end timestamps in UTC as
- // milliseconds since January 1, 1970
- // Compatible with java.util.Date#setTime()
- optional int64 start_millis = 3;
-
- optional int64 end_millis = 4;
-
- // HWUI renders pipeline type: GL (1) or Vulkan (2).
- enum PipelineType {
- UNKNOWN = 0;
- GL = 1;
- VULKAN = 2;
- }
-
- // HWUI renders pipeline type: GL or Vulkan.
- optional PipelineType pipeline = 5;
-
- // Distinct frame count.
- optional int32 total_frames = 6;
-
- // Number of "missed vsync" events.
- optional int32 missed_vsync_count = 7;
-
- // Number of frames in triple-buffering scenario (high input latency)
- optional int32 high_input_latency_count = 8;
-
- // Number of "slow UI thread" events.
- optional int32 slow_ui_thread_count = 9;
-
- // Number of "slow bitmap upload" events.
- optional int32 slow_bitmap_upload_count = 10;
-
- // Number of "slow draw" events.
- optional int32 slow_draw_count = 11;
-
- // Number of frames that missed their deadline (aka, visibly janked)
- optional int32 missed_deadline_count = 12;
-
- // The frame time histogram for the package
- optional FrameTimingHistogram cpu_histogram = 13
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // The gpu frame time histogram for the package
- optional FrameTimingHistogram gpu_histogram = 14
- [(android.os.statsd.log_mode) = MODE_BYTES];
-
- // UI mainline module version.
- optional int64 version_ui_module = 15;
-
- // If true, these are HWUI stats for up to a 24h period for a given app from today.
- // If false, these are HWUI stats for a 24h period for a given app from the last complete
- // day (yesterday). Stats from yesterday stay constant, while stats from today may change as
- // more apps are running / rendering.
- optional bool is_today = 16;
-}
-
-/**
- * Message related to dangerous (runtime) app ops access
- */
-message RuntimeAppOpAccess {
- // Uid of the package accessing app op
- optional int32 uid = 1 [(is_uid) = true];
-
- // Name of the package accessing app op
- optional string package_name = 2;
-
- // deprecated - set to empty string
- optional string op_deprecated = 3 [deprecated = true];
-
- // attribution_tag; provided by developer when accessing related API, limited at 50 chars by
- // API. Attributions must be provided through manifest using <attribution> tag available in R
- // and above.
- optional string attribution_tag = 4;
-
- // message related to app op access, limited to 600 chars by API
- optional string message = 5;
-
- enum SamplingStrategy {
- DEFAULT = 0;
- UNIFORM = 1;
- RARELY_USED = 2;
- BOOT_TIME_SAMPLING = 3;
- UNIFORM_OPS = 4;
- }
-
- // sampling strategy used to collect this message
- optional SamplingStrategy sampling_strategy = 6;
-
- // operation id
- optional android.app.AppOpEnum op = 7 [default = APP_OP_NONE];
-}
-
-/*
- * Logs userspace reboot outcome and duration.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/server/BootReceiver.java
- */
-message UserspaceRebootReported {
- // Possible outcomes of userspace reboot.
- enum Outcome {
- // Default value in case platform failed to determine the outcome.
- OUTCOME_UNKNOWN = 0;
- // Userspace reboot succeeded (i.e. boot completed without a fall back to hard reboot).
- SUCCESS = 1;
- // Userspace reboot shutdown sequence was aborted.
- FAILED_SHUTDOWN_SEQUENCE_ABORTED = 2;
- // Remounting userdata into checkpointing mode failed.
- FAILED_USERDATA_REMOUNT = 3;
- // Device didn't finish booting before timeout and userspace reboot watchdog issued a hard
- // reboot.
- FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED = 4;
- }
- // Outcome of userspace reboot. Always set.
- optional Outcome outcome = 1;
- // Duration of userspace reboot in case it has a successful outcome.
- // Duration is measured as time between userspace reboot was initiated and until boot completed
- // (e.g. sys.boot_completed=1).
- optional int64 duration_millis = 2;
- // State of primary user's (user0) credential encryption storage.
- enum UserEncryptionState {
- // Default value.
- USER_ENCRYPTION_STATE_UNKNOWN = 0;
- // Credential encrypted storage is unlocked.
- UNLOCKED = 1;
- // Credential encrypted storage is locked.
- LOCKED = 2;
- }
- // State of primary user's encryption storage at the moment boot completed. Always set.
- optional UserEncryptionState user_encryption_state = 3;
-}
-
-/*
- * Logs integrity check information during each install.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
- */
-message IntegrityCheckResultReported {
- optional string package_name = 1;
- optional string app_certificate_hash = 2;
- optional int64 version_code = 3;
- optional string installer_package_name = 4;
- enum Response {
- UNKNOWN = 0;
- ALLOWED = 1;
- REJECTED = 2;
- FORCE_ALLOWED = 3;
- }
- optional Response response = 5;
- // An estimate on the cause of the response. This will only be populated for
- // REJECTED and FORCE_ALLOWED
- optional bool caused_by_app_cert_rule = 6;
- optional bool caused_by_installer_rule = 7;
-}
-
-/**
- * Logs the information about the rules and the provider whenever rules are
- * pushed into AppIntegrityManager.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
- */
-message IntegrityRulesPushed {
- optional bool success = 1;
- // Package name of the app that pushed the rules.
- optional string rule_provider = 2;
- // Version string of arbitrary format provided by the rule provider to
- // identify the rules.
- optional string rule_version = 3;
-}
-
-/**
- * Logs when a cell broadcast message is received on the device.
- *
- * Logged from Cell Broadcast module and platform:
- * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/
- * packages/apps/CellBroadcastReceiver/
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
- */
-message CellBroadcastMessageReported {
- // The type of Cell Broadcast message
- enum CbType {
- UNKNOWN_TYPE = 0;
- GSM = 1;
- CDMA = 2;
- CDMA_SPC = 3;
- }
-
- // The parts of the cell broadcast message pipeline
- enum ReportSource {
- UNKNOWN_SOURCE = 0;
- FRAMEWORK = 1;
- CB_SERVICE = 2;
- CB_RECEIVER_APP = 3;
- }
-
- // GSM, CDMA, CDMA-SCP
- optional CbType type = 1;
-
- // The source of the report
- optional ReportSource source = 2;
-}
-
-/**
- * Logs when a cell broadcast message is filtered out, or otherwise intentionally not sent to CBR.
- *
- * Logged from CellBroadcastService module:
- * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/
- */
-message CellBroadcastMessageFiltered {
- enum FilterReason {
- NOT_FILTERED = 0;
- DUPLICATE_MESSAGE = 1;
- GEOFENCED_MESSAGE = 2;
- AREA_INFO_MESSAGE = 3;
- }
-
- // GSM, CDMA, CDMA-SCP
- optional CellBroadcastMessageReported.CbType type = 1;
-
- // The source of the report
- optional FilterReason filter = 2;
-}
-
-/**
- * Logs when an error occurs while handling a cell broadcast message;
- *
- * Logged from CellBroadcastService module:
- * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/
- */
-message CellBroadcastMessageError {
- // The type of error raised when trying to handle a cell broadcast message
- enum ErrorType {
- UNKNOWN_TYPE = 0;
- CDMA_DECODING_ERROR = 1;
- CDMA_SCP_EMPTY = 2;
- CDMA_SCP_HANDLING_ERROR = 3;
- GSM_INVALID_HEADER_LENGTH = 4;
- GSM_UNSUPPORTED_HEADER_MESSAGE_TYPE = 5;
- GSM_UNSUPPORTED_HEADER_DATA_CODING_SCHEME = 6;
- GSM_INVALID_PDU = 7;
- GSM_INVALID_GEO_FENCING_DATA = 8;
- GSM_UMTS_INVALID_WAC = 9;
- FAILED_TO_INSERT_TO_DB = 10;
- UNEXPECTED_GEOMETRY_FROM_FWK = 11;
- UNEXPECTED_GSM_MESSAGE_TYPE_FROM_FWK = 12;
- UNEXPECTED_CDMA_MESSAGE_TYPE_FROM_FWK = 13;
- UNEXPECTED_CDMA_SCP_MESSAGE_TYPE_FROM_FWK = 14;
- NO_CONNECTION_TO_CB_SERVICE = 15;
- }
-
- // What kind of error occurred
- optional ErrorType type = 1;
-
- // Exception message (or log message) associated with the error (max 1000 chars)
- optional string exception_message = 2;
-}
-
-/**
- * Logs when a tune occurs through device's Frontend.
- * This is atom ID 276.
- *
- * Logged from:
- * frameworks/base/media/java/android/media/tv/tuner/Tuner.java
- */
-message TvTunerStateChanged {
- enum State {
- UNKNOWN = 0;
- TUNING = 1; // Signal is tuned
- LOCKED = 2; // the signal is locked
- NOT_LOCKED = 3; // the signal isn’t locked.
- SIGNAL_LOST = 4; // the signal was locked, but is lost now.
- SCANNING = 5; // the signal is scanned
- SCAN_STOPPED = 6; // the scan is stopped.
- }
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
- // new state
- optional State state = 2;
-}
-
-/**
- * Logs the status of a dvr playback or record.
- * This is atom ID 279.
- *
- * Logged from:
- * frameworks/base/media/java/android/media/tv/tuner/dvr
- */
-message TvTunerDvrStatus {
- enum Type {
- UNKNOWN_TYPE = 0;
- PLAYBACK = 1; // is a playback
- RECORD = 2; // is a record
- }
- enum State {
- UNKNOWN_STATE = 0;
- STARTED = 1; // DVR is started
- STOPPED = 2; // DVR is stopped
- }
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
- // DVR type
- optional Type type = 2;
- // DVR state
- optional State state = 3;
- // Identify the segment of a record or playback
- optional int32 segment_id = 4;
- // indicate how many overflow or underflow happened between started to stopped
- optional int32 overflow_underflow_count = 5;
-}
-
-/**
- * Logs when a cas session opened through MediaCas.
- * This is atom ID 280.
- *
- * Logged from:
- * frameworks/base/media/java/android/media/MediaCas.java
- */
-message TvCasSessionOpenStatus {
- enum State {
- UNKNOWN = 0;
- SUCCEEDED = 1; // indicate that the session is opened successfully.
- FAILED = 2; // indicate that the session isn’t opened successfully.
- }
- // The uid of the application that sent this custom atom.
- optional int32 uid = 1 [(is_uid) = true];
- // Cas system Id
- optional int32 cas_system_id = 2;
- // State of the session
- optional State state = 3;
-}
-
-/**
- * Logs for ContactsProvider general usage.
- * This is atom ID 301.
- *
- * Logged from:
- * packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
- */
-message ContactsProviderStatusReported {
- enum ApiType {
- UNKNOWN_API = 0;
- QUERY = 1;
- // INSERT includes insert and bulkInsert, and inserts triggered by applyBatch.
- INSERT = 2;
- // UPDATE and DELETE includes update/delete and the ones triggered by applyBatch.
- UPDATE = 3;
- DELETE = 4;
- }
-
- enum ResultType {
- UNKNOWN_RESULT = 0;
- SUCCESS = 1;
- FAIL = 2;
- ILLEGAL_ARGUMENT = 3;
- UNSUPPORTED_OPERATION = 4;
- }
-
- enum CallerType {
- UNSPECIFIED_CALLER_TYPE = 0;
- CALLER_IS_SYNC_ADAPTER = 1;
- CALLER_IS_NOT_SYNC_ADAPTER = 2;
- }
-
- optional ApiType api_type = 1;
- // Defined in
- // packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
- optional int32 uri_type = 2;
- optional CallerType caller_type = 3;
- optional ResultType result_type = 4;
- optional int32 result_count = 5;
- optional int64 latency_micros = 6;
-}
-
-/**
- * Logs when an app is frozen or unfrozen.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/CachedAppOptimizer.java
- */
-message AppFreezeChanged {
- // The type of event.
- enum Action {
- UNKNOWN = 0;
- FREEZE_APP = 1;
- UNFREEZE_APP = 2;
- }
- optional Action action = 1;
-
- // Pid of the process being frozen.
- optional int32 pid = 2;
-
- // Name of the process being frozen.
- optional string process_name = 3;
-
- // Time since last unfrozen.
- optional int64 time_unfrozen_millis = 4;
-}
-
-/**
- * Pulls information for a single voice call.
- *
- * Each pull creates multiple atoms, one for each call. The sequence is randomized when pulled.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message VoiceCallSession {
- // Bearer (IMS or CS) when the call started.
- optional android.telephony.CallBearerEnum bearer_at_start = 1;
-
- // Bearer (IMS or CS) when the call ended.
- // The bearer may change during the call, e.g. due to SRVCC.
- optional android.telephony.CallBearerEnum bearer_at_end = 2;
-
- // Direction of the call (incoming or outgoing).
- optional android.telephony.CallDirectionEnum direction = 3;
-
- // Time spent setting up the call.
- optional android.telephony.CallSetupDurationEnum setup_duration = 4;
-
- // Whether the call ended before the setup was completed.
- optional bool setup_failed = 5;
-
- // IMS reason code or CS disconnect cause.
- // For IMS, see: frameworks/base/telephony/java/android/telephony/ims/ImsReasonInfo.java
- // For CS, see: frameworks/base/telephony/java/android/telephony/DisconnectCause.java
- optional int32 disconnect_reason_code = 6;
-
- // IMS extra code or CS precise disconnect cause.
- // For IMS, this code is vendor-specific
- // For CS, see: frameworks/base/telephony/java/android/telephony/PreciseDisconnectCause.java
- optional int32 disconnect_extra_code = 7;
-
- // IMS extra message or CS vendor cause.
- optional string disconnect_extra_message = 8;
-
- // Radio access technology (RAT) used when call started.
- optional android.telephony.NetworkTypeEnum rat_at_start = 9;
-
- // Radio access technology (RAT) used when call terminated.
- optional android.telephony.NetworkTypeEnum rat_at_end = 10;
-
- // Number of times RAT changed during the call.
- optional int64 rat_switch_count = 11;
-
- // A bitmask of all codecs used during the call.
- // See: frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
- optional int64 codec_bitmask = 12;
-
- // Number of other calls going on during call setup, for the same SIM slot.
- optional int32 concurrent_call_count_at_start = 13;
-
- // Number of other calls going on during call termination, for the same SIM slot.
- optional int32 concurrent_call_count_at_end = 14;
-
- // Index of the SIM is used, 0 for single-SIM devices.
- optional int32 sim_slot_index = 15;
-
- // Whether the device was in multi-SIM mode (with multiple active SIM profiles).
- optional bool is_multi_sim = 16;
-
- // Whether the call was made with an eSIM profile.
- optional bool is_esim = 17;
-
- // Carrier ID of the SIM card.
- // See https://source.android.com/devices/tech/config/carrierid.
- optional int32 carrier_id = 18;
-
- // Whether an SRVCC has been completed successfully for this call.
- optional bool srvcc_completed = 19;
-
- // Number of SRVCC failures.
- optional int64 srvcc_failure_count = 20;
-
- // Number of SRVCC cancellations.
- optional int64 srvcc_cancellation_count = 21;
-
- // Whether the Real-Time Text (RTT) was ever used in the call (rather than whether RTT was
- // enabled in the dialer's settings).
- optional bool rtt_enabled = 22;
-
- // Whether this was an emergency call.
- optional bool is_emergency = 23;
-
- // Whether the call was performed while roaming.
- optional bool is_roaming = 24;
-
- // A random number used as the dimension field to pull multiple atoms.
- optional int32 dimension = 25;
-}
-
-/**
- * Pulls voice call radio access technology (RAT) usage.
- *
- * Each pull creates multiple atoms, one for each carrier/RAT, the order of which is irrelevant to
- * time. The atom will be skipped if not enough data is available.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message VoiceCallRatUsage {
- // Carrier ID (https://source.android.com/devices/tech/config/carrierid).
- optional int32 carrier_id = 1;
-
- // Radio access technology.
- optional android.telephony.NetworkTypeEnum rat = 2;
-
- // Total duration that voice calls spent on this carrier and RAT.
- optional int64 total_duration_seconds = 3;
-
- // Total number of calls using this carrier and RAT.
- // A call is counted once even if it used the RAT multiple times.
- optional int64 call_count = 4;
-}
-
-/**
- * Pulls the number of active SIM slots and SIMs/eSIM profiles.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message SimSlotState {
- // Number of active SIM slots (both physical and eSIM profiles) in the device.
- optional int32 active_slot_count = 1;
-
- // Number of SIM cards (both physical and active eSIM profiles).
- // This number is always equal to or less than the number of active SIM slots.
- optional int32 sim_count = 2;
-
- // Number of active eSIM profiles.
- // This number is always equal to or less than the number of SIMs.
- optional int32 esim_count = 3;
-}
-
-/**
- * Pulls supported cellular radio access technologies.
- *
- * This atom reports the capabilities of the device, rather than the network it has access to.
- *
- * Pulled from:
- * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
- */
-message SupportedRadioAccessFamily {
- // A bitmask of supported radio technologies.
- // See android.telephony.TelephonyManager.NetworkTypeBitMask.
- optional int64 network_type_bitmask = 1;
-}
-
-/**
- * Logs gnss stats from location service provider
- *
- * Pulled from:
- * frameworks/base/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
- */
-
-message GnssStats {
- // Number of location reports since boot
- optional int64 location_reports = 1;
-
- // Total pulled reports of Location failures since boot
- optional int64 location_failure_reports = 2;
-
- // Number of time to first fix reports since boot
- optional int64 time_to_first_fix_reports = 3;
-
- // Total pulled reported time to first fix (in milli-seconds) since boot
- optional int64 time_to_first_fix_millis = 4;
-
- // Number of position accuracy reports since boot
- optional int64 position_accuracy_reports = 5;
-
- // Total pulled reported position accuracy (in meters) since boot
- optional int64 position_accuracy_meters = 6;
-
- // Number of top 4 average CN0 reports since boot
- optional int64 top_four_average_cn0_reports = 7;
-
- // Total pulled reported of top 4 average CN0 (dB-mHz) since boot
- optional int64 top_four_average_cn0_db_mhz = 8;
-
- // Number of l5 top 4 average CN0 reports since boot
- optional int64 l5_top_four_average_cn0_reports = 9;
-
- // Total pulled reported of l5 top 4 average CN0 (dB-mHz) since boot
- optional int64 l5_top_four_average_cn0_db_mhz = 10;
-
- // Total number of sv status messages reports since boot
- optional int64 sv_status_reports = 11;
-
- // Total number of sv status messages reports, where sv is used in fix since boot
- optional int64 sv_status_reports_used_in_fix = 12;
-
- // Total number of L5 sv status messages reports since boot
- optional int64 l5_sv_status_reports = 13;
-
- // Total number of L5 sv status messages reports, where sv is used in fix since boot
- optional int64 l5_sv_status_reports_used_in_fix = 14;
-}
-
-/**
- * Logs when an app is moved to a different standby bucket.
- *
- * Logged from:
- * frameworks/base/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
- */
-message AppStandbyBucketChanged {
- optional string package_name = 1;
-
- // Should be 0, 10, 11, 12, etc. where 0 is the owner. See UserHandle for more documentation.
- optional int32 user_id = 2;
-
- // These enum values match the constants defined in UsageStatsManager.java.
- enum Bucket {
- BUCKET_UNKNOWN = 0;
- BUCKET_EXEMPTED = 5;
- BUCKET_ACTIVE = 10;
- BUCKET_WORKING_SET = 20;
- BUCKET_FREQUENT = 30;
- BUCKET_RARE = 40;
- BUCKET_RESTRICTED = 45;
- BUCKET_NEVER = 50;
- }
- optional Bucket bucket = 3;
-
- enum MainReason {
- MAIN_UNKNOWN = 0;
- MAIN_DEFAULT = 0x0100;
- MAIN_TIMEOUT = 0x0200;
- MAIN_USAGE = 0x0300;
- MAIN_FORCED_BY_USER = 0x0400;
- MAIN_PREDICTED = 0x0500;
- MAIN_FORCED_BY_SYSTEM = 0x0600;
- }
- optional MainReason main_reason = 4;
-
- // A more detailed reason for the standby bucket change. The sub reason name is dependent on
- // the main reason. Values are one of the REASON_SUB_XXX constants defined in
- // UsageStatsManager.java.
- optional int32 sub_reason = 5;
-}
-
-/**
-* Reports a started sharesheet transaction.
-*
-* Logged from:
-* frameworks/base/core/java/com/android/internal/app/ChooserActivity.java
-*/
-message SharesheetStarted {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The calling app's package name.
- optional string package_name = 2;
- // An identifier to tie together multiple logs relating to the same share event
- optional int32 instance_id = 3;
- // The mime type of the share
- optional string mime_type = 4;
- // The number of direct targets the calling app is providing that will be shown.
- optional int32 num_app_provided_direct_targets = 5;
- // The number of app targets the calling app is providing that will be shown.
- optional int32 num_app_provided_app_targets = 6;
- // True if the share originates from the workprofile
- optional bool is_workprofile = 7;
-
- enum SharesheetPreviewType { // Constants from ChooserActivity.java
- CONTENT_PREVIEW_TYPE_UNKNOWN = 0; // Default for proto 2 / 3 compatibility.
- CONTENT_PREVIEW_IMAGE = 1; // The preview shown in the sharesheet is an image.
- CONTENT_PREVIEW_FILE = 2; // The preview shown in the sharesheet is a file.
- CONTENT_PREVIEW_TEXT = 3; // The preview shown in the sharesheet is text.
- }
- // How the sharesheet preview is presented.
- optional SharesheetPreviewType preview_type = 8;
-
- enum ResolverActivityIntent { // Intents handled by ResolverActivity.java
- INTENT_DEFAULT = 0;
- INTENT_ACTION_VIEW = 1;
- INTENT_ACTION_EDIT = 2;
- INTENT_ACTION_SEND = 3;
- INTENT_ACTION_SENDTO = 4;
- INTENT_ACTION_SEND_MULTIPLE = 5;
- INTENT_ACTION_IMAGE_CAPTURE = 6;
- INTENT_ACTION_MAIN = 7;
- }
- // The intent being processed (only SEND and SEND_MULTIPLE are system sharesheet)
- optional ResolverActivityIntent intent_type = 9;
-}
-
-/**
- * Reports a ranking selection event.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/app/ChooserActivity.java (sharesheet)
- */
-message RankingSelected {
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
- // The relevant app's package name (can be source or picked package).
- optional string package_name = 2;
- // An identifier to tie together multiple logs relating to the same share event.
- optional int32 instance_id = 3;
- // Which of the ranked targets got picked, default starting position 0.
- optional int32 position_picked = 4;
-}
-
-/**
- * Logs when TvSettings UI is interacted at.
- *
- * Logged from: packages/apps/TvSettings
- */
-message TvSettingsUIInteracted {
-
- /** The UI action category */
- optional android.app.tvsettings.Action action = 1;
-
- /** The ID of the entry that the users actioned on */
- optional android.app.tvsettings.ItemId item_id = 2;
-}
-
-/**
- * Logs information about a package installation using package installer V2 APIs.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java
- */
-message PackageInstallerV2Reported {
- // Whether this installation uses Incremental File System
- optional bool is_incremental = 1;
- // Name of the package that is intended to be installed
- optional string package_name = 2;
- // The duration between when the install was requested to when the install has completed
- optional int64 duration_millis = 3;
- // Installation result in final integer, which are SystemApi's.
- // Return_code 1 indicates success.
- // For full list, see frameworks/base/core/java/android/content/pm/PackageManager.java
- optional int32 return_code = 4;
- // Total size of the APKs installed for this package
- optional int64 apks_size_bytes = 5;
-}
-
-/**
- * Logs settings provider values.
- *
- * Use DeviceConfig.getProperties to get a list Setting key, query the data from content provider,
- * then write the value to proto.
- *
- */
-message SettingSnapshot {
-
- // Setting key
- optional string name = 1;
-
- enum SettingsValueType {
- NOTASSIGNED = 0;
- ASSIGNED_BOOL_TYPE = 1;
- ASSIGNED_INT_TYPE = 2;
- ASSIGNED_FLOAT_TYPE = 3;
- ASSIGNED_STRING_TYPE = 4;
- };
- // Setting value type
- optional SettingsValueType type = 2;
-
- optional bool bool_value = 3;
-
- optional int32 int_value = 4;
-
- optional float float_value = 5;
-
- optional string str_value = 6;
-
- // Android user index. 0 for primary user, 10, 11 for secondary or profile user
- optional int32 user_id = 7;
-}
-
-/**
- * An event logged to indicate that a user journey is about to be performed. This atom includes
- * relevant information about the users involved in the journey. A UserLifecycleEventOccurred event
- * will immediately follow this atom which will describe the event(s) and its state.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/UserController.java
- * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
- */
-message UserLifecycleJourneyReported {
- // An identifier to track a chain of user lifecycle events occurring (referenced in the
- // UserLifecycleEventOccurred atom)
- optional int64 session_id = 1;
-
- // Indicates what type of user journey this session is related to
- enum Journey {
- UNKNOWN = 0; // Undefined user lifecycle journey
- USER_SWITCH_UI = 1; // A user switch journey where a UI is shown
- USER_SWITCH_FG = 2; // A user switch journey without a UI shown
- USER_START = 3; // A user start journey
- USER_CREATE = 4; // A user creation journey
- }
- optional Journey journey = 2;
- // Which user the journey is originating from - could be -1 for certain phases (eg USER_CREATE)
- // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
- optional int32 origin_user = 3;
- // Which user the journey is targeting
- // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
- optional int32 target_user = 4;
-
- // What is the user type of the target user
- // These should be in sync with USER_TYPE_* flags defined in UserManager.java
- enum UserType {
- TYPE_UNKNOWN = 0;
- FULL_SYSTEM = 1;
- FULL_SECONDARY = 2;
- FULL_GUEST = 3;
- FULL_DEMO = 4;
- FULL_RESTRICTED = 5;
- PROFILE_MANAGED = 6;
- SYSTEM_HEADLESS = 7;
- }
- optional UserType user_type = 5;
- // What are the flags attached to the target user
- optional int32 user_flags = 6;
-}
-
-/**
- * An event logged when a specific user lifecycle event is performed. These events should be
- * correlated with a UserLifecycleJourneyReported atom via the session_id.
- * Note: journeys can span over multiple events, hence some events may share a single session id.
- *
- * Logged from:
- * frameworks/base/services/core/java/com/android/server/am/UserController.java
- * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
- */
-message UserLifecycleEventOccurred {
- // An id which links back to user details (reported in the UserLifecycleJourneyReported atom)
- optional int64 session_id = 1;
- // The target user for this event (same as target_user in the UserLifecycleJourneyReported atom)
- // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
- optional int32 user_id = 2;
-
- enum Event {
- UNKNOWN = 0; // Indicates that the associated user journey timed-out or resulted in an error
- SWITCH_USER = 1; // Indicates that this is a user switch event
- START_USER = 2; // Indicates that this is a user start event
- CREATE_USER = 3; // Indicates that this is a user create event
- USER_RUNNING_LOCKED = 4; // Indicates that user is running in locked state
- UNLOCKING_USER = 5; // Indicates that this is a user unlocking event
- UNLOCKED_USER = 6; // Indicates that this is a user unlocked event
- }
- optional Event event = 3;
-
- enum State {
- NONE = 0; // Indicates the associated event has no start/end defined
- BEGIN = 1;
- FINISH = 2;
- }
- optional State state = 4; // Represents the state of an event (beginning/ending)
-}
-
-/**
- * Logs when accessibility shortcut clicked.
- *
- * Logged from:
- * frameworks/base/services/accessibility/java/com/android/server/accessibility
- */
-message AccessibilityShortcutReported {
- // The accessibility feature(including installed a11y service, framework a11y feature,
- // and installed a11y activity) package name that is assigned to the accessibility shortcut.
- optional string package_name = 1;
-
- // The definition of the accessibility shortcut.
- // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto.
- optional android.stats.accessibility.ShortcutType shortcut_type = 2;
-
- // The definition of the service status.
- // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto.
- optional android.stats.accessibility.ServiceStatus service_status = 3;
-}
-
-/**
- * Logs when accessibility service status changed.
- *
- * Logged from:
- * packages/apps/Settings/src/com/android/settings/accessibility
- */
-message AccessibilityServiceReported {
- // The accessibility service package name.
- optional string package_name = 1;
-
- // The definition of the service status.
- // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto.
- optional android.stats.accessibility.ServiceStatus service_status = 2;
-}
-
-/**
- * Logs when display wake up.
- *
- * Logged from:
- * services/core/java/com/android/server/power/Notifier.java
- */
-
-message DisplayWakeReported {
- // Wake_up_reason code
- // If LOWORD(wake_up_reason) = 0
- // reference to HIWORD(wake_up_reason) PowerManager.WAKE_REASON_XXX
- // else reference wake_up_reason to
- // services/core/java/com/android/server/power/Notifier.java#onWakeUp
- optional int32 wake_up_reason = 1;
-}
-
-/**
- * Logs app usage events.
- */
-message AppUsageEventOccurred {
- optional int32 uid = 1 [(is_uid) = true];
- optional string package_name = 2;
- optional string class_name = 3;
-
- enum EventType {
- NONE = 0;
- MOVE_TO_FOREGROUND = 1;
- MOVE_TO_BACKGROUND = 2;
- }
- optional EventType event_type = 4;
-}
-
-/*
- * Quality metrics logged when EVS cameras are active.
- *
- * Logged from:
- * packages/services/Car/evs/manager/1.1/Enumerator.cpp
- */
-message EvsUsageStatsReported {
-
- // Camera identifier to distinguish the source camera device. This is not
- // globally unique and therefore cannot be used to identify the user and/or
- // the device.
- optional int32 device_id = 1;
-
- // Peak number of clients during the service
- optional int32 peak_num_clients = 2;
-
- // Number of erroneous events during the service
- optional int32 num_errors = 3;
-
- // Round trip latency of the very first frame
- optional int64 first_latency_millis = 4;
-
- // Average frame round trip latency
- optional float avg_latency_millis = 5;
-
- // Peak frame round trip latency
- optional int64 peak_latency_millis = 6;
-
- // Total number of frames received
- optional int64 total_frames = 7;
-
- // Number of frames ignored
- optional int64 ignored_frames = 8;
-
- // Number of dropped frames to synchronize camera devices
- optional int64 dropped_frames_to_sync = 9;
-
- // The duration of the service
- optional int64 duration_millis = 10;
-}
-
-/**
- * Logs audio power usage stats.
- *
- * Pushed from:
- * frameworks/av/services/mediametrics/AudioPowerUsage.cpp
- */
-message AudioPowerUsageDataReported {
- /**
- * Device used for input/output
- *
- * All audio devices please refer to below file:
- * system/media/audio/include/system/audio-base.h
- *
- * Define our own enum values because we don't report all audio devices.
- * Currently, we only report built-in audio devices such as handset, speaker,
- * built-in mics, common audio devices such as wired headset, usb headset
- * and bluetooth devices.
- */
- enum AudioDevice {
- OUTPUT_EARPIECE = 0x1; // handset
- OUTPUT_SPEAKER = 0x2; // dual speaker
- OUTPUT_WIRED_HEADSET = 0x4; // 3.5mm headset
- OUTPUT_USB_HEADSET = 0x8; // usb headset
- OUTPUT_BLUETOOTH_SCO = 0x10; // bluetooth sco
- OUTPUT_BLUETOOTH_A2DP = 0x20; // a2dp
- OUTPUT_SPEAKER_SAFE = 0x40; // bottom speaker
-
- INPUT_DEVICE_BIT = 0x40000000; // non-negative positive int32.
- INPUT_BUILTIN_MIC = 0x40000001; // buildin mic
- INPUT_BUILTIN_BACK_MIC = 0x40000002; // buildin back mic
- INPUT_WIRED_HEADSET_MIC = 0x40000004; // 3.5mm headset mic
- INPUT_USB_HEADSET_MIC = 0x40000008; // usb headset mic
- INPUT_BLUETOOTH_SCO = 0x40000010; // bluetooth sco mic
- }
- optional AudioDevice audio_device = 1;
-
- // Duration of the audio in seconds
- optional int32 duration_secs = 2;
-
- // Average volume (0 ... 1.0)
- optional float average_volume = 3;
-
- enum AudioType {
- UNKNOWN_TYPE = 0;
- VOICE_CALL_TYPE = 1; // voice call
- VOIP_CALL_TYPE = 2; // voip call, including uplink and downlink
- MEDIA_TYPE = 3; // music and system sound
- RINGTONE_NOTIFICATION_TYPE = 4; // ringtone and notification
- ALARM_TYPE = 5; // alarm type
- // record type
- CAMCORDER_TYPE = 6; // camcorder
- RECORD_TYPE = 7; // other recording
- }
- optional AudioType type = 4;
-}
-
-/**
- * Pulls bytes transferred over WiFi and mobile networks sliced by uid, is_metered, and tag.
- *
- * Pulled from:
- * StatsPullAtomService, which uses NetworkStatsService to query NetworkStats.
- */
-message BytesTransferByTagAndMetered {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional bool is_metered = 2;
-
- optional int32 tag = 3;
-
- optional int64 rx_bytes = 4;
-
- optional int64 rx_packets = 5;
-
- optional int64 tx_bytes = 6;
-
- optional int64 tx_packets = 7;
-}
-
-/*
- * Logs when the Media Output Switcher finishes a media switch operation.
- *
- * Logged from:
- * packages/apps/Settings/src/com/android/settings/media/MediaOutputSliceWorker.java
- */
-message MediaOutputOpSwitchReported {
- // Source medium type before switching.
- optional android.app.settings.mediaoutput.MediumType source = 1;
-
- // Target medium type after switching.
- optional android.app.settings.mediaoutput.MediumType target = 2;
-
- // The result of switching.
- optional android.app.settings.mediaoutput.SwitchResult result = 3;
-
- // The detail code of a switching result.
- optional android.app.settings.mediaoutput.SubResult subresult = 4;
-
- /*
- * The package name of a pre-installed app, whose media session is being switched.
- */
- optional string media_session_package_name = 5;
-
- // The amount of available wired devices when a switching is being performed.
- optional int32 available_wired_device_count = 6;
-
- // The amount of available Bluetooth devices a switching is being performed.
- optional int32 available_bt_device_count = 7;
-
- // The amount of available remote devices when a switching is being performed.
- optional int32 available_remote_device_count = 8;
-
- // The amount of applied devices within a remote dynamic group after a switching is done.
- optional int32 applied_device_count_within_remote_group = 9;
-}
-
-/**
- * Logs when the Assistant is invoked.
- *
- * Logged from:
- * frameworks/base/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
- */
-message AssistantInvocationReported {
-
- // The event_id (as for UiEventReported).
- optional int32 event_id = 1;
-
- // The registered Assistant's uid and package (as for UiEventReported).
- optional int32 uid = 2 [(is_uid) = true];
- optional string package_name = 3;
-
- // An identifier used to disambiguate which logs refer to a particular invocation of the
- // Assistant (as for UiEventReported).
- optional int32 instance_id = 4;
-
- // The state of the device at the time of invocation.
- enum DeviceState {
- UNKNOWN_DEVICE_STATE = 0;
- AOD1 = 1;
- AOD2 = 2;
- BOUNCER = 3;
- UNLOCKED_LOCKSCREEN = 4;
- LAUNCHER_HOME = 5;
- LAUNCHER_OVERVIEW = 6;
- LAUNCHER_ALL_APPS = 7;
- APP_DEFAULT = 8;
- APP_IMMERSIVE = 9;
- APP_FULLSCREEN = 10;
- }
- optional DeviceState device_state = 5;
-
- // Whether the Assistant handles were showing at the time of invocation.
- optional bool assistant_handles_showing = 6;
-}
-
-/**
- * Logs when an AudioRecord finishes running on an audio device
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioRecordDeviceUsageReported {
- // The devices connected to this AudioRecord.
- // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
- // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string devices = 1;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 2;
-
- // The amount of time spent in the device as measured by the active track in AudioFlinger.
- optional int64 device_time_nanos = 3;
-
- // The audio data format used for encoding.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
- optional string encoding = 4;
-
- // The client-server buffer framecount.
- // The framecount is generally between 960 - 48000 for PCM encoding.
- // The framecount represents raw buffer size in bytes for non-PCM encoding.
- optional int32 frame_count = 5;
-
- // The number of audio intervals (contiguous, continuous playbacks).
- optional int32 interval_count = 6;
-
- // The sample rate of the AudioRecord.
- // A number generally between 8000-96000 (frames per second).
- optional int32 sample_rate = 7;
-
- // The audio input flags used to construct the AudioRecord.
- // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t
- optional string flags = 8;
-
- // The santized package name of the audio client associated with the AudioRecord.
- // See getSanitizedPackageNameAndVersionCode() in
- // frameworks/av/services/mediametrics/MediaMetricsService.cpp
- optional string package_name = 9;
-
- // The selected device id (nonzero if a non-default device is selected)
- optional int32 selected_device_id = 10;
-
- // The caller of the AudioRecord.
- // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- optional string caller = 11;
-
- // The audio source for AudioRecord.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_source_t
- optional string source = 12;
-}
-
-/**
- * Logs when an AudioThread finishes running on an audio device
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioThreadDeviceUsageReported {
- // The devices connected to this audio thread.
- // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
- // (for record threads):
- // See lookup<INPUT_DEVICE> in frameworks/av/services/mediametrics/AudioTypes.cpp
- // (for playback threads):
- // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string devices = 1;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 2;
-
- // The amount of time spent in the device as measured by the active track in AudioFlinger.
- optional int64 device_time_nanos = 3;
-
- // The audio data format used for encoding.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
- optional string encoding = 4;
-
- // The framecount of the buffer delivered to (or from) the HAL.
- // The framecount is generally ~960 for PCM encoding.
- // The framecount represents raw buffer size in bytes for non-PCM encoding.
- optional int32 frame_count = 5;
-
- // The number of audio intervals (contiguous, continuous playbacks).
- optional int32 interval_count = 6;
-
- // The sample rate of the audio thread.
- // A number generally between 8000-96000 (frames per second).
- optional int32 sample_rate = 7;
-
- // The audio flags used to construct the thread
- // (for record threads):
- // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t
- // (for playback threads):
- // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t
- optional string flags = 8;
-
- // The number of underruns encountered for a playback thread or the
- // number of overruns encountered for a capture thread.
- optional int32 xruns = 9;
-
- // The type of thread
- // A thread type enumeration from
- // frameworks/av/mediametrics/services/Translate.h
- optional string type = 10;
-}
-
-/**
- * Logs when an AudioTrack finishes running on an audio device
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioTrackDeviceUsageReported {
- // The output devices connected to this AudioTrack.
- // A string OR of various output device categories, e.g. "DEVICE1|DEVICE2".
- // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string devices = 1;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 2;
-
- // The amount of time spent in the device as measured by the active track in AudioFlinger.
- optional int64 device_time_nanos = 3;
-
- // The audio data format used for encoding.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
- optional string encoding = 4;
-
- // The client-server buffer framecount.
- // The framecount is generally between 960 - 48000 for PCM encoding.
- // The framecount represents raw buffer size in bytes for non-PCM encoding.
- // A static track (see traits) may have a very large framecount.
- optional int32 frame_count = 5;
-
- // The number of audio intervals (contiguous, continuous playbacks).
- optional int32 interval_count = 6;
-
- // The sample rate of the AudioTrack.
- // A number generally between 8000-96000 (frames per second).
- optional int32 sample_rate = 7;
-
- // The audio flags used to construct the AudioTrack.
- // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t
- optional string flags = 8;
-
- // The number of underruns encountered.
- optional int32 xruns = 9;
-
- // The santized package name of the audio client associated with the AudioTrack.
- // See getSanitizedPackageNameAndVersionCode() in
- // frameworks/av/services/mediametrics/MediaMetricsService.cpp
- optional string package_name = 10;
-
- // The latency of the last sample in the buffer in milliseconds.
- optional float device_latency_millis = 11;
-
- // The startup time in milliseconds from start() to sample played.
- optional float device_startup_millis = 12;
-
- // The average volume of the track on the device [ 0.f - 1.f ]
- optional float device_volume = 13;
-
- // The selected device id (nonzero if a non-default device is selected)
- optional int32 selected_device_id = 14;
-
- // The stream_type category for the AudioTrack.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_stream_type_t
- optional string stream_type = 15;
-
- // The usage for the AudioTrack.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_usage_t
- optional string usage = 16;
-
- // The content type of the AudioTrack.
- // An enumeration from system/media/audio/include/system/audio-base.h audio_content_type_t
- optional string content_type = 17;
-
- // The caller of the AudioTrack.
- // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- optional string caller = 18;
-
- // The traits of the AudioTrack.
- // A string OR of different traits, may be empty string.
- // Only "static" is supported for R.
- // See lookup<TRACK_TRAITS>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- optional string traits = 19;
-}
-
-/**
- * Logs the status of an audio device connection attempt.
- *
- * Logged from:
- * frameworks/av/services/mediametrics/AudioAnalytics.cpp
- */
-message MediametricsAudioDeviceConnectionReported {
- // The input devices represented by this report.
- // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
- // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string input_devices = 1;
-
- // The output devices represented by this report.
- // A string OR of various output device categories.
- // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
- // See audio_device_t in system/media/audio/include/system/audio-base.h
- optional string output_devices = 2;
-
- // The name of the remote device attached to the device, typically available for USB or BT.
- // This may be empty for a fixed device, or separated by "|" if more than one.
- optional string device_names = 3;
-
- // The result of the audio device connection.
- // 0 indicates success: connection verified.
- // 1 indicates unknown: connection not verified or not known if diverted properly.
- // Other values indicate specific status.
- // See DeviceConnectionResult in frameworks/av/services/mediametrics/AudioTypes.h
- optional int32 result = 4;
-
- // Average milliseconds of time to connect
- optional float time_to_connect_millis = 5;
-
- // Number of connections if aggregated statistics, otherwise 1.
- optional int32 connection_count = 6;
-}
-
-/**
- * Logs: i) creation of different types of cryptographic keys in the keystore,
- * ii) operations performed using the keys,
- * iii) attestation of the keys
- * Logged from: system/security/keystore/key_event_log_handler.cpp
- */
-message KeystoreKeyEventReported {
-
- enum Algorithm {
- /** Asymmetric algorithms. */
- RSA = 1;
- // 2 removed, do not reuse.
- EC = 3;
- /** Block cipher algorithms */
- AES = 32;
- TRIPLE_DES = 33;
- /** MAC algorithms */
- HMAC = 128;
- };
- /** Algorithm associated with the key */
- optional Algorithm algorithm = 1;
-
- /** Size of the key */
- optional int32 key_size = 2;
-
- enum KeyOrigin {
- /** Generated in keymaster. Should not exist outside the TEE. */
- GENERATED = 0;
- /** Derived inside keymaster. Likely exists off-device. */
- DERIVED = 1;
- /** Imported into keymaster. Existed as cleartext in Android. */
- IMPORTED = 2;
- /** Keymaster did not record origin. */
- UNKNOWN = 3;
- /** Securely imported into Keymaster. */
- SECURELY_IMPORTED = 4;
- };
- /* Logs whether the key was generated, imported, securely imported, or derived.*/
- optional KeyOrigin key_origin = 3;
-
- enum HardwareAuthenticatorType {
- NONE = 0;
- PASSWORD = 1;
- FINGERPRINT = 2;
- // Additional entries must be powers of 2.
- };
- /**
- * What auth types does this key require? If none,
- * then no auth required.
- */
- optional HardwareAuthenticatorType user_auth_type = 4;
-
- /**
- * If user authentication is required, is the requirement time based? If it
- * is not time based then this field will not be used and the key is per
- * operation. Per operation keys must be user authenticated on each usage.
- */
- optional int32 user_auth_key_timeout_secs = 5;
-
- /**
- * padding mode, digest, block_mode and purpose should ideally be repeated
- * fields. However, since statsd does not support repeated fields in
- * pushed atoms, they are represented using bitmaps.
- */
-
- /** Track which padding mode is being used.*/
- optional int32 padding_mode_bitmap = 6;
-
- /** Track which digest is being used. */
- optional int32 digest_bitmap = 7;
-
- /** Track what block mode is being used (for encryption). */
- optional int32 block_mode_bitmap = 8;
-
- /** Track what purpose is this key serving. */
- optional int32 purpose_bitmap = 9;
-
- enum EcCurve {
- P_224 = 0;
- P_256 = 1;
- P_384 = 2;
- P_521 = 3;
- };
- /** Which ec curve was selected if elliptic curve cryptography is in use **/
- optional EcCurve ec_curve = 10;
-
- enum KeyBlobUsageRequirements {
- STANDALONE = 0;
- REQUIRES_FILE_SYSTEM = 1;
- };
- /** Standalone or is a file system required */
- optional KeyBlobUsageRequirements key_blob_usage_reqs = 11;
-
- enum Type {
- key_operation = 0;
- key_creation = 1;
- key_attestation = 2;
- }
- /** Key creation event, operation event or attestation event? */
- optional Type type = 12;
-
- /** Was the key creation, operation, or attestation successful? */
- optional bool was_successful = 13;
-
- /** Response code or error code */
- optional int32 error_code = 14;
-}
-
-// Blob Committer stats
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobCommitterProto {
- // Committer app's uid
- optional int32 uid = 1 [(is_uid) = true];
-
- // Unix epoch timestamp of the commit in milliseconds
- optional int64 commit_timestamp_millis = 2;
-
- // Flags of what access types the committer has set for the Blob
- optional int32 access_mode = 3;
-
- // Number of packages that have been whitelisted for ACCESS_TYPE_WHITELIST
- optional int32 num_whitelisted_package = 4;
-}
-
-// Blob Leasee stats
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobLeaseeProto {
- // Leasee app's uid
- optional int32 uid = 1 [(is_uid) = true];
-
- // Unix epoch timestamp for lease expiration in milliseconds
- optional int64 lease_expiry_timestamp_millis = 2;
-}
-
-// List of Blob Committers
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobCommitterListProto {
- repeated BlobCommitterProto committer = 1;
-}
-
-// List of Blob Leasees
-// Keep in sync between:
-// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
-// frameworks/base/cmds/statsd/src/atoms.proto
-message BlobLeaseeListProto {
- repeated BlobLeaseeProto leasee = 1;
-}
-
-/**
- * Logs the current state of a Blob committed with BlobStoreManager
- *
- * Pulled from:
- * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
- */
-message BlobInfo {
- // Id of the Blob
- optional int64 blob_id = 1;
-
- // Size of the Blob data
- optional int64 size = 2;
-
- // Unix epoch timestamp of the Blob's expiration in milliseconds
- optional int64 expiry_timestamp_millis = 3;
-
- // List of committers of this Blob
- optional BlobCommitterListProto committers = 4;
-
- // List of leasees of this Blob
- optional BlobLeaseeListProto leasees = 5;
-}
-
-/**
- * Logs when a TextClassifier API is invoked.
- *
- * See frameworks/base/core/java/android/view/textclassifier/TextClassifier.java
- * Logged from: external/libtextclassifier/java/
- */
-message TextClassifierApiUsageReported {
- enum ApiType {
- UNKNOWN_API = 0;
- SUGGEST_SELECTION = 1;
- CLASSIFY_TEXT = 2;
- GENERATE_LINKS = 3;
- DETECT_LANGUAGES = 4;
- SUGGEST_CONVERSATION_ACTIONS = 5;
- }
- optional ApiType api_type = 1;
-
- enum ResultType {
- UNKNOWN_RESULT = 0;
- SUCCESS = 1;
- FAIL = 2;
- }
- optional ResultType result_type = 2;
- optional int64 latency_millis = 3;
-}
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
deleted file mode 100644
index e9875baf58c7..000000000000
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-#include "CombinationConditionTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-using std::vector;
-
-CombinationConditionTracker::CombinationConditionTracker(const int64_t& id, const int index)
- : ConditionTracker(id, index) {
- VLOG("creating CombinationConditionTracker %lld", (long long)mConditionId);
-}
-
-CombinationConditionTracker::~CombinationConditionTracker() {
- VLOG("~CombinationConditionTracker() %lld", (long long)mConditionId);
-}
-
-bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConfig,
- const vector<sp<ConditionTracker>>& allConditionTrackers,
- const unordered_map<int64_t, int>& conditionIdIndexMap,
- vector<bool>& stack,
- vector<ConditionState>& initialConditionCache) {
- VLOG("Combination predicate init() %lld", (long long)mConditionId);
- if (mInitialized) {
- return true;
- }
-
- // mark this node as visited in the recursion stack.
- stack[mIndex] = true;
-
- Predicate_Combination combinationCondition = allConditionConfig[mIndex].combination();
-
- if (!combinationCondition.has_operation()) {
- return false;
- }
- mLogicalOperation = combinationCondition.operation();
-
- if (mLogicalOperation == LogicalOperation::NOT && combinationCondition.predicate_size() != 1) {
- return false;
- }
-
- for (auto child : combinationCondition.predicate()) {
- auto it = conditionIdIndexMap.find(child);
-
- if (it == conditionIdIndexMap.end()) {
- ALOGW("Predicate %lld not found in the config", (long long)child);
- return false;
- }
-
- int childIndex = it->second;
- const auto& childTracker = allConditionTrackers[childIndex];
- // if the child is a visited node in the recursion -> circle detected.
- if (stack[childIndex]) {
- ALOGW("Circle detected!!!");
- return false;
- }
-
- bool initChildSucceeded =
- childTracker->init(allConditionConfig, allConditionTrackers, conditionIdIndexMap,
- stack, initialConditionCache);
-
- if (!initChildSucceeded) {
- ALOGW("Child initialization failed %lld ", (long long)child);
- return false;
- } else {
- VLOG("Child initialization success %lld ", (long long)child);
- }
-
- if (allConditionTrackers[childIndex]->isSliced()) {
- setSliced(true);
- mSlicedChildren.push_back(childIndex);
- } else {
- mUnSlicedChildren.push_back(childIndex);
- }
- mChildren.push_back(childIndex);
- mTrackerIndex.insert(childTracker->getLogTrackerIndex().begin(),
- childTracker->getLogTrackerIndex().end());
- }
-
- mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
- initialConditionCache);
- initialConditionCache[mIndex] =
- evaluateCombinationCondition(mChildren, mLogicalOperation, initialConditionCache);
-
- // unmark this node in the recursion stack.
- stack[mIndex] = false;
-
- mInitialized = true;
-
- return true;
-}
-
-void CombinationConditionTracker::isConditionMet(
- const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- vector<ConditionState>& conditionCache) const {
- // So far, this is fine as there is at most one child having sliced output.
- for (const int childIndex : mChildren) {
- if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
- allConditions[childIndex]->isConditionMet(conditionParameters, allConditions,
- isPartialLink,
- conditionCache);
- }
- }
- conditionCache[mIndex] =
- evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
-}
-
-void CombinationConditionTracker::evaluateCondition(
- const LogEvent& event, const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& nonSlicedConditionCache,
- std::vector<bool>& conditionChangedCache) {
- // value is up to date.
- if (nonSlicedConditionCache[mIndex] != ConditionState::kNotEvaluated) {
- return;
- }
-
- for (const int childIndex : mChildren) {
- // So far, this is fine as there is at most one child having sliced output.
- if (nonSlicedConditionCache[childIndex] == ConditionState::kNotEvaluated) {
- const sp<ConditionTracker>& child = mAllConditions[childIndex];
- child->evaluateCondition(event, eventMatcherValues, mAllConditions,
- nonSlicedConditionCache, conditionChangedCache);
- }
- }
-
- ConditionState newCondition =
- evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
- if (!mSliced) {
- bool nonSlicedChanged = (mUnSlicedPartCondition != newCondition);
- mUnSlicedPartCondition = newCondition;
-
- nonSlicedConditionCache[mIndex] = mUnSlicedPartCondition;
- conditionChangedCache[mIndex] = nonSlicedChanged;
- } else {
- mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
- nonSlicedConditionCache);
-
- for (const int childIndex : mChildren) {
- // If any of the sliced condition in children condition changes, the combination
- // condition may be changed too.
- if (conditionChangedCache[childIndex]) {
- conditionChangedCache[mIndex] = true;
- break;
- }
- }
- nonSlicedConditionCache[mIndex] = newCondition;
- VLOG("CombinationPredicate %lld sliced may changed? %d", (long long)mConditionId,
- conditionChangedCache[mIndex] == true);
- }
-}
-
-bool CombinationConditionTracker::equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const {
- if (mSlicedChildren.size() != 1 ||
- mSlicedChildren.front() >= (int)allConditions.size() ||
- mLogicalOperation != LogicalOperation::AND) {
- return false;
- }
- const sp<ConditionTracker>& slicedChild = allConditions.at(mSlicedChildren.front());
- return slicedChild->equalOutputDimensions(allConditions, dimensions);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
deleted file mode 100644
index 39ff0ab03266..000000000000
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COMBINATION_CONDITION_TRACKER_H
-#define COMBINATION_CONDITION_TRACKER_H
-
-#include "ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class CombinationConditionTracker : public virtual ConditionTracker {
-public:
- CombinationConditionTracker(const int64_t& id, const int index);
-
- ~CombinationConditionTracker();
-
- bool init(const std::vector<Predicate>& allConditionConfig,
- const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
- std::vector<ConditionState>& initialConditionCache) override;
-
- void evaluateCondition(const LogEvent& event,
- const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache) override;
-
- void isConditionMet(const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- std::vector<ConditionState>& conditionCache) const override;
-
- // Only one child predicate can have dimension.
- const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const override {
- for (const auto& child : mChildren) {
- auto result = allConditions[child]->getChangedToTrueDimensions(allConditions);
- if (result != nullptr) {
- return result;
- }
- }
- return nullptr;
- }
-
- // Only one child predicate can have dimension.
- const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const override {
- for (const auto& child : mChildren) {
- auto result = allConditions[child]->getChangedToFalseDimensions(allConditions);
- if (result != nullptr) {
- return result;
- }
- }
- return nullptr;
- }
-
- bool IsSimpleCondition() const override { return false; }
-
- bool IsChangedDimensionTrackable() const override {
- return mLogicalOperation == LogicalOperation::AND && mSlicedChildren.size() == 1;
- }
-
- bool equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const override;
-
- void getTrueSlicedDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- std::set<HashableDimensionKey>* dimensions) const override {
- if (mSlicedChildren.size() == 1) {
- return allConditions[mSlicedChildren.front()]->getTrueSlicedDimensions(
- allConditions, dimensions);
- }
- }
-
-
-private:
- LogicalOperation mLogicalOperation;
-
- // Store index of the children Predicates.
- // We don't store string name of the Children, because we want to get rid of the hash map to
- // map the name to object. We don't want to store smart pointers to children, because it
- // increases the risk of circular dependency and memory leak.
- std::vector<int> mChildren;
-
- std::vector<int> mSlicedChildren;
- std::vector<int> mUnSlicedChildren;
-
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // COMBINATION_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/ConditionTimer.h b/cmds/statsd/src/condition/ConditionTimer.h
deleted file mode 100644
index 442bc11934fe..000000000000
--- a/cmds/statsd/src/condition/ConditionTimer.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include <stdint.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * A simple stopwatch to time the duration of condition being true.
- *
- * The owner of the stopwatch (MetricProducer) is responsible to notify the stopwatch when condition
- * changes (start/pause), and when to start a new bucket (a new lap basically). All timestamps
- * should be elapsedRealTime in nano seconds.
- *
- * Keep the timer simple and inline everything. This class is *NOT* thread safe. Caller is
- * responsible for thread safety.
- */
-class ConditionTimer {
-public:
- explicit ConditionTimer(bool initCondition, int64_t bucketStartNs) : mCondition(initCondition) {
- if (initCondition) {
- mLastConditionTrueTimestampNs = bucketStartNs;
- }
- };
-
- // Tracks how long the condition has been stayed true in the *current* bucket.
- // When a new bucket is created, this value will be reset to 0.
- int64_t mTimerNs = 0;
-
- // Last elapsed real timestamp when condition turned to true
- // When a new bucket is created and the condition is true, then the timestamp is set
- // to be the bucket start timestamp.
- int64_t mLastConditionTrueTimestampNs = 0;
-
- bool mCondition = false;
-
- int64_t newBucketStart(int64_t nextBucketStartNs) {
- if (mCondition) {
- mTimerNs += (nextBucketStartNs - mLastConditionTrueTimestampNs);
- mLastConditionTrueTimestampNs = nextBucketStartNs;
- }
-
- int64_t temp = mTimerNs;
- mTimerNs = 0;
- return temp;
- }
-
- void onConditionChanged(bool newCondition, int64_t timestampNs) {
- if (newCondition == mCondition) {
- return;
- }
- mCondition = newCondition;
- if (newCondition) {
- mLastConditionTrueTimestampNs = timestampNs;
- } else {
- mTimerNs += (timestampNs - mLastConditionTrueTimestampNs);
- }
- }
-
- FRIEND_TEST(ConditionTimerTest, TestTimer_Inital_False);
- FRIEND_TEST(ConditionTimerTest, TestTimer_Inital_True);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
deleted file mode 100644
index 62736c8160bb..000000000000
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "condition/condition_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/LogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-
-#include <utils/RefBase.h>
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConditionTracker : public virtual RefBase {
-public:
- ConditionTracker(const int64_t& id, const int index)
- : mConditionId(id),
- mIndex(index),
- mInitialized(false),
- mTrackerIndex(),
- mUnSlicedPartCondition(ConditionState::kUnknown),
- mSliced(false){};
-
- virtual ~ConditionTracker(){};
-
- inline const int64_t& getId() { return mConditionId; }
-
- // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
- // be done in the constructor, but we do it separately because (1) easy to return a bool to
- // indicate whether the initialization is successful. (2) makes unit test easier.
- // allConditionConfig: the list of all Predicate config from statsd_config.
- // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
- // need to call init() on children conditions)
- // conditionIdIndexMap: the mapping from condition id to its index.
- // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
- // initialConditionCache: tracks initial conditions of all ConditionTrackers.
- virtual bool init(const std::vector<Predicate>& allConditionConfig,
- const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap,
- std::vector<bool>& stack,
- std::vector<ConditionState>& initialConditionCache) = 0;
-
- // evaluate current condition given the new event.
- // event: the new log event
- // eventMatcherValues: the results of the LogMatcherTrackers. LogMatcherTrackers always process
- // event before ConditionTrackers, because ConditionTracker depends on
- // LogMatchingTrackers.
- // mAllConditions: the list of all ConditionTracker
- // conditionCache: the cached non-sliced condition of the ConditionTrackers for this new event.
- // conditionChanged: the bit map to record whether the condition has changed.
- // If the condition has dimension, then any sub condition changes will report
- // conditionChanged.
- virtual void evaluateCondition(const LogEvent& event,
- const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& conditionChanged) = 0;
-
- // Query the condition with parameters.
- // [conditionParameters]: a map from condition name to the HashableDimensionKey to query the
- // condition.
- // [allConditions]: all condition trackers. This is needed because the condition evaluation is
- // done recursively
- // [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields
- // in the condition tracker output dimension.
- // [conditionCache]: the cache holding the condition evaluation values.
- virtual void isConditionMet(
- const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- std::vector<ConditionState>& conditionCache) const = 0;
-
- // return the list of LogMatchingTracker index that this ConditionTracker uses.
- virtual const std::set<int>& getLogTrackerIndex() const {
- return mTrackerIndex;
- }
-
- virtual void setSliced(bool sliced) {
- mSliced = mSliced | sliced;
- }
-
- inline bool isSliced() const {
- return mSliced;
- }
-
- virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
- virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
-
- inline int64_t getConditionId() const {
- return mConditionId;
- }
-
- virtual void getTrueSlicedDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- std::set<HashableDimensionKey>* dimensions) const = 0;
-
- virtual bool IsChangedDimensionTrackable() const = 0;
-
- virtual bool IsSimpleCondition() const = 0;
-
- virtual bool equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const = 0;
-
- // Return the current condition state of the unsliced part of the condition.
- inline ConditionState getUnSlicedPartConditionState() const {
- return mUnSlicedPartCondition;
- }
-
-protected:
- const int64_t mConditionId;
-
- // the index of this condition in the manager's condition list.
- const int mIndex;
-
- // if it's properly initialized.
- bool mInitialized;
-
- // the list of LogMatchingTracker index that this ConditionTracker uses.
- std::set<int> mTrackerIndex;
-
- // This variable is only used for CombinationConditionTrackers.
- // SimpleConditionTrackers technically don't have an unsliced part because
- // they are either sliced or unsliced.
- //
- // CombinationConditionTrackers have multiple children ConditionTrackers
- // that can be a mixture of sliced or unsliced. This tracks the
- // condition of the unsliced part of the combination condition.
- ConditionState mUnSlicedPartCondition;
-
- bool mSliced;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp
deleted file mode 100644
index c542032b48ea..000000000000
--- a/cmds/statsd/src/condition/ConditionWizard.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "ConditionWizard.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters,
- const bool isPartialLink) {
- vector<ConditionState> cache(mAllConditions.size(), ConditionState::kNotEvaluated);
-
- mAllConditions[index]->isConditionMet(
- parameters, mAllConditions, isPartialLink,
- cache);
- return cache[index];
-}
-
-const set<HashableDimensionKey>* ConditionWizard::getChangedToTrueDimensions(
- const int index) const {
- return mAllConditions[index]->getChangedToTrueDimensions(mAllConditions);
-}
-
-const set<HashableDimensionKey>* ConditionWizard::getChangedToFalseDimensions(
- const int index) const {
- return mAllConditions[index]->getChangedToFalseDimensions(mAllConditions);
-}
-
-bool ConditionWizard::IsChangedDimensionTrackable(const int index) {
- if (index >= 0 && index < (int)mAllConditions.size()) {
- return mAllConditions[index]->IsChangedDimensionTrackable();
- } else {
- return false;
- }
-}
-
-bool ConditionWizard::IsSimpleCondition(const int index) {
- if (index >= 0 && index < (int)mAllConditions.size()) {
- return mAllConditions[index]->IsSimpleCondition();
- } else {
- return false;
- }
-}
-
-bool ConditionWizard::equalOutputDimensions(const int index, const vector<Matcher>& dimensions) {
- if (index >= 0 && index < (int)mAllConditions.size()) {
- return mAllConditions[index]->equalOutputDimensions(mAllConditions, dimensions);
- } else {
- return false;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
deleted file mode 100644
index 892647910d9f..000000000000
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CONDITION_WIZARD_H
-#define CONDITION_WIZARD_H
-
-#include "ConditionTracker.h"
-#include "condition_util.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Held by MetricProducer, to query a condition state with input defined in MetricConditionLink.
-class ConditionWizard : public virtual android::RefBase {
-public:
- ConditionWizard(){}; // for testing
- explicit ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
- : mAllConditions(conditionTrackers){};
-
- virtual ~ConditionWizard(){};
-
- // Query condition state, for a ConditionTracker at [conditionIndex], with [conditionParameters]
- // [conditionParameters] mapping from condition name to the HashableDimensionKey to query the
- // condition.
- // The ConditionTracker at [conditionIndex] can be a CombinationConditionTracker. In this case,
- // the conditionParameters contains the parameters for it's children SimpleConditionTrackers.
- virtual ConditionState query(const int conditionIndex, const ConditionKey& conditionParameters,
- const bool isPartialLink);
-
- virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(const int index) const;
- virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const int index) const;
- bool equalOutputDimensions(const int index, const vector<Matcher>& dimensions);
-
- bool IsChangedDimensionTrackable(const int index);
- bool IsSimpleCondition(const int index);
-
- ConditionState getUnSlicedPartConditionState(const int index) {
- return mAllConditions[index]->getUnSlicedPartConditionState();
- }
- void getTrueSlicedDimensions(const int index,
- std::set<HashableDimensionKey>* trueDimensions) const {
- return mAllConditions[index]->getTrueSlicedDimensions(mAllConditions, trueDimensions);
- }
-
-private:
- std::vector<sp<ConditionTracker>> mAllConditions;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // CONDITION_WIZARD_H
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
deleted file mode 100644
index efb4d4989425..000000000000
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "SimpleConditionTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-
-SimpleConditionTracker::SimpleConditionTracker(
- const ConfigKey& key, const int64_t& id, const int index,
- const SimplePredicate& simplePredicate,
- const unordered_map<int64_t, int>& trackerNameIndexMap)
- : ConditionTracker(id, index), mConfigKey(key), mContainANYPositionInInternalDimensions(false) {
- VLOG("creating SimpleConditionTracker %lld", (long long)mConditionId);
- mCountNesting = simplePredicate.count_nesting();
-
- if (simplePredicate.has_start()) {
- auto pair = trackerNameIndexMap.find(simplePredicate.start());
- if (pair == trackerNameIndexMap.end()) {
- ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start());
- return;
- }
- mStartLogMatcherIndex = pair->second;
- mTrackerIndex.insert(mStartLogMatcherIndex);
- } else {
- mStartLogMatcherIndex = -1;
- }
-
- if (simplePredicate.has_stop()) {
- auto pair = trackerNameIndexMap.find(simplePredicate.stop());
- if (pair == trackerNameIndexMap.end()) {
- ALOGW("Stop matcher %lld not found in the config", (long long)simplePredicate.stop());
- return;
- }
- mStopLogMatcherIndex = pair->second;
- mTrackerIndex.insert(mStopLogMatcherIndex);
- } else {
- mStopLogMatcherIndex = -1;
- }
-
- if (simplePredicate.has_stop_all()) {
- auto pair = trackerNameIndexMap.find(simplePredicate.stop_all());
- if (pair == trackerNameIndexMap.end()) {
- ALOGW("Stop all matcher %lld found in the config", (long long)simplePredicate.stop_all());
- return;
- }
- mStopAllLogMatcherIndex = pair->second;
- mTrackerIndex.insert(mStopAllLogMatcherIndex);
- } else {
- mStopAllLogMatcherIndex = -1;
- }
-
- if (simplePredicate.has_dimensions()) {
- translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions);
- if (mOutputDimensions.size() > 0) {
- mSliced = true;
- mDimensionTag = mOutputDimensions[0].mMatcher.getTag();
- }
- mContainANYPositionInInternalDimensions = HasPositionANY(simplePredicate.dimensions());
- }
-
- if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) {
- mInitialValue = ConditionState::kFalse;
- } else {
- mInitialValue = ConditionState::kUnknown;
- }
-
- mInitialized = true;
-}
-
-SimpleConditionTracker::~SimpleConditionTracker() {
- VLOG("~SimpleConditionTracker()");
-}
-
-bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
- const vector<sp<ConditionTracker>>& allConditionTrackers,
- const unordered_map<int64_t, int>& conditionIdIndexMap,
- vector<bool>& stack,
- vector<ConditionState>& initialConditionCache) {
- // SimpleConditionTracker does not have dependency on other conditions, thus we just return
- // if the initialization was successful.
- initialConditionCache[mIndex] = mInitialValue;
- return mInitialized;
-}
-
-void SimpleConditionTracker::dumpState() {
- VLOG("%lld DUMP:", (long long)mConditionId);
- for (const auto& pair : mSlicedConditionState) {
- VLOG("\t%s : %d", pair.first.toString().c_str(), pair.second);
- }
-
- VLOG("Changed to true keys: \n");
- for (const auto& key : mLastChangedToTrueDimensions) {
- VLOG("%s", key.toString().c_str());
- }
- VLOG("Changed to false keys: \n");
- for (const auto& key : mLastChangedToFalseDimensions) {
- VLOG("%s", key.toString().c_str());
- }
-}
-
-void SimpleConditionTracker::handleStopAll(std::vector<ConditionState>& conditionCache,
- std::vector<bool>& conditionChangedCache) {
- // Unless the default condition is false, and there was nothing started, otherwise we have
- // triggered a condition change.
- conditionChangedCache[mIndex] =
- (mInitialValue == ConditionState::kFalse && mSlicedConditionState.empty()) ? false
- : true;
-
- for (const auto& cond : mSlicedConditionState) {
- if (cond.second > 0) {
- mLastChangedToFalseDimensions.insert(cond.first);
- }
- }
-
- // After StopAll, we know everything has stopped. From now on, default condition is false.
- mInitialValue = ConditionState::kFalse;
- mSlicedConditionState.clear();
- conditionCache[mIndex] = ConditionState::kFalse;
-}
-
-bool SimpleConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) {
- if (!mSliced || mSlicedConditionState.find(newKey) != mSlicedConditionState.end()) {
- // if the condition is not sliced or the key is not new, we are good!
- return false;
- }
- // 1. Report the tuple count if the tuple count > soft limit
- if (mSlicedConditionState.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mSlicedConditionState.size() + 1;
- StatsdStats::getInstance().noteConditionDimensionSize(mConfigKey, mConditionId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("Predicate %lld dropping data for dimension key %s",
- (long long)mConditionId, newKey.toString().c_str());
- return true;
- }
- }
- return false;
-}
-
-void SimpleConditionTracker::handleConditionEvent(const HashableDimensionKey& outputKey,
- bool matchStart, ConditionState* conditionCache,
- bool* conditionChangedCache) {
- bool changed = false;
- auto outputIt = mSlicedConditionState.find(outputKey);
- ConditionState newCondition;
- if (hitGuardRail(outputKey)) {
- (*conditionChangedCache) = false;
- // Tells the caller it's evaluated.
- (*conditionCache) = ConditionState::kUnknown;
- return;
- }
- if (outputIt == mSlicedConditionState.end()) {
- // We get a new output key.
- newCondition = matchStart ? ConditionState::kTrue : ConditionState::kFalse;
- if (matchStart && mInitialValue != ConditionState::kTrue) {
- mSlicedConditionState[outputKey] = 1;
- changed = true;
- mLastChangedToTrueDimensions.insert(outputKey);
- } else if (mInitialValue != ConditionState::kFalse) {
- // it's a stop and we don't have history about it.
- // If the default condition is not false, it means this stop is valuable to us.
- mSlicedConditionState[outputKey] = 0;
- mLastChangedToFalseDimensions.insert(outputKey);
- changed = true;
- }
- } else {
- // we have history about this output key.
- auto& startedCount = outputIt->second;
- // assign the old value first.
- newCondition = startedCount > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- if (matchStart) {
- if (startedCount == 0) {
- mLastChangedToTrueDimensions.insert(outputKey);
- // This condition for this output key will change from false -> true
- changed = true;
- }
-
- // it's ok to do ++ here, even if we don't count nesting. The >1 counts will be treated
- // as 1 if not counting nesting.
- startedCount++;
- newCondition = ConditionState::kTrue;
- } else {
- // This is a stop event.
- if (startedCount > 0) {
- if (mCountNesting) {
- startedCount--;
- if (startedCount == 0) {
- newCondition = ConditionState::kFalse;
- }
- } else {
- // not counting nesting, so ignore the number of starts, stop now.
- startedCount = 0;
- newCondition = ConditionState::kFalse;
- }
- // if everything has stopped for this output key, condition true -> false;
- if (startedCount == 0) {
- mLastChangedToFalseDimensions.insert(outputKey);
- changed = true;
- }
- }
-
- // if default condition is false, it means we don't need to keep the false values.
- if (mInitialValue == ConditionState::kFalse && startedCount == 0) {
- mSlicedConditionState.erase(outputIt);
- VLOG("erase key %s", outputKey.toString().c_str());
- }
- }
- }
-
- // dump all dimensions for debugging
- if (DEBUG) {
- dumpState();
- }
-
- (*conditionChangedCache) = changed;
- (*conditionCache) = newCondition;
-
- VLOG("SimplePredicate %lld nonSlicedChange? %d", (long long)mConditionId,
- conditionChangedCache[mIndex] == true);
-}
-
-void SimpleConditionTracker::evaluateCondition(
- const LogEvent& event,
- const vector<MatchingState>& eventMatcherValues,
- const vector<sp<ConditionTracker>>& mAllConditions,
- vector<ConditionState>& conditionCache,
- vector<bool>& conditionChangedCache) {
- if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
- // it has been evaluated.
- VLOG("Yes, already evaluated, %lld %d",
- (long long)mConditionId, conditionCache[mIndex]);
- return;
- }
- mLastChangedToTrueDimensions.clear();
- mLastChangedToFalseDimensions.clear();
-
- if (mStopAllLogMatcherIndex >= 0 && mStopAllLogMatcherIndex < int(eventMatcherValues.size()) &&
- eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
- handleStopAll(conditionCache, conditionChangedCache);
- return;
- }
-
- int matchedState = -1;
- // Note: The order to evaluate the following start, stop, stop_all matters.
- // The priority of overwrite is stop_all > stop > start.
- if (mStartLogMatcherIndex >= 0 &&
- eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
- matchedState = 1;
- }
-
- if (mStopLogMatcherIndex >= 0 &&
- eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
- matchedState = 0;
- }
-
- if (matchedState < 0) {
- // The event doesn't match this condition. So we just report existing condition values.
- conditionChangedCache[mIndex] = false;
- if (mSliced) {
- // if the condition result is sliced. The overall condition is true if any of the sliced
- // condition is true
- conditionCache[mIndex] = mInitialValue;
- for (const auto& slicedCondition : mSlicedConditionState) {
- if (slicedCondition.second > 0) {
- conditionCache[mIndex] = ConditionState::kTrue;
- break;
- }
- }
- } else {
- const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
- if (itr == mSlicedConditionState.end()) {
- // condition not sliced, but we haven't seen the matched start or stop yet. so
- // return initial value.
- conditionCache[mIndex] = mInitialValue;
- } else {
- // return the cached condition.
- conditionCache[mIndex] =
- itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- }
- }
- return;
- }
-
- ConditionState overallState = mInitialValue;
- bool overallChanged = false;
-
- if (mOutputDimensions.size() == 0) {
- handleConditionEvent(DEFAULT_DIMENSION_KEY, matchedState == 1, &overallState,
- &overallChanged);
- } else if (!mContainANYPositionInInternalDimensions) {
- HashableDimensionKey outputValue;
- filterValues(mOutputDimensions, event.getValues(), &outputValue);
-
- // If this event has multiple nodes in the attribution chain, this log event probably will
- // generate multiple dimensions. If so, we will find if the condition changes for any
- // dimension and ask the corresponding metric producer to verify whether the actual sliced
- // condition has changed or not.
- // A high level assumption is that a predicate is either sliced or unsliced. We will never
- // have both sliced and unsliced version of a predicate.
- handleConditionEvent(outputValue, matchedState == 1, &overallState, &overallChanged);
- } else {
- ALOGE("The condition tracker should not be sliced by ANY position matcher.");
- }
- conditionCache[mIndex] = overallState;
- conditionChangedCache[mIndex] = overallChanged;
-}
-
-void SimpleConditionTracker::isConditionMet(
- const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- vector<ConditionState>& conditionCache) const {
-
- if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
- // it has been evaluated.
- VLOG("Yes, already evaluated, %lld %d",
- (long long)mConditionId, conditionCache[mIndex]);
- return;
- }
- const auto pair = conditionParameters.find(mConditionId);
-
- if (pair == conditionParameters.end()) {
- ConditionState conditionState = ConditionState::kNotEvaluated;
- conditionState = conditionState | mInitialValue;
- if (!mSliced) {
- const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
- if (itr != mSlicedConditionState.end()) {
- ConditionState sliceState =
- itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
- }
- }
- conditionCache[mIndex] = conditionState;
- return;
- }
-
- ConditionState conditionState = ConditionState::kNotEvaluated;
- const HashableDimensionKey& key = pair->second;
- if (isPartialLink) {
- // For unseen key, check whether the require dimensions are subset of sliced condition
- // output.
- conditionState = conditionState | mInitialValue;
- for (const auto& slice : mSlicedConditionState) {
- ConditionState sliceState =
- slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- if (slice.first.contains(key)) {
- conditionState = conditionState | sliceState;
- }
- }
- } else {
- auto startedCountIt = mSlicedConditionState.find(key);
- conditionState = conditionState | mInitialValue;
- if (startedCountIt != mSlicedConditionState.end()) {
- ConditionState sliceState =
- startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
- conditionState = conditionState | sliceState;
- }
-
- }
- conditionCache[mIndex] = conditionState;
- VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
deleted file mode 100644
index ea7f87bde2b8..000000000000
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SIMPLE_CONDITION_TRACKER_H
-#define SIMPLE_CONDITION_TRACKER_H
-
-#include <gtest/gtest_prod.h>
-#include "ConditionTracker.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class SimpleConditionTracker : public virtual ConditionTracker {
-public:
- SimpleConditionTracker(const ConfigKey& key, const int64_t& id, const int index,
- const SimplePredicate& simplePredicate,
- const std::unordered_map<int64_t, int>& trackerNameIndexMap);
-
- ~SimpleConditionTracker();
-
- bool init(const std::vector<Predicate>& allConditionConfig,
- const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
- std::vector<ConditionState>& initialConditionCache) override;
-
- void evaluateCondition(const LogEvent& event,
- const std::vector<MatchingState>& eventMatcherValues,
- const std::vector<sp<ConditionTracker>>& mAllConditions,
- std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache) override;
-
- void isConditionMet(const ConditionKey& conditionParameters,
- const std::vector<sp<ConditionTracker>>& allConditions,
- const bool isPartialLink,
- std::vector<ConditionState>& conditionCache) const override;
-
- virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const {
- if (mSliced) {
- return &mLastChangedToTrueDimensions;
- } else {
- return nullptr;
- }
- }
-
- virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions) const {
- if (mSliced) {
- return &mLastChangedToFalseDimensions;
- } else {
- return nullptr;
- }
- }
-
- void getTrueSlicedDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- std::set<HashableDimensionKey>* dimensions) const override {
- for (const auto& itr : mSlicedConditionState) {
- if (itr.second > 0) {
- dimensions->insert(itr.first);
- }
- }
- }
-
- bool IsChangedDimensionTrackable() const override { return true; }
-
- bool IsSimpleCondition() const override { return true; }
-
- bool equalOutputDimensions(
- const std::vector<sp<ConditionTracker>>& allConditions,
- const vector<Matcher>& dimensions) const override {
- return equalDimensions(mOutputDimensions, dimensions);
- }
-
-private:
- const ConfigKey mConfigKey;
- // The index of the LogEventMatcher which defines the start.
- int mStartLogMatcherIndex;
-
- // The index of the LogEventMatcher which defines the end.
- int mStopLogMatcherIndex;
-
- // if the start end needs to be nested.
- bool mCountNesting;
-
- // The index of the LogEventMatcher which defines the stop all.
- int mStopAllLogMatcherIndex;
-
- ConditionState mInitialValue;
-
- std::vector<Matcher> mOutputDimensions;
-
- bool mContainANYPositionInInternalDimensions;
-
- std::set<HashableDimensionKey> mLastChangedToTrueDimensions;
- std::set<HashableDimensionKey> mLastChangedToFalseDimensions;
-
- int mDimensionTag;
-
- std::map<HashableDimensionKey, int> mSlicedConditionState;
-
- void handleStopAll(std::vector<ConditionState>& conditionCache,
- std::vector<bool>& changedCache);
-
- void handleConditionEvent(const HashableDimensionKey& outputKey, bool matchStart,
- ConditionState* conditionCache, bool* changedCache);
-
- bool hitGuardRail(const HashableDimensionKey& newKey);
-
- void dumpState();
-
- FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedCondition);
- FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim);
- FRIEND_TEST(SimpleConditionTrackerTest, TestStopAll);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // SIMPLE_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
deleted file mode 100644
index 60b8c53e91e1..000000000000
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Log.h"
-
-#include "condition_util.h"
-
-#include "../matchers/matcher_util.h"
-#include "ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-
-ConditionState evaluateCombinationCondition(const std::vector<int>& children,
- const LogicalOperation& operation,
- const std::vector<ConditionState>& conditionCache) {
- ConditionState newCondition;
-
- bool hasUnknown = false;
- bool hasFalse = false;
- bool hasTrue = false;
-
- for (auto childIndex : children) {
- ConditionState childState = conditionCache[childIndex];
- if (childState == ConditionState::kUnknown) {
- hasUnknown = true;
- break;
- }
- if (childState == ConditionState::kFalse) {
- hasFalse = true;
- }
- if (childState == ConditionState::kTrue) {
- hasTrue = true;
- }
- }
-
- // If any child condition is in unknown state, the condition is unknown too.
- if (hasUnknown) {
- return ConditionState::kUnknown;
- }
-
- switch (operation) {
- case LogicalOperation::AND: {
- newCondition = hasFalse ? ConditionState::kFalse : ConditionState::kTrue;
- break;
- }
- case LogicalOperation::OR: {
- newCondition = hasTrue ? ConditionState::kTrue : ConditionState::kFalse;
- break;
- }
- case LogicalOperation::NOT:
- newCondition = children.empty() ? ConditionState::kUnknown :
- ((conditionCache[children[0]] == ConditionState::kFalse) ?
- ConditionState::kTrue : ConditionState::kFalse);
- break;
- case LogicalOperation::NAND:
- newCondition = hasFalse ? ConditionState::kTrue : ConditionState::kFalse;
- break;
- case LogicalOperation::NOR:
- newCondition = hasTrue ? ConditionState::kFalse : ConditionState::kTrue;
- break;
- case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
- newCondition = ConditionState::kFalse;
- break;
- }
- return newCondition;
-}
-
-ConditionState operator|(ConditionState l, ConditionState r) {
- return l >= r ? l : r;
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/condition/condition_util.h b/cmds/statsd/src/condition/condition_util.h
deleted file mode 100644
index fed90ec3da37..000000000000
--- a/cmds/statsd/src/condition/condition_util.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CONDITION_UTIL_H
-#define CONDITION_UTIL_H
-
-#include <vector>
-#include "../matchers/matcher_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum ConditionState {
- kNotEvaluated = -2,
- kUnknown = -1,
- kFalse = 0,
- kTrue = 1,
-};
-
-ConditionState operator|(ConditionState l, ConditionState r);
-
-ConditionState evaluateCombinationCondition(const std::vector<int>& children,
- const LogicalOperation& operation,
- const std::vector<ConditionState>& conditionCache);
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // CONDITION_UTIL_H
diff --git a/cmds/statsd/src/config/ConfigKey.cpp b/cmds/statsd/src/config/ConfigKey.cpp
deleted file mode 100644
index 4a2bd2799df8..000000000000
--- a/cmds/statsd/src/config/ConfigKey.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "config/ConfigKey.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConfigKey::ConfigKey() {
-}
-
-ConfigKey::ConfigKey(const ConfigKey& that) : mId(that.mId), mUid(that.mUid) {
-}
-
-ConfigKey::ConfigKey(int uid, const int64_t& id) : mId(id), mUid(uid) {
-}
-
-ConfigKey::~ConfigKey() {
-}
-
-string ConfigKey::ToString() const {
- string s;
- s += "(" + std::to_string(mUid) + " " + std::to_string(mId) + ")";
- return s;
-}
-
-
-int64_t StrToInt64(const string& str) {
- char* endp;
- int64_t value;
- value = strtoll(str.c_str(), &endp, 0);
- if (endp == str.c_str() || *endp != '\0') {
- value = 0;
- }
- return value;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h
deleted file mode 100644
index 4cc9393fbd02..000000000000
--- a/cmds/statsd/src/config/ConfigKey.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::hash;
-using std::string;
-
-/**
- * Uniquely identifies a configuration.
- */
-class ConfigKey {
-public:
- ConfigKey();
- ConfigKey(const ConfigKey& that);
- ConfigKey(int uid, const int64_t& id);
- ~ConfigKey();
-
- inline int GetUid() const {
- return mUid;
- }
- inline const int64_t& GetId() const {
- return mId;
- }
-
- inline bool operator<(const ConfigKey& that) const {
- if (mUid < that.mUid) {
- return true;
- }
- if (mUid > that.mUid) {
- return false;
- }
- return mId < that.mId;
- };
-
- inline bool operator==(const ConfigKey& that) const {
- return mUid == that.mUid && mId == that.mId;
- };
-
- string ToString() const;
-
-private:
- int64_t mId;
- int mUid;
-};
-
-int64_t StrToInt64(const string& str);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-/**
- * A hash function for ConfigKey so it can be used for unordered_map/set.
- * Unfortunately this has to go in std namespace because C++ is fun!
- */
-namespace std {
-
-using android::os::statsd::ConfigKey;
-
-template <>
-struct hash<ConfigKey> {
- std::size_t operator()(const ConfigKey& key) const {
- return (7 * key.GetUid()) ^ ((hash<long long>()(key.GetId())));
- }
-};
-
-} // namespace std
diff --git a/cmds/statsd/src/config/ConfigListener.cpp b/cmds/statsd/src/config/ConfigListener.cpp
deleted file mode 100644
index 21a3f1673fd7..000000000000
--- a/cmds/statsd/src/config/ConfigListener.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "config/ConfigListener.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConfigListener::ConfigListener() {
-}
-
-ConfigListener::~ConfigListener() {
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h
deleted file mode 100644
index dcd5e52feefd..000000000000
--- a/cmds/statsd/src/config/ConfigListener.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::RefBase;
-
-/**
- * Callback for different subsystems inside statsd to implement to find out
- * when a configuration has been added, updated or removed.
- */
-class ConfigListener : public virtual RefBase {
-public:
- ConfigListener();
- virtual ~ConfigListener();
-
- /**
- * A configuration was added or updated.
- */
- virtual void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config) = 0;
-
- /**
- * A configuration was removed.
- */
- virtual void OnConfigRemoved(const ConfigKey& key) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
deleted file mode 100644
index bbae3fef7934..000000000000
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "config/ConfigManager.h"
-#include "storage/StorageManager.h"
-
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <stdio.h>
-#include <vector>
-#include "android-base/stringprintf.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::pair;
-using std::string;
-using std::vector;
-
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-
-using android::base::StringPrintf;
-using std::unique_ptr;
-
-struct ConfigReceiverDeathCookie {
- ConfigReceiverDeathCookie(const wp<ConfigManager>& configManager, const ConfigKey& configKey,
- const shared_ptr<IPendingIntentRef>& pir) :
- mConfigManager(configManager), mConfigKey(configKey), mPir(pir) {
- }
-
- wp<ConfigManager> mConfigManager;
- ConfigKey mConfigKey;
- shared_ptr<IPendingIntentRef> mPir;
-};
-
-void ConfigManager::configReceiverDied(void* cookie) {
- auto cookie_ = static_cast<ConfigReceiverDeathCookie*>(cookie);
- sp<ConfigManager> thiz = cookie_->mConfigManager.promote();
- if (!thiz) {
- return;
- }
-
- ConfigKey& configKey = cookie_->mConfigKey;
- shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
- // Erase the mapping from the config key to the config receiver (pir) if the
- // mapping still exists.
- lock_guard<mutex> lock(thiz->mMutex);
- auto it = thiz->mConfigReceivers.find(configKey);
- if (it != thiz->mConfigReceivers.end() && it->second == pir) {
- thiz->mConfigReceivers.erase(configKey);
- }
-
- // The death recipient corresponding to this specific pir can never be
- // triggered again, so free up resources.
- delete cookie_;
-}
-
-struct ActiveConfigChangedReceiverDeathCookie {
- ActiveConfigChangedReceiverDeathCookie(const wp<ConfigManager>& configManager, const int uid,
- const shared_ptr<IPendingIntentRef>& pir) :
- mConfigManager(configManager), mUid(uid), mPir(pir) {
- }
-
- wp<ConfigManager> mConfigManager;
- int mUid;
- shared_ptr<IPendingIntentRef> mPir;
-};
-
-void ConfigManager::activeConfigChangedReceiverDied(void* cookie) {
- auto cookie_ = static_cast<ActiveConfigChangedReceiverDeathCookie*>(cookie);
- sp<ConfigManager> thiz = cookie_->mConfigManager.promote();
- if (!thiz) {
- return;
- }
-
- int uid = cookie_->mUid;
- shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
- // Erase the mapping from the config key to the active config changed
- // receiver (pir) if the mapping still exists.
- lock_guard<mutex> lock(thiz->mMutex);
- auto it = thiz->mActiveConfigsChangedReceivers.find(uid);
- if (it != thiz->mActiveConfigsChangedReceivers.end() && it->second == pir) {
- thiz->mActiveConfigsChangedReceivers.erase(uid);
- }
-
- // The death recipient corresponding to this specific pir can never
- // be triggered again, so free up resources.
- delete cookie_;
-}
-
-ConfigManager::ConfigManager() :
- mConfigReceiverDeathRecipient(AIBinder_DeathRecipient_new(configReceiverDied)),
- mActiveConfigChangedReceiverDeathRecipient(
- AIBinder_DeathRecipient_new(activeConfigChangedReceiverDied)) {
-}
-
-ConfigManager::~ConfigManager() {
-}
-
-void ConfigManager::Startup() {
- map<ConfigKey, StatsdConfig> configsFromDisk;
- StorageManager::readConfigFromDisk(configsFromDisk);
- for (const auto& pair : configsFromDisk) {
- UpdateConfig(pair.first, pair.second);
- }
-}
-
-void ConfigManager::StartupForTest() {
- // Dummy function to avoid reading configs from disks for tests.
-}
-
-void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
- lock_guard<mutex> lock(mMutex);
- mListeners.push_back(listener);
-}
-
-void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- const int numBytes = config.ByteSize();
- vector<uint8_t> buffer(numBytes);
- config.SerializeToArray(&buffer[0], numBytes);
-
- auto uidIt = mConfigs.find(key.GetUid());
- // GuardRail: Limit the number of configs per uid.
- if (uidIt != mConfigs.end()) {
- auto it = uidIt->second.find(key);
- if (it == uidIt->second.end() &&
- uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
- ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
- return;
- }
- }
-
- // Check if it's a duplicate config.
- if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
- StorageManager::hasIdenticalConfig(key, buffer)) {
- // This is a duplicate config.
- ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
- // Update saved file on disk. We still update timestamp of file when
- // there exists a duplicate configuration to avoid garbage collection.
- update_saved_configs_locked(key, buffer, numBytes);
- return;
- }
-
- // Update saved file on disk.
- update_saved_configs_locked(key, buffer, numBytes);
-
- // Add to set.
- mConfigs[key.GetUid()].insert(key);
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- const int64_t timestampNs = getElapsedRealtimeNs();
- // Tell everyone
- for (const sp<ConfigListener>& listener : broadcastList) {
- listener->OnConfigUpdated(timestampNs, key, config);
- }
-}
-
-void ConfigManager::SetConfigReceiver(const ConfigKey& key,
- const shared_ptr<IPendingIntentRef>& pir) {
- lock_guard<mutex> lock(mMutex);
- mConfigReceivers[key] = pir;
- AIBinder_linkToDeath(pir->asBinder().get(), mConfigReceiverDeathRecipient.get(),
- new ConfigReceiverDeathCookie(this, key, pir));
-}
-
-void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
- lock_guard<mutex> lock(mMutex);
- mConfigReceivers.erase(key);
-}
-
-void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
- const shared_ptr<IPendingIntentRef>& pir) {
- {
- lock_guard<mutex> lock(mMutex);
- mActiveConfigsChangedReceivers[uid] = pir;
- }
- AIBinder_linkToDeath(pir->asBinder().get(), mActiveConfigChangedReceiverDeathRecipient.get(),
- new ActiveConfigChangedReceiverDeathCookie(this, uid, pir));
-}
-
-void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
- lock_guard<mutex> lock(mMutex);
- mActiveConfigsChangedReceivers.erase(uid);
-}
-
-void ConfigManager::RemoveConfig(const ConfigKey& key) {
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- auto uid = key.GetUid();
- auto uidIt = mConfigs.find(uid);
- if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
- // Remove from map
- uidIt->second.erase(key);
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- // Remove from disk. There can still be a lingering file on disk so we check
- // whether or not the config was on memory.
- remove_saved_configs(key);
- }
-
- for (const sp<ConfigListener>& listener:broadcastList) {
- listener->OnConfigRemoved(key);
- }
-}
-
-void ConfigManager::remove_saved_configs(const ConfigKey& key) {
- string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
- StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
-}
-
-void ConfigManager::RemoveConfigs(int uid) {
- vector<ConfigKey> removed;
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- auto uidIt = mConfigs.find(uid);
- if (uidIt == mConfigs.end()) {
- return;
- }
-
- for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
- // Remove from map
- remove_saved_configs(*it);
- removed.push_back(*it);
- }
-
- mConfigs.erase(uidIt);
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- // Remove separately so if they do anything in the callback they can't mess up our iteration.
- for (auto& key : removed) {
- // Tell everyone
- for (const sp<ConfigListener>& listener:broadcastList) {
- listener->OnConfigRemoved(key);
- }
- }
-}
-
-void ConfigManager::RemoveAllConfigs() {
- vector<ConfigKey> removed;
- vector<sp<ConfigListener>> broadcastList;
- {
- lock_guard <mutex> lock(mMutex);
-
- for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
- for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
- // Remove from map
- removed.push_back(*it);
- it = uidIt->second.erase(it);
- }
- uidIt = mConfigs.erase(uidIt);
- }
-
- for (const sp<ConfigListener>& listener : mListeners) {
- broadcastList.push_back(listener);
- }
- }
-
- // Remove separately so if they do anything in the callback they can't mess up our iteration.
- for (auto& key : removed) {
- // Tell everyone
- for (const sp<ConfigListener>& listener:broadcastList) {
- listener->OnConfigRemoved(key);
- }
- }
-}
-
-vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
- lock_guard<mutex> lock(mMutex);
-
- vector<ConfigKey> ret;
- for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
- for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
- ret.push_back(*it);
- }
- }
- return ret;
-}
-
-const shared_ptr<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mConfigReceivers.find(key);
- if (it == mConfigReceivers.end()) {
- return nullptr;
- } else {
- return it->second;
- }
-}
-
-const shared_ptr<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid)
- const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mActiveConfigsChangedReceivers.find(uid);
- if (it == mActiveConfigsChangedReceivers.end()) {
- return nullptr;
- } else {
- return it->second;
- }
-}
-
-void ConfigManager::Dump(FILE* out) {
- lock_guard<mutex> lock(mMutex);
-
- fprintf(out, "CONFIGURATIONS\n");
- fprintf(out, " uid name\n");
- for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
- for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
- fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
- auto receiverIt = mConfigReceivers.find(*it);
- if (receiverIt != mConfigReceivers.end()) {
- fprintf(out, " -> received by PendingIntent as binder\n");
- }
- }
- }
-}
-
-void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
- const vector<uint8_t>& buffer,
- const int numBytes) {
- // If there is a pre-existing config with same key we should first delete it.
- remove_saved_configs(key);
-
- // Then we save the latest config.
- string file_name =
- StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
- key.GetUid(), (long long)key.GetId());
- StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
deleted file mode 100644
index 40146b1b2bec..000000000000
--- a/cmds/statsd/src/config/ConfigManager.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
-
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <mutex>
-#include <string>
-
-#include <stdio.h>
-
-using aidl::android::os::IPendingIntentRef;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Keeps track of which configurations have been set from various sources.
- */
-class ConfigManager : public virtual android::RefBase {
-public:
- ConfigManager();
- virtual ~ConfigManager();
-
- /**
- * Initialize ConfigListener by reading from disk and get updates.
- */
- void Startup();
-
- /*
- * Dummy initializer for tests.
- */
- void StartupForTest();
-
- /**
- * Someone else wants to know about the configs.
- */
- void AddListener(const sp<ConfigListener>& listener);
-
- /**
- * A configuration was added or updated.
- *
- * Reports this to listeners.
- */
- void UpdateConfig(const ConfigKey& key, const StatsdConfig& data);
-
- /**
- * Sets the broadcast receiver for a configuration key.
- */
- void SetConfigReceiver(const ConfigKey& key, const shared_ptr<IPendingIntentRef>& pir);
-
- /**
- * Returns the package name and class name representing the broadcast receiver for this config.
- */
- const shared_ptr<IPendingIntentRef> GetConfigReceiver(const ConfigKey& key) const;
-
- /**
- * Returns all config keys registered.
- */
- std::vector<ConfigKey> GetAllConfigKeys() const;
-
- /**
- * Erase any broadcast receiver associated with this config key.
- */
- void RemoveConfigReceiver(const ConfigKey& key);
-
- /**
- * Sets the broadcast receiver that is notified whenever the list of active configs
- * changes for this uid.
- */
- void SetActiveConfigsChangedReceiver(const int uid, const shared_ptr<IPendingIntentRef>& pir);
-
- /**
- * Returns the broadcast receiver for active configs changed for this uid.
- */
-
- const shared_ptr<IPendingIntentRef> GetActiveConfigsChangedReceiver(const int uid) const;
-
- /**
- * Erase any active configs changed broadcast receiver associated with this uid.
- */
- void RemoveActiveConfigsChangedReceiver(const int uid);
-
- /**
- * A configuration was removed.
- *
- * Reports this to listeners.
- */
- void RemoveConfig(const ConfigKey& key);
-
- /**
- * Remove all of the configs for the given uid.
- */
- void RemoveConfigs(int uid);
-
- /**
- * Remove all of the configs from memory.
- */
- void RemoveAllConfigs();
-
- /**
- * Text dump of our state for debugging.
- */
- void Dump(FILE* out);
-
-private:
- mutable std::mutex mMutex;
-
- /**
- * Save the configs to disk.
- */
- void update_saved_configs_locked(const ConfigKey& key,
- const std::vector<uint8_t>& buffer,
- const int numBytes);
-
- /**
- * Remove saved configs from disk.
- */
- void remove_saved_configs(const ConfigKey& key);
-
- /**
- * Maps from uid to the config keys that have been set.
- */
- std::map<int, std::set<ConfigKey>> mConfigs;
-
- /**
- * Each config key can be subscribed by up to one receiver, specified as IPendingIntentRef.
- */
- std::map<ConfigKey, shared_ptr<IPendingIntentRef>> mConfigReceivers;
-
- /**
- * Each uid can be subscribed by up to one receiver to notify that the list of active configs
- * for this uid has changed. The receiver is specified as IPendingIntentRef.
- */
- std::map<int, shared_ptr<IPendingIntentRef>> mActiveConfigsChangedReceivers;
-
- /**
- * The ConfigListeners that will be told about changes.
- */
- std::vector<sp<ConfigListener>> mListeners;
-
- // Death recipients that are triggered when the host process holding an
- // IPendingIntentRef dies.
- ::ndk::ScopedAIBinder_DeathRecipient mConfigReceiverDeathRecipient;
- ::ndk::ScopedAIBinder_DeathRecipient mActiveConfigChangedReceiverDeathRecipient;
-
- /**
- * Death recipient callback that is called when a config receiver dies.
- * The cookie is a pointer to a ConfigReceiverDeathCookie.
- */
- static void configReceiverDied(void* cookie);
-
- /**
- * Death recipient callback that is called when an active config changed
- * receiver dies. The cookie is a pointer to an
- * ActiveConfigChangedReceiverDeathCookie.
- */
- static void activeConfigChangedReceiverDied(void* cookie);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/experiment_ids.proto b/cmds/statsd/src/experiment_ids.proto
deleted file mode 100644
index c2036314cf58..000000000000
--- a/cmds/statsd/src/experiment_ids.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "ExperimentIdsProto";
-
-// StatsLogProcessor uses the proto to parse experiment ids from
-// BinaryPushStateChanged atoms. This needs to be in sync with
-// TrainExperimentIds in atoms.proto.
-message ExperimentIds {
- repeated int64 experiment_id = 1;
-}
diff --git a/cmds/statsd/src/external/Perfetto.cpp b/cmds/statsd/src/external/Perfetto.cpp
deleted file mode 100644
index 85b660efc956..000000000000
--- a/cmds/statsd/src/external/Perfetto.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "config/ConfigKey.h"
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert
-
-#include <android-base/unique_fd.h>
-#include <inttypes.h>
-#include <sys/wait.h>
-
-#include <string>
-
-namespace {
-const char kDropboxTag[] = "perfetto";
-}
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config,
- int64_t subscription_id,
- int64_t alert_id,
- const ConfigKey& configKey) {
- VLOG("Starting trace collection through perfetto");
-
- if (!config.has_trace_config()) {
- ALOGE("The perfetto trace config is empty, aborting");
- return false;
- }
-
- char subscriptionId[25];
- char alertId[25];
- char configId[25];
- char configUid[25];
- snprintf(subscriptionId, sizeof(subscriptionId), "%" PRId64, subscription_id);
- snprintf(alertId, sizeof(alertId), "%" PRId64, alert_id);
- snprintf(configId, sizeof(configId), "%" PRId64, configKey.GetId());
- snprintf(configUid, sizeof(configUid), "%d", configKey.GetUid());
-
- android::base::unique_fd readPipe;
- android::base::unique_fd writePipe;
- if (!android::base::Pipe(&readPipe, &writePipe)) {
- ALOGE("pipe() failed while calling the Perfetto client: %s", strerror(errno));
- return false;
- }
-
- pid_t pid = fork();
- if (pid < 0) {
- ALOGE("fork() failed while calling the Perfetto client: %s", strerror(errno));
- return false;
- }
-
- if (pid == 0) {
- // Child process.
-
- // No malloc calls or library calls after this point. Remember that even
- // ALOGx (aka android_printLog()) can use dynamic memory for vsprintf().
-
- writePipe.reset(); // Close the write end (owned by the main process).
-
- // Replace stdin with |readPipe| so the main process can write into it.
- if (dup2(readPipe.get(), STDIN_FILENO) < 0) _exit(1);
- readPipe.reset();
-
- // Replace stdout/stderr with /dev/null and close any other file
- // descriptor. This is to avoid SELinux complaining about perfetto
- // trying to access files accidentally left open by statsd (i.e. files
- // that have been opened without the O_CLOEXEC flag).
- int devNullFd = open("/dev/null", O_RDWR | O_CLOEXEC);
- if (dup2(devNullFd, STDOUT_FILENO) < 0) _exit(2);
- if (dup2(devNullFd, STDERR_FILENO) < 0) _exit(3);
- close(devNullFd);
- for (int i = 0; i < 1024; i++) {
- if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO) close(i);
- }
-
- execl("/system/bin/perfetto", "perfetto", "--background", "--config", "-", "--dropbox",
- kDropboxTag, "--alert-id", alertId, "--config-id", configId, "--config-uid",
- configUid, "--subscription-id", subscriptionId, nullptr);
-
- // execl() doesn't return in case of success, if we get here something
- // failed.
- _exit(4);
- }
-
- // Main process.
-
- readPipe.reset(); // Close the read end (owned by the child process).
-
- // Using fdopen() because fwrite() has the right logic to chunking write()
- // over a pipe (see __sfvwrite()).
- FILE* writePipeStream = android::base::Fdopen(std::move(writePipe), "wb");
- if (!writePipeStream) {
- ALOGE("fdopen() failed while calling the Perfetto client: %s", strerror(errno));
- return false;
- }
-
- const std::string& cfgProto = config.trace_config();
- size_t bytesWritten = fwrite(cfgProto.data(), 1, cfgProto.size(), writePipeStream);
- fclose(writePipeStream);
- if (bytesWritten != cfgProto.size() || cfgProto.size() == 0) {
- ALOGE("fwrite() failed (ret: %zd) while calling the Perfetto client: %s", bytesWritten,
- strerror(errno));
- return false;
- }
-
- // This does NOT wait for the full duration of the trace. It just waits until
- // the process has read the config from stdin and detached.
- int childStatus = 0;
- waitpid(pid, &childStatus, 0);
- if (!WIFEXITED(childStatus) || WEXITSTATUS(childStatus) != 0) {
- ALOGE("Child process failed (0x%x) while calling the Perfetto client", childStatus);
- return false;
- }
-
- VLOG("CollectPerfettoTraceAndUploadToDropbox() succeeded");
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/Perfetto.h b/cmds/statsd/src/external/Perfetto.h
deleted file mode 100644
index 095782a49f9b..000000000000
--- a/cmds/statsd/src/external/Perfetto.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConfigKey;
-class PerfettoDetails; // Declared in statsd_config.pb.h
-
-// Starts the collection of a Perfetto trace with the given |config|.
-// The trace is uploaded to Dropbox by the perfetto cmdline util once done.
-// This method returns immediately after passing the config and does NOT wait
-// for the full duration of the trace.
-bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config,
- int64_t subscription_id,
- int64_t alert_id,
- const ConfigKey& configKey);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullDataReceiver.h b/cmds/statsd/src/external/PullDataReceiver.h
deleted file mode 100644
index dd5c0cfa04c1..000000000000
--- a/cmds/statsd/src/external/PullDataReceiver.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullDataReceiver : virtual public RefBase{
- public:
- virtual ~PullDataReceiver() {}
- /**
- * @param data The pulled data.
- * @param pullSuccess Whether the pull succeeded. If the pull does not succeed, the data for the
- * bucket should be invalidated.
- * @param originalPullTimeNs This is when all the pulls have been initiated (elapsed time).
- */
- virtual void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
- bool pullSuccess, int64_t originalPullTimeNs) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullResultReceiver.cpp b/cmds/statsd/src/external/PullResultReceiver.cpp
deleted file mode 100644
index 8aa4792dc179..000000000000
--- a/cmds/statsd/src/external/PullResultReceiver.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "PullResultReceiver.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-PullResultReceiver::PullResultReceiver(
- std::function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCb)
- : pullFinishCallback(std::move(pullFinishCb)) {
-}
-
-Status PullResultReceiver::pullFinished(int32_t atomTag, bool success,
- const vector<StatsEventParcel>& output) {
- pullFinishCallback(atomTag, success, output);
- return Status::ok();
-}
-
-PullResultReceiver::~PullResultReceiver() {
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullResultReceiver.h b/cmds/statsd/src/external/PullResultReceiver.h
deleted file mode 100644
index ceaae801b2d5..000000000000
--- a/cmds/statsd/src/external/PullResultReceiver.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <aidl/android/os/BnPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomResultReceiver;
-using aidl::android::util::StatsEventParcel;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullResultReceiver : public BnPullAtomResultReceiver {
-public:
- PullResultReceiver(function<void(int32_t, bool, const vector<StatsEventParcel>&)>
- pullFinishCallback);
- ~PullResultReceiver();
-
- /**
- * Binder call for finishing a pull.
- */
- Status pullFinished(int32_t atomTag, bool success,
- const vector<StatsEventParcel>& output) override;
-
-private:
- function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCallback;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/PullUidProvider.h b/cmds/statsd/src/external/PullUidProvider.h
deleted file mode 100644
index 2318c501ea4b..000000000000
--- a/cmds/statsd/src/external/PullUidProvider.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullUidProvider : virtual public RefBase {
-public:
- virtual ~PullUidProvider() {}
-
- /**
- * @param atomId The atom for which to get the uids.
- */
- virtual vector<int32_t> getPullAtomUids(int32_t atomId) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
deleted file mode 100644
index 78e6f094db7e..000000000000
--- a/cmds/statsd/src/external/StatsCallbackPuller.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsCallbackPuller.h"
-#include "PullResultReceiver.h"
-#include "StatsPullerManager.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-
-#include <aidl/android/util/StatsEventParcel.h>
-
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsCallbackPuller::StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
- const int64_t coolDownNs, int64_t timeoutNs,
- const vector<int> additiveFields)
- : StatsPuller(tagId, coolDownNs, timeoutNs, additiveFields), mCallback(callback) {
- VLOG("StatsCallbackPuller created for tag %d", tagId);
-}
-
-bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
- VLOG("StatsCallbackPuller called for tag %d", mTagId);
- if(mCallback == nullptr) {
- ALOGW("No callback registered");
- return false;
- }
-
- // Shared variables needed in the result receiver.
- shared_ptr<mutex> cv_mutex = make_shared<mutex>();
- shared_ptr<condition_variable> cv = make_shared<condition_variable>();
- shared_ptr<bool> pullFinish = make_shared<bool>(false);
- shared_ptr<bool> pullSuccess = make_shared<bool>(false);
- shared_ptr<vector<shared_ptr<LogEvent>>> sharedData =
- make_shared<vector<shared_ptr<LogEvent>>>();
-
- shared_ptr<PullResultReceiver> resultReceiver = SharedRefBase::make<PullResultReceiver>(
- [cv_mutex, cv, pullFinish, pullSuccess, sharedData](
- int32_t atomTag, bool success, const vector<StatsEventParcel>& output) {
- // This is the result of the pull, executing in a statsd binder thread.
- // The pull could have taken a long time, and we should only modify
- // data (the output param) if the pointer is in scope and the pull did not time out.
- {
- lock_guard<mutex> lk(*cv_mutex);
- for (const StatsEventParcel& parcel: output) {
- shared_ptr<LogEvent> event = make_shared<LogEvent>(/*uid=*/-1, /*pid=*/-1);
- bool valid = event->parseBuffer((uint8_t*)parcel.buffer.data(),
- parcel.buffer.size());
- if (valid) {
- sharedData->push_back(event);
- } else {
- StatsdStats::getInstance().noteAtomError(event->GetTagId(),
- /*pull=*/true);
- }
- }
- *pullSuccess = success;
- *pullFinish = true;
- }
- cv->notify_one();
- });
-
- // Initiate the pull. This is a oneway call to a different process, except
- // in unit tests. In process calls are not oneway.
- Status status = mCallback->onPullAtom(mTagId, resultReceiver);
- if (!status.isOk()) {
- StatsdStats::getInstance().notePullBinderCallFailed(mTagId);
- return false;
- }
-
- {
- unique_lock<mutex> unique_lk(*cv_mutex);
- // Wait until the pull finishes, or until the pull timeout.
- cv->wait_for(unique_lk, chrono::nanoseconds(mPullTimeoutNs),
- [pullFinish] { return *pullFinish; });
- if (!*pullFinish) {
- // Note: The parent stats puller will also note that there was a timeout and that the
- // cache should be cleared. Once we migrate all pullers to this callback, we could
- // consolidate the logic.
- return true;
- } else {
- // Only copy the data if we did not timeout and the pull was successful.
- if (*pullSuccess) {
- *data = std::move(*sharedData);
- }
- VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
- return *pullSuccess;
- }
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
deleted file mode 100644
index e82e8bb532be..000000000000
--- a/cmds/statsd/src/external/StatsCallbackPuller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPullAtomCallback.h>
-#include "StatsPuller.h"
-
-using aidl::android::os::IPullAtomCallback;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCallbackPuller : public StatsPuller {
-public:
- explicit StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
- const int64_t coolDownNs, const int64_t timeoutNs,
- const std::vector<int> additiveFields);
-
-private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
- const shared_ptr<IPullAtomCallback> mCallback;
-
- FRIEND_TEST(StatsCallbackPullerTest, PullFail);
- FRIEND_TEST(StatsCallbackPullerTest, PullSuccess);
- FRIEND_TEST(StatsCallbackPullerTest, PullTimeout);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
deleted file mode 100644
index bb5d0a6bab58..000000000000
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsPuller.h"
-#include "StatsPullerManager.h"
-#include "guardrail/StatsdStats.h"
-#include "puller_util.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::lock_guard;
-
-sp<UidMap> StatsPuller::mUidMap = nullptr;
-void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
-
-StatsPuller::StatsPuller(const int tagId, const int64_t coolDownNs, const int64_t pullTimeoutNs,
- const std::vector<int> additiveFields)
- : mTagId(tagId),
- mPullTimeoutNs(pullTimeoutNs),
- mCoolDownNs(coolDownNs),
- mAdditiveFields(additiveFields),
- mLastPullTimeNs(0),
- mLastEventTimeNs(0) {
-}
-
-bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) {
- lock_guard<std::mutex> lock(mLock);
- const int64_t elapsedTimeNs = getElapsedRealtimeNs();
- const int64_t systemUptimeMillis = getSystemUptimeMillis();
- StatsdStats::getInstance().notePull(mTagId);
- const bool shouldUseCache =
- (mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs);
- if (shouldUseCache) {
- if (mHasGoodData) {
- (*data) = mCachedData;
- StatsdStats::getInstance().notePullFromCache(mTagId);
-
- }
- return mHasGoodData;
- }
- if (mLastPullTimeNs > 0) {
- StatsdStats::getInstance().updateMinPullIntervalSec(
- mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC);
- }
- mCachedData.clear();
- mLastPullTimeNs = elapsedTimeNs;
- mLastEventTimeNs = eventTimeNs;
- mHasGoodData = PullInternal(&mCachedData);
- if (!mHasGoodData) {
- return mHasGoodData;
- }
- const int64_t pullElapsedDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
- const int64_t pullSystemUptimeDurationMillis = getSystemUptimeMillis() - systemUptimeMillis;
- StatsdStats::getInstance().notePullTime(mTagId, pullElapsedDurationNs);
- const bool pullTimeOut = pullElapsedDurationNs > mPullTimeoutNs;
- if (pullTimeOut) {
- // Something went wrong. Discard the data.
- mCachedData.clear();
- mHasGoodData = false;
- StatsdStats::getInstance().notePullTimeout(
- mTagId, pullSystemUptimeDurationMillis, NanoToMillis(pullElapsedDurationNs));
- ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
- (long long)pullElapsedDurationNs);
- return mHasGoodData;
- }
-
- if (mCachedData.size() > 0) {
- mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId, mAdditiveFields);
- }
-
- if (mCachedData.empty()) {
- VLOG("Data pulled is empty");
- StatsdStats::getInstance().noteEmptyData(mTagId);
- }
-
- (*data) = mCachedData;
- return mHasGoodData;
-}
-
-int StatsPuller::ForceClearCache() {
- return clearCache();
-}
-
-int StatsPuller::clearCache() {
- lock_guard<std::mutex> lock(mLock);
- return clearCacheLocked();
-}
-
-int StatsPuller::clearCacheLocked() {
- int ret = mCachedData.size();
- mCachedData.clear();
- mLastPullTimeNs = 0;
- mLastEventTimeNs = 0;
- return ret;
-}
-
-int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
- if (timestampNs - mLastPullTimeNs > mCoolDownNs) {
- return clearCache();
- } else {
- return 0;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
deleted file mode 100644
index 470d15e6fbd1..000000000000
--- a/cmds/statsd/src/external/StatsPuller.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-#include <mutex>
-#include <vector>
-#include "packages/UidMap.h"
-
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "puller_util.h"
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsPuller : public virtual RefBase {
-public:
- explicit StatsPuller(const int tagId,
- const int64_t coolDownNs = NS_PER_SEC,
- const int64_t pullTimeoutNs = StatsdStats::kPullMaxDelayNs,
- const std::vector<int> additiveFields = std::vector<int>());
-
- virtual ~StatsPuller() {}
-
- // Pulls the most recent data.
- // The data may be served from cache if consecutive pulls come within
- // predefined cooldown time.
- // Returns true if the pull was successful.
- // Returns false when
- // 1) the pull fails
- // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
- // If a metric wants to make any change to the data, like timestamps, it
- // should make a copy as this data may be shared with multiple metrics.
- bool Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data);
-
- // Clear cache immediately
- int ForceClearCache();
-
- // Clear cache if elapsed time is more than cooldown time
- int ClearCacheIfNecessary(int64_t timestampNs);
-
- static void SetUidMap(const sp<UidMap>& uidMap);
-
- virtual void SetStatsCompanionService(
- shared_ptr<IStatsCompanionService> statsCompanionService) {};
-
-protected:
- const int mTagId;
-
- // Max time allowed to pull this atom.
- // We cannot reliably kill a pull thread. So we don't terminate the puller.
- // The data is discarded if the pull takes longer than this and mHasGoodData
- // marked as false.
- const int64_t mPullTimeoutNs = StatsdStats::kPullMaxDelayNs;
-
-private:
- mutable std::mutex mLock;
-
- // Real puller impl.
- virtual bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) = 0;
-
- bool mHasGoodData = false;
-
- // Minimum time before this puller does actual pull again.
- // Pullers can cause significant impact to system health and battery.
- // So that we don't pull too frequently.
- // If a pull request comes before cooldown, a cached version from previous pull
- // will be returned.
- const int64_t mCoolDownNs = 1 * NS_PER_SEC;
-
- // The field numbers of the fields that need to be summed when merging
- // isolated uid with host uid.
- const std::vector<int> mAdditiveFields;
-
- int64_t mLastPullTimeNs;
-
- // All pulls happen due to an event (app upgrade, bucket boundary, condition change, etc).
- // If multiple pulls need to be done at the same event time, we will always use the cache after
- // the first pull.
- int64_t mLastEventTimeNs;
-
- // Cache of data from last pull. If next request comes before cool down finishes,
- // cached data will be returned.
- // Cached data is cleared when
- // 1) A pull fails
- // 2) A new pull request comes after cooldown time.
- // 3) clearCache is called.
- std::vector<std::shared_ptr<LogEvent>> mCachedData;
-
- int clearCache();
-
- int clearCacheLocked();
-
- static sp<UidMap> mUidMap;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
deleted file mode 100644
index 8334b6b4db90..000000000000
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include "StatsPullerManager.h"
-
-#include <cutils/log.h>
-#include <math.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <iostream>
-
-#include "../StatsService.h"
-#include "../logd/LogEvent.h"
-#include "../stats_log_util.h"
-#include "../statscompanion_util.h"
-#include "StatsCallbackPuller.h"
-#include "TrainInfoPuller.h"
-#include "statslog_statsd.h"
-
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Stores the puller as a wp to avoid holding a reference in case it is unregistered and
-// pullAtomCallbackDied is never called.
-struct PullAtomCallbackDeathCookie {
- PullAtomCallbackDeathCookie(const wp<StatsPullerManager>& pullerManager,
- const PullerKey& pullerKey, const wp<StatsPuller>& puller) :
- mPullerManager(pullerManager), mPullerKey(pullerKey), mPuller(puller) {
- }
-
- wp<StatsPullerManager> mPullerManager;
- PullerKey mPullerKey;
- wp<StatsPuller> mPuller;
-};
-
-void StatsPullerManager::pullAtomCallbackDied(void* cookie) {
- PullAtomCallbackDeathCookie* cookie_ = static_cast<PullAtomCallbackDeathCookie*>(cookie);
- sp<StatsPullerManager> thiz = cookie_->mPullerManager.promote();
- if (!thiz) {
- return;
- }
-
- const PullerKey& pullerKey = cookie_->mPullerKey;
- wp<StatsPuller> puller = cookie_->mPuller;
-
- // Erase the mapping from the puller key to the puller if the mapping still exists.
- // Note that we are removing the StatsPuller object, which internally holds the binder
- // IPullAtomCallback. However, each new registration creates a new StatsPuller, so this works.
- lock_guard<mutex> lock(thiz->mLock);
- const auto& it = thiz->kAllPullAtomInfo.find(pullerKey);
- if (it != thiz->kAllPullAtomInfo.end() && puller != nullptr && puller == it->second) {
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(pullerKey.atomTag,
- /*registered=*/false);
- thiz->kAllPullAtomInfo.erase(pullerKey);
- }
- // The death recipient corresponding to this specific IPullAtomCallback can never
- // be triggered again, so free up resources.
- delete cookie_;
-}
-
-// Values smaller than this may require to update the alarm.
-const int64_t NO_ALARM_UPDATE = INT64_MAX;
-
-StatsPullerManager::StatsPullerManager()
- : kAllPullAtomInfo({
- // TrainInfo.
- {{.atomTag = util::TRAIN_INFO, .uid = AID_STATSD}, new TrainInfoPuller()},
- }),
- mNextPullTimeNs(NO_ALARM_UPDATE),
- mPullAtomCallbackDeathRecipient(AIBinder_DeathRecipient_new(pullAtomCallbackDied)) {
-}
-
-bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<shared_ptr<LogEvent>>* data) {
- std::lock_guard<std::mutex> _l(mLock);
- return PullLocked(tagId, configKey, eventTimeNs, data);
-}
-
-bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- std::lock_guard<std::mutex> _l(mLock);
- return PullLocked(tagId, uids, eventTimeNs, data);
-}
-
-bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
- const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data) {
- vector<int32_t> uids;
- const auto& uidProviderIt = mPullUidProviders.find(configKey);
- if (uidProviderIt == mPullUidProviders.end()) {
- ALOGE("Error pulling tag %d. No pull uid provider for config key %s", tagId,
- configKey.ToString().c_str());
- StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
- return false;
- }
- sp<PullUidProvider> pullUidProvider = uidProviderIt->second.promote();
- if (pullUidProvider == nullptr) {
- ALOGE("Error pulling tag %d, pull uid provider for config %s is gone.", tagId,
- configKey.ToString().c_str());
- StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
- return false;
- }
- uids = pullUidProvider->getPullAtomUids(tagId);
- return PullLocked(tagId, uids, eventTimeNs, data);
-}
-
-bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
- const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data) {
- VLOG("Initiating pulling %d", tagId);
- for (int32_t uid : uids) {
- PullerKey key = {.atomTag = tagId, .uid = uid};
- auto pullerIt = kAllPullAtomInfo.find(key);
- if (pullerIt != kAllPullAtomInfo.end()) {
- bool ret = pullerIt->second->Pull(eventTimeNs, data);
- VLOG("pulled %zu items", data->size());
- if (!ret) {
- StatsdStats::getInstance().notePullFailed(tagId);
- }
- return ret;
- }
- }
- StatsdStats::getInstance().notePullerNotFound(tagId);
- ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
- return false; // Return early since we don't know what to pull.
-}
-
-bool StatsPullerManager::PullerForMatcherExists(int tagId) const {
- // Pulled atoms might be registered after we parse the config, so just make sure the id is in
- // an appropriate range.
- return isVendorPulledAtom(tagId) || isPulledAtom(tagId);
-}
-
-void StatsPullerManager::updateAlarmLocked() {
- if (mNextPullTimeNs == NO_ALARM_UPDATE) {
- VLOG("No need to set alarms. Skipping");
- return;
- }
-
- // TODO(b/151045771): do not hold a lock while making a binder call
- if (mStatsCompanionService != nullptr) {
- mStatsCompanionService->setPullingAlarm(mNextPullTimeNs / 1000000);
- } else {
- VLOG("StatsCompanionService not available. Alarm not set.");
- }
- return;
-}
-
-void StatsPullerManager::SetStatsCompanionService(
- shared_ptr<IStatsCompanionService> statsCompanionService) {
- std::lock_guard<std::mutex> _l(mLock);
- shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
- mStatsCompanionService = statsCompanionService;
- for (const auto& pulledAtom : kAllPullAtomInfo) {
- pulledAtom.second->SetStatsCompanionService(statsCompanionService);
- }
- if (mStatsCompanionService != nullptr) {
- updateAlarmLocked();
- }
-}
-
-void StatsPullerManager::RegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
- int64_t intervalNs) {
- std::lock_guard<std::mutex> _l(mLock);
- auto& receivers = mReceivers[{.atomTag = tagId, .configKey = configKey}];
- for (auto it = receivers.begin(); it != receivers.end(); it++) {
- if (it->receiver == receiver) {
- VLOG("Receiver already registered of %d", (int)receivers.size());
- return;
- }
- }
- ReceiverInfo receiverInfo;
- receiverInfo.receiver = receiver;
-
- // Round it to the nearest minutes. This is the limit of alarm manager.
- // In practice, we should always have larger buckets.
- int64_t roundedIntervalNs = intervalNs / NS_PER_SEC / 60 * NS_PER_SEC * 60;
- // Scheduled pulling should be at least 1 min apart.
- // This can be lower in cts tests, in which case we round it to 1 min.
- if (roundedIntervalNs < 60 * (int64_t)NS_PER_SEC) {
- roundedIntervalNs = 60 * (int64_t)NS_PER_SEC;
- }
-
- receiverInfo.intervalNs = roundedIntervalNs;
- receiverInfo.nextPullTimeNs = nextPullTimeNs;
- receivers.push_back(receiverInfo);
-
- // There is only one alarm for all pulled events. So only set it to the smallest denom.
- if (nextPullTimeNs < mNextPullTimeNs) {
- VLOG("Updating next pull time %lld", (long long)mNextPullTimeNs);
- mNextPullTimeNs = nextPullTimeNs;
- updateAlarmLocked();
- }
- VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
-}
-
-void StatsPullerManager::UnRegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver) {
- std::lock_guard<std::mutex> _l(mLock);
- auto receiversIt = mReceivers.find({.atomTag = tagId, .configKey = configKey});
- if (receiversIt == mReceivers.end()) {
- VLOG("Unknown pull code or no receivers: %d", tagId);
- return;
- }
- std::list<ReceiverInfo>& receivers = receiversIt->second;
- for (auto it = receivers.begin(); it != receivers.end(); it++) {
- if (receiver == it->receiver) {
- receivers.erase(it);
- VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size());
- return;
- }
- }
-}
-
-void StatsPullerManager::RegisterPullUidProvider(const ConfigKey& configKey,
- wp<PullUidProvider> provider) {
- std::lock_guard<std::mutex> _l(mLock);
- mPullUidProviders[configKey] = provider;
-}
-
-void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey,
- wp<PullUidProvider> provider) {
- std::lock_guard<std::mutex> _l(mLock);
- const auto& it = mPullUidProviders.find(configKey);
- if (it != mPullUidProviders.end() && it->second == provider) {
- mPullUidProviders.erase(it);
- }
-}
-
-void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) {
- std::lock_guard<std::mutex> _l(mLock);
- int64_t wallClockNs = getWallClockNs();
-
- int64_t minNextPullTimeNs = NO_ALARM_UPDATE;
-
- vector<pair<const ReceiverKey*, vector<ReceiverInfo*>>> needToPull;
- for (auto& pair : mReceivers) {
- vector<ReceiverInfo*> receivers;
- if (pair.second.size() != 0) {
- for (ReceiverInfo& receiverInfo : pair.second) {
- if (receiverInfo.nextPullTimeNs <= elapsedTimeNs) {
- receivers.push_back(&receiverInfo);
- } else {
- if (receiverInfo.nextPullTimeNs < minNextPullTimeNs) {
- minNextPullTimeNs = receiverInfo.nextPullTimeNs;
- }
- }
- }
- if (receivers.size() > 0) {
- needToPull.push_back(make_pair(&pair.first, receivers));
- }
- }
- }
- for (const auto& pullInfo : needToPull) {
- vector<shared_ptr<LogEvent>> data;
- bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey,
- elapsedTimeNs, &data);
- if (!pullSuccess) {
- VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs);
- }
-
- // Convention is to mark pull atom timestamp at request time.
- // If we pull at t0, puller starts at t1, finishes at t2, and send back
- // at t3, we mark t0 as its timestamp, which should correspond to its
- // triggering event, such as condition change at t0.
- // Here the triggering event is alarm fired from AlarmManager.
- // In ValueMetricProducer and GaugeMetricProducer we do same thing
- // when pull on condition change, etc.
- for (auto& event : data) {
- event->setElapsedTimestampNs(elapsedTimeNs);
- event->setLogdWallClockTimestampNs(wallClockNs);
- }
-
- for (const auto& receiverInfo : pullInfo.second) {
- sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
- if (receiverPtr != nullptr) {
- receiverPtr->onDataPulled(data, pullSuccess, elapsedTimeNs);
- // We may have just come out of a coma, compute next pull time.
- int numBucketsAhead =
- (elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs;
- receiverInfo->nextPullTimeNs += (numBucketsAhead + 1) * receiverInfo->intervalNs;
- if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) {
- minNextPullTimeNs = receiverInfo->nextPullTimeNs;
- }
- } else {
- VLOG("receiver already gone.");
- }
- }
- }
-
- VLOG("mNextPullTimeNs: %lld updated to %lld", (long long)mNextPullTimeNs,
- (long long)minNextPullTimeNs);
- mNextPullTimeNs = minNextPullTimeNs;
- updateAlarmLocked();
-}
-
-int StatsPullerManager::ForceClearPullerCache() {
- std::lock_guard<std::mutex> _l(mLock);
- int totalCleared = 0;
- for (const auto& pulledAtom : kAllPullAtomInfo) {
- totalCleared += pulledAtom.second->ForceClearCache();
- }
- return totalCleared;
-}
-
-int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) {
- std::lock_guard<std::mutex> _l(mLock);
- int totalCleared = 0;
- for (const auto& pulledAtom : kAllPullAtomInfo) {
- totalCleared += pulledAtom.second->ClearCacheIfNecessary(timestampNs);
- }
- return totalCleared;
-}
-
-void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
- const int64_t coolDownNs, const int64_t timeoutNs,
- const vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& callback) {
- std::lock_guard<std::mutex> _l(mLock);
- VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
-
- if (callback == nullptr) {
- ALOGW("SetPullAtomCallback called with null callback for atom %d.", atomTag);
- return;
- }
-
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
- int64_t actualCoolDownNs = coolDownNs < kMinCoolDownNs ? kMinCoolDownNs : coolDownNs;
- int64_t actualTimeoutNs = timeoutNs > kMaxTimeoutNs ? kMaxTimeoutNs : timeoutNs;
-
- sp<StatsCallbackPuller> puller = new StatsCallbackPuller(atomTag, callback, actualCoolDownNs,
- actualTimeoutNs, additiveFields);
- PullerKey key = {.atomTag = atomTag, .uid = uid};
- AIBinder_linkToDeath(callback->asBinder().get(), mPullAtomCallbackDeathRecipient.get(),
- new PullAtomCallbackDeathCookie(this, key, puller));
- kAllPullAtomInfo[key] = puller;
-}
-
-void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag) {
- std::lock_guard<std::mutex> _l(mLock);
- PullerKey key = {.atomTag = atomTag, .uid = uid};
- if (kAllPullAtomInfo.find(key) != kAllPullAtomInfo.end()) {
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag,
- /*registered=*/false);
- kAllPullAtomInfo.erase(key);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
deleted file mode 100644
index 489cbdbe5400..000000000000
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-
-#include <list>
-#include <vector>
-
-#include "PullDataReceiver.h"
-#include "PullUidProvider.h"
-#include "StatsPuller.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-using aidl::android::os::IPullAtomCallback;
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-typedef struct PullerKey {
- // The uid of the process that registers this puller.
- const int uid = -1;
- // The atom that this puller is for.
- const int atomTag;
-
- bool operator<(const PullerKey& that) const {
- if (uid < that.uid) {
- return true;
- }
- if (uid > that.uid) {
- return false;
- }
- return atomTag < that.atomTag;
- };
-
- bool operator==(const PullerKey& that) const {
- return uid == that.uid && atomTag == that.atomTag;
- };
-} PullerKey;
-
-class StatsPullerManager : public virtual RefBase {
-public:
- StatsPullerManager();
-
- virtual ~StatsPullerManager() {
- }
-
-
- // Registers a receiver for tagId. It will be pulled on the nextPullTimeNs
- // and then every intervalNs thereafter.
- virtual void RegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
- int64_t intervalNs);
-
- // Stop listening on a tagId.
- virtual void UnRegisterReceiver(int tagId, const ConfigKey& configKey,
- wp<PullDataReceiver> receiver);
-
- // Registers a pull uid provider for the config key. When pulling atoms, it will be used to
- // determine which uids to pull from.
- virtual void RegisterPullUidProvider(const ConfigKey& configKey, wp<PullUidProvider> provider);
-
- // Unregister a pull uid provider.
- virtual void UnregisterPullUidProvider(const ConfigKey& configKey,
- wp<PullUidProvider> provider);
-
- // Verify if we know how to pull for this matcher
- bool PullerForMatcherExists(int tagId) const;
-
- void OnAlarmFired(int64_t elapsedTimeNs);
-
- // Pulls the most recent data.
- // The data may be served from cache if consecutive pulls come within
- // mCoolDownNs.
- // Returns true if the pull was successful.
- // Returns false when
- // 1) the pull fails
- // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
- // 3) Either a PullUidProvider was not registered for the config, or the there was no puller
- // registered for any of the uids for this atom.
- // If the metric wants to make any change to the data, like timestamps, they
- // should make a copy as this data may be shared with multiple metrics.
- virtual bool Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data);
-
- // Same as above, but directly specify the allowed uids to pull from.
- virtual bool Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data);
-
- // Clear pull data cache immediately.
- int ForceClearPullerCache();
-
- // Clear pull data cache if it is beyond respective cool down time.
- int ClearPullerCacheIfNecessary(int64_t timestampNs);
-
- void SetStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
-
- void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
- const int64_t timeoutNs, const vector<int32_t>& additiveFields,
- const shared_ptr<IPullAtomCallback>& callback);
-
- void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
-
- std::map<const PullerKey, sp<StatsPuller>> kAllPullAtomInfo;
-
-private:
- const static int64_t kMinCoolDownNs = NS_PER_SEC;
- const static int64_t kMaxTimeoutNs = 10 * NS_PER_SEC;
- shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
-
- // A struct containing an atom id and a Config Key
- typedef struct ReceiverKey {
- const int atomTag;
- const ConfigKey configKey;
-
- inline bool operator<(const ReceiverKey& that) const {
- return atomTag == that.atomTag ? configKey < that.configKey : atomTag < that.atomTag;
- }
- } ReceiverKey;
-
- typedef struct {
- int64_t nextPullTimeNs;
- int64_t intervalNs;
- wp<PullDataReceiver> receiver;
- } ReceiverInfo;
-
- // mapping from Receiver Key to receivers
- std::map<ReceiverKey, std::list<ReceiverInfo>> mReceivers;
-
- // mapping from Config Key to the PullUidProvider for that config
- std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders;
-
- bool PullLocked(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data);
-
- bool PullLocked(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data);
-
- // locks for data receiver and StatsCompanionService changes
- std::mutex mLock;
-
- void updateAlarmLocked();
-
- int64_t mNextPullTimeNs;
-
- // Death recipient that is triggered when the process holding the IPullAtomCallback has died.
- ::ndk::ScopedAIBinder_DeathRecipient mPullAtomCallbackDeathRecipient;
-
- /**
- * Death recipient callback that is called when a pull atom callback dies.
- * The cookie is a pointer to a PullAtomCallbackDeathCookie.
- */
- static void pullAtomCallbackDied(void* cookie);
-
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
-
- FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/TrainInfoPuller.cpp b/cmds/statsd/src/external/TrainInfoPuller.cpp
deleted file mode 100644
index 3837f4a1a517..000000000000
--- a/cmds/statsd/src/external/TrainInfoPuller.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "external/StatsPuller.h"
-
-#include "TrainInfoPuller.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-using std::make_shared;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TrainInfoPuller::TrainInfoPuller() :
- StatsPuller(util::TRAIN_INFO) {
-}
-
-bool TrainInfoPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
- vector<InstallTrainInfo> trainInfoList =
- StorageManager::readAllTrainInfo();
- if (trainInfoList.empty()) {
- ALOGW("Train info was empty.");
- return true;
- }
- for (InstallTrainInfo& trainInfo : trainInfoList) {
- auto event = make_shared<LogEvent>(getWallClockNs(), getElapsedRealtimeNs(), trainInfo);
- data->push_back(event);
- }
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/TrainInfoPuller.h b/cmds/statsd/src/external/TrainInfoPuller.h
deleted file mode 100644
index 615d02351fd3..000000000000
--- a/cmds/statsd/src/external/TrainInfoPuller.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Reads train info from disk.
- */
-class TrainInfoPuller : public StatsPuller {
- public:
- TrainInfoPuller();
-
- private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
deleted file mode 100644
index aa99d0082bdd..000000000000
--- a/cmds/statsd/src/external/puller_util.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "puller_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace std;
-
-/**
- * Process all data and merge isolated with host if necessary.
- * For example:
- * NetworkBytesAtom {
- * int uid = 1;
- * State process_state = 2;
- * int byte_send = 3;
- * int byte_recv = 4;
- * }
- * additive fields are {3, 4}
- * If we pulled the following events (uid1_child is an isolated uid which maps to uid1):
- * [uid1, fg, 100, 200]
- * [uid1_child, fg, 100, 200]
- * [uid1, bg, 100, 200]
- *
- * We want to merge them and results should be:
- * [uid1, fg, 200, 400]
- * [uid1, bg, 100, 200]
- *
- * All atoms should be of the same tagId. All fields should be present.
- */
-void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap,
- int tagId, const vector<int>& additiveFieldsVec) {
- // Check the first LogEvent for attribution chain or a uid field as either all atoms with this
- // tagId have them or none of them do.
- std::pair<int, int> attrIndexRange;
- const bool hasAttributionChain = data[0]->hasAttributionChain(&attrIndexRange);
- bool hasUidField = (data[0]->getUidFieldIndex() != -1);
-
- if (!hasAttributionChain && !hasUidField) {
- VLOG("No uid or attribution chain to merge, atom %d", tagId);
- return;
- }
-
- // 1. Map all isolated uid in-place to host uid
- for (shared_ptr<LogEvent>& event : data) {
- if (event->GetTagId() != tagId) {
- ALOGE("Wrong atom. Expecting %d, got %d", tagId, event->GetTagId());
- return;
- }
- if (hasAttributionChain) {
- vector<FieldValue>* const fieldValues = event->getMutableValues();
- for (int i = attrIndexRange.first; i <= attrIndexRange.second; i++) {
- FieldValue& fieldValue = fieldValues->at(i);
- if (isAttributionUidField(fieldValue)) {
- const int hostUid = uidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
- fieldValue.mValue.setInt(hostUid);
- }
- }
- } else {
- int uidFieldIndex = event->getUidFieldIndex();
- if (uidFieldIndex != -1) {
- Value& value = (*event->getMutableValues())[uidFieldIndex].mValue;
- const int hostUid = uidMap->getHostUidOrSelf(value.int_value);
- value.setInt(hostUid);
- } else {
- ALOGE("Malformed log, uid not found. %s", event->ToString().c_str());
- }
- }
- }
-
- // 2. sort the data, bit-wise
- sort(data.begin(), data.end(),
- [](const shared_ptr<LogEvent>& lhs, const shared_ptr<LogEvent>& rhs) {
- if (lhs->size() != rhs->size()) {
- return lhs->size() < rhs->size();
- }
- const std::vector<FieldValue>& lhsValues = lhs->getValues();
- const std::vector<FieldValue>& rhsValues = rhs->getValues();
- for (int i = 0; i < (int)lhs->size(); i++) {
- if (lhsValues[i] != rhsValues[i]) {
- return lhsValues[i] < rhsValues[i];
- }
- }
- return false;
- });
-
- vector<shared_ptr<LogEvent>> mergedData;
- const set<int> additiveFields(additiveFieldsVec.begin(), additiveFieldsVec.end());
- bool needMerge = true;
-
- // 3. do the merge.
- // The loop invariant is this: for every event, check if it differs on
- // non-additive fields, or have different attribution chain length.
- // If so, no need to merge, add itself to the result.
- // Otherwise, merge the value onto the one immediately next to it.
- for (int i = 0; i < (int)data.size() - 1; i++) {
- // Size different, must be different chains.
- if (data[i]->size() != data[i + 1]->size()) {
- mergedData.push_back(data[i]);
- continue;
- }
- vector<FieldValue>* lhsValues = data[i]->getMutableValues();
- vector<FieldValue>* rhsValues = data[i + 1]->getMutableValues();
- needMerge = true;
- for (int p = 0; p < (int)lhsValues->size(); p++) {
- if ((*lhsValues)[p] != (*rhsValues)[p]) {
- int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
- // Differ on non-additive field, abort.
- if (additiveFields.find(pos) == additiveFields.end()) {
- needMerge = false;
- break;
- }
- }
- }
- if (!needMerge) {
- mergedData.push_back(data[i]);
- continue;
- }
- // This should be infrequent operation.
- for (int p = 0; p < (int)lhsValues->size(); p++) {
- int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
- if (additiveFields.find(pos) != additiveFields.end()) {
- (*rhsValues)[p].mValue += (*lhsValues)[p].mValue;
- }
- }
- }
- mergedData.push_back(data.back());
-
- data.clear();
- data = mergedData;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/puller_util.h b/cmds/statsd/src/external/puller_util.h
deleted file mode 100644
index afcf68ca10ad..000000000000
--- a/cmds/statsd/src/external/puller_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <vector>
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void mapAndMergeIsolatedUidsToHostUid(std::vector<std::shared_ptr<LogEvent>>& data,
- const sp<UidMap>& uidMap, int tagId,
- const vector<int>& additiveFieldsVec);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
deleted file mode 100644
index 6e89038f4152..000000000000
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ /dev/null
@@ -1,1101 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsdStats.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include "../stats_log_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::lock_guard;
-using std::shared_ptr;
-using std::string;
-using std::to_string;
-using std::vector;
-
-const int FIELD_ID_BEGIN_TIME = 1;
-const int FIELD_ID_END_TIME = 2;
-const int FIELD_ID_CONFIG_STATS = 3;
-const int FIELD_ID_ATOM_STATS = 7;
-const int FIELD_ID_UIDMAP_STATS = 8;
-const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
-const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
-const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
-const int FIELD_ID_LOGGER_ERROR_STATS = 16;
-const int FIELD_ID_OVERFLOW = 18;
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL = 19;
-
-const int FIELD_ID_ATOM_STATS_TAG = 1;
-const int FIELD_ID_ATOM_STATS_COUNT = 2;
-const int FIELD_ID_ATOM_STATS_ERROR_COUNT = 3;
-
-const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
-const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1;
-
-const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
-const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
-const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
-const int FIELD_ID_LOG_LOSS_STATS_TAG = 4;
-const int FIELD_ID_LOG_LOSS_STATS_UID = 5;
-const int FIELD_ID_LOG_LOSS_STATS_PID = 6;
-
-const int FIELD_ID_OVERFLOW_COUNT = 1;
-const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2;
-const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3;
-
-const int FIELD_ID_CONFIG_STATS_UID = 1;
-const int FIELD_ID_CONFIG_STATS_ID = 2;
-const int FIELD_ID_CONFIG_STATS_CREATION = 3;
-const int FIELD_ID_CONFIG_STATS_RESET = 19;
-const int FIELD_ID_CONFIG_STATS_DELETION = 4;
-const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5;
-const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6;
-const int FIELD_ID_CONFIG_STATS_MATCHER_COUNT = 7;
-const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8;
-const int FIELD_ID_CONFIG_STATS_VALID = 9;
-const int FIELD_ID_CONFIG_STATS_BROADCAST = 10;
-const int FIELD_ID_CONFIG_STATS_DATA_DROP_TIME = 11;
-const int FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES = 21;
-const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME = 12;
-const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES = 20;
-const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13;
-const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
-const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
-const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
-const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18;
-const int FIELD_ID_CONFIG_STATS_ACTIVATION = 22;
-const int FIELD_ID_CONFIG_STATS_DEACTIVATION = 23;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2;
-
-const int FIELD_ID_MATCHER_STATS_ID = 1;
-const int FIELD_ID_MATCHER_STATS_COUNT = 2;
-const int FIELD_ID_CONDITION_STATS_ID = 1;
-const int FIELD_ID_CONDITION_STATS_COUNT = 2;
-const int FIELD_ID_METRIC_STATS_ID = 1;
-const int FIELD_ID_METRIC_STATS_COUNT = 2;
-const int FIELD_ID_ALERT_STATS_ID = 1;
-const int FIELD_ID_ALERT_STATS_COUNT = 2;
-
-const int FIELD_ID_UID_MAP_CHANGES = 1;
-const int FIELD_ID_UID_MAP_BYTES_USED = 2;
-const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3;
-const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
-
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
-
-const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = {
- {util::BINDER_CALLS, {6000, 10000}},
- {util::LOOPER_STATS, {1500, 2500}},
- {util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
-};
-
-StatsdStats::StatsdStats() {
- mPushedAtomStats.resize(kMaxPushedAtomId + 1);
- mStartTimeSec = getWallClockSec();
-}
-
-StatsdStats& StatsdStats::getInstance() {
- static StatsdStats statsInstance;
- return statsInstance;
-}
-
-void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) {
- // The size of mIceBox grows strictly by one at a time. It won't be > kMaxIceBoxSize.
- if (mIceBox.size() == kMaxIceBoxSize) {
- mIceBox.pop_front();
- }
- mIceBox.push_back(stats);
-}
-
-void StatsdStats::noteConfigReceived(
- const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount,
- int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations,
- bool isValid) {
- lock_guard<std::mutex> lock(mLock);
- int32_t nowTimeSec = getWallClockSec();
-
- // If there is an existing config for the same key, icebox the old config.
- noteConfigRemovedInternalLocked(key);
-
- shared_ptr<ConfigStats> configStats = std::make_shared<ConfigStats>();
- configStats->uid = key.GetUid();
- configStats->id = key.GetId();
- configStats->creation_time_sec = nowTimeSec;
- configStats->metric_count = metricsCount;
- configStats->condition_count = conditionsCount;
- configStats->matcher_count = matchersCount;
- configStats->alert_count = alertsCount;
- configStats->is_valid = isValid;
- for (auto& v : annotations) {
- configStats->annotations.emplace_back(v);
- }
-
- if (isValid) {
- mConfigStats[key] = configStats;
- } else {
- configStats->deletion_time_sec = nowTimeSec;
- addToIceBoxLocked(configStats);
- }
-}
-
-void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) {
- auto it = mConfigStats.find(key);
- if (it != mConfigStats.end()) {
- int32_t nowTimeSec = getWallClockSec();
- it->second->deletion_time_sec = nowTimeSec;
- addToIceBoxLocked(it->second);
- mConfigStats.erase(it);
- }
-}
-
-void StatsdStats::noteConfigRemoved(const ConfigKey& key) {
- lock_guard<std::mutex> lock(mLock);
- noteConfigRemovedInternalLocked(key);
-}
-
-void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) {
- auto it = mConfigStats.find(key);
- if (it != mConfigStats.end()) {
- it->second->reset_time_sec = getWallClockSec();
- }
-}
-
-void StatsdStats::noteConfigReset(const ConfigKey& key) {
- lock_guard<std::mutex> lock(mLock);
- noteConfigResetInternalLocked(key);
-}
-
-void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
- int32_t lastTag, int32_t uid, int32_t pid) {
- lock_guard<std::mutex> lock(mLock);
- if (mLogLossStats.size() == kMaxLoggerErrors) {
- mLogLossStats.pop_front();
- }
- mLogLossStats.emplace_back(wallClockTimeSec, count, lastError, lastTag, uid, pid);
-}
-
-void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
- noteBroadcastSent(key, getWallClockSec());
-}
-
-void StatsdStats::noteBroadcastSent(const ConfigKey& key, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- if (it->second->broadcast_sent_time_sec.size() == kMaxTimestampCount) {
- it->second->broadcast_sent_time_sec.pop_front();
- }
- it->second->broadcast_sent_time_sec.push_back(timeSec);
-}
-
-void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated) {
- noteActiveStatusChanged(key, activated, getWallClockSec());
-}
-
-void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- auto& vec = activated ? it->second->activation_time_sec
- : it->second->deactivation_time_sec;
- if (vec.size() == kMaxTimestampCount) {
- vec.pop_front();
- }
- vec.push_back(timeSec);
-}
-
-void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid) {
- noteActivationBroadcastGuardrailHit(uid, getWallClockSec());
-}
-
-void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid, const int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto& guardrailTimes = mActivationBroadcastGuardrailStats[uid];
- if (guardrailTimes.size() == kMaxTimestampCount) {
- guardrailTimes.pop_front();
- }
- guardrailTimes.push_back(timeSec);
-}
-
-void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) {
- noteDataDropped(key, totalBytes, getWallClockSec());
-}
-
-void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs) {
- lock_guard<std::mutex> lock(mLock);
-
- mOverflowCount++;
-
- int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs;
-
- if (history > mMaxQueueHistoryNs) {
- mMaxQueueHistoryNs = history;
- }
-
- if (history < mMinQueueHistoryNs) {
- mMinQueueHistoryNs = history;
- }
-}
-
-void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- if (it->second->data_drop_time_sec.size() == kMaxTimestampCount) {
- it->second->data_drop_time_sec.pop_front();
- it->second->data_drop_bytes.pop_front();
- }
- it->second->data_drop_time_sec.push_back(timeSec);
- it->second->data_drop_bytes.push_back(totalBytes);
-}
-
-void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes) {
- noteMetricsReportSent(key, num_bytes, getWallClockSec());
-}
-
-void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes,
- int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
- auto it = mConfigStats.find(key);
- if (it == mConfigStats.end()) {
- ALOGE("Config key %s not found!", key.ToString().c_str());
- return;
- }
- if (it->second->dump_report_stats.size() == kMaxTimestampCount) {
- it->second->dump_report_stats.pop_front();
- }
- it->second->dump_report_stats.push_back(std::make_pair(timeSec, num_bytes));
-}
-
-void StatsdStats::noteUidMapDropped(int deltas) {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.dropped_changes += mUidMapStats.dropped_changes + deltas;
-}
-
-void StatsdStats::noteUidMapAppDeletionDropped() {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.deleted_apps++;
-}
-
-void StatsdStats::setUidMapChanges(int changes) {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.changes = changes;
-}
-
-void StatsdStats::setCurrentUidMapMemory(int bytes) {
- lock_guard<std::mutex> lock(mLock);
- mUidMapStats.bytes_used = bytes;
-}
-
-void StatsdStats::noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
- lock_guard<std::mutex> lock(mLock);
- // if name doesn't exist before, it will create the key with count 0.
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
-
- auto& conditionSizeMap = statsIt->second->condition_stats;
- if (size > conditionSizeMap[id]) {
- conditionSizeMap[id] = size;
- }
-}
-
-void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
- lock_guard<std::mutex> lock(mLock);
- // if name doesn't exist before, it will create the key with count 0.
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- auto& metricsDimensionMap = statsIt->second->metric_stats;
- if (size > metricsDimensionMap[id]) {
- metricsDimensionMap[id] = size;
- }
-}
-
-void StatsdStats::noteMetricDimensionInConditionSize(
- const ConfigKey& key, const int64_t& id, int size) {
- lock_guard<std::mutex> lock(mLock);
- // if name doesn't exist before, it will create the key with count 0.
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats;
- if (size > metricsDimensionMap[id]) {
- metricsDimensionMap[id] = size;
- }
-}
-
-void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t& id) {
- lock_guard<std::mutex> lock(mLock);
-
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- statsIt->second->matcher_stats[id]++;
-}
-
-void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const int64_t& id) {
- lock_guard<std::mutex> lock(mLock);
- auto statsIt = mConfigStats.find(key);
- if (statsIt == mConfigStats.end()) {
- return;
- }
- statsIt->second->alert_stats[id]++;
-}
-
-void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
- lock_guard<std::mutex> lock(mLock);
- mAnomalyAlarmRegisteredStats++;
-}
-
-void StatsdStats::noteRegisteredPeriodicAlarmChanged() {
- lock_guard<std::mutex> lock(mLock);
- mPeriodicAlarmRegisteredStats++;
-}
-
-void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].minPullIntervalSec =
- std::min(mPulledAtomStats[pullAtomId].minPullIntervalSec, intervalSec);
-}
-
-void StatsdStats::notePull(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].totalPull++;
-}
-
-void StatsdStats::notePullFromCache(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].totalPullFromCache++;
-}
-
-void StatsdStats::notePullTime(int pullAtomId, int64_t pullTimeNs) {
- lock_guard<std::mutex> lock(mLock);
- auto& pullStats = mPulledAtomStats[pullAtomId];
- pullStats.maxPullTimeNs = std::max(pullStats.maxPullTimeNs, pullTimeNs);
- pullStats.avgPullTimeNs = (pullStats.avgPullTimeNs * pullStats.numPullTime + pullTimeNs) /
- (pullStats.numPullTime + 1);
- pullStats.numPullTime += 1;
-}
-
-void StatsdStats::notePullDelay(int pullAtomId, int64_t pullDelayNs) {
- lock_guard<std::mutex> lock(mLock);
- auto& pullStats = mPulledAtomStats[pullAtomId];
- pullStats.maxPullDelayNs = std::max(pullStats.maxPullDelayNs, pullDelayNs);
- pullStats.avgPullDelayNs =
- (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
- (pullStats.numPullDelay + 1);
- pullStats.numPullDelay += 1;
-}
-
-void StatsdStats::notePullDataError(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].dataError++;
-}
-
-void StatsdStats::notePullTimeout(int pullAtomId,
- int64_t pullUptimeMillis,
- int64_t pullElapsedMillis) {
- lock_guard<std::mutex> lock(mLock);
- PulledAtomStats& pulledAtomStats = mPulledAtomStats[pullAtomId];
- pulledAtomStats.pullTimeout++;
-
- if (pulledAtomStats.pullTimeoutMetadata.size() == kMaxTimestampCount) {
- pulledAtomStats.pullTimeoutMetadata.pop_front();
- }
-
- pulledAtomStats.pullTimeoutMetadata.emplace_back(pullUptimeMillis, pullElapsedMillis);
-}
-
-void StatsdStats::notePullExceedMaxDelay(int pullAtomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].pullExceedMaxDelay++;
-}
-
-void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
-
- if (atomId <= kMaxPushedAtomId) {
- mPushedAtomStats[atomId]++;
- } else {
- if (mNonPlatformPushedAtomStats.size() < kMaxNonPlatformPushedAtoms) {
- mNonPlatformPushedAtomStats[atomId]++;
- }
- }
-}
-
-void StatsdStats::noteSystemServerRestart(int32_t timeSec) {
- lock_guard<std::mutex> lock(mLock);
-
- if (mSystemServerRestartSec.size() == kMaxSystemServerRestarts) {
- mSystemServerRestartSec.pop_front();
- }
- mSystemServerRestartSec.push_back(timeSec);
-}
-
-void StatsdStats::notePullFailed(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].pullFailed++;
-}
-
-void StatsdStats::notePullUidProviderNotFound(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].pullUidProviderNotFound++;
-}
-
-void StatsdStats::notePullerNotFound(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].pullerNotFound++;
-}
-
-void StatsdStats::notePullBinderCallFailed(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].binderCallFailCount++;
-}
-
-void StatsdStats::noteEmptyData(int atomId) {
- lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[atomId].emptyData++;
-}
-
-void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
- lock_guard<std::mutex> lock(mLock);
- if (registered) {
- mPulledAtomStats[atomId].registeredCount++;
- } else {
- mPulledAtomStats[atomId].unregisteredCount++;
- }
-}
-
-void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).hardDimensionLimitReached++;
-}
-
-void StatsdStats::noteLateLogEventSkipped(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).lateLogEventSkipped++;
-}
-
-void StatsdStats::noteSkippedForwardBuckets(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).skippedForwardBuckets++;
-}
-
-void StatsdStats::noteBadValueType(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).badValueType++;
-}
-
-void StatsdStats::noteBucketDropped(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).bucketDropped++;
-}
-
-void StatsdStats::noteBucketUnknownCondition(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).bucketUnknownCondition++;
-}
-
-void StatsdStats::noteConditionChangeInNextBucket(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).conditionChangeInNextBucket++;
-}
-
-void StatsdStats::noteInvalidatedBucket(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).invalidatedBucket++;
-}
-
-void StatsdStats::noteBucketCount(int64_t metricId) {
- lock_guard<std::mutex> lock(mLock);
- getAtomMetricStats(metricId).bucketCount++;
-}
-
-void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) {
- lock_guard<std::mutex> lock(mLock);
- AtomMetricStats& pullStats = getAtomMetricStats(metricId);
- pullStats.maxBucketBoundaryDelayNs =
- std::max(pullStats.maxBucketBoundaryDelayNs, timeDelayNs);
- pullStats.minBucketBoundaryDelayNs =
- std::min(pullStats.minBucketBoundaryDelayNs, timeDelayNs);
-}
-
-void StatsdStats::noteAtomError(int atomTag, bool pull) {
- lock_guard<std::mutex> lock(mLock);
- if (pull) {
- mPulledAtomStats[atomTag].atomErrorCount++;
- return;
- }
-
- bool present = (mPushedAtomErrorStats.find(atomTag) != mPushedAtomErrorStats.end());
- bool full = (mPushedAtomErrorStats.size() >= (size_t)kMaxPushedAtomErrorStatsSize);
- if (!full || present) {
- mPushedAtomErrorStats[atomTag]++;
- }
-}
-
-StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int64_t metricId) {
- auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
- if (atomMetricStatsIter != mAtomMetricStats.end()) {
- return atomMetricStatsIter->second;
- }
- auto emplaceResult = mAtomMetricStats.emplace(metricId, AtomMetricStats());
- return emplaceResult.first->second;
-}
-
-void StatsdStats::reset() {
- lock_guard<std::mutex> lock(mLock);
- resetInternalLocked();
-}
-
-void StatsdStats::resetInternalLocked() {
- // Reset the historical data, but keep the active ConfigStats
- mStartTimeSec = getWallClockSec();
- mIceBox.clear();
- std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0);
- mNonPlatformPushedAtomStats.clear();
- mAnomalyAlarmRegisteredStats = 0;
- mPeriodicAlarmRegisteredStats = 0;
- mSystemServerRestartSec.clear();
- mLogLossStats.clear();
- mOverflowCount = 0;
- mMinQueueHistoryNs = kInt64Max;
- mMaxQueueHistoryNs = 0;
- for (auto& config : mConfigStats) {
- config.second->broadcast_sent_time_sec.clear();
- config.second->activation_time_sec.clear();
- config.second->deactivation_time_sec.clear();
- config.second->data_drop_time_sec.clear();
- config.second->data_drop_bytes.clear();
- config.second->dump_report_stats.clear();
- config.second->annotations.clear();
- config.second->matcher_stats.clear();
- config.second->condition_stats.clear();
- config.second->metric_stats.clear();
- config.second->metric_dimension_in_condition_stats.clear();
- config.second->alert_stats.clear();
- }
- for (auto& pullStats : mPulledAtomStats) {
- pullStats.second.totalPull = 0;
- pullStats.second.totalPullFromCache = 0;
- pullStats.second.minPullIntervalSec = LONG_MAX;
- pullStats.second.avgPullTimeNs = 0;
- pullStats.second.maxPullTimeNs = 0;
- pullStats.second.numPullTime = 0;
- pullStats.second.avgPullDelayNs = 0;
- pullStats.second.maxPullDelayNs = 0;
- pullStats.second.numPullDelay = 0;
- pullStats.second.dataError = 0;
- pullStats.second.pullTimeout = 0;
- pullStats.second.pullExceedMaxDelay = 0;
- pullStats.second.pullFailed = 0;
- pullStats.second.pullUidProviderNotFound = 0;
- pullStats.second.pullerNotFound = 0;
- pullStats.second.registeredCount = 0;
- pullStats.second.unregisteredCount = 0;
- pullStats.second.atomErrorCount = 0;
- pullStats.second.binderCallFailCount = 0;
- pullStats.second.pullTimeoutMetadata.clear();
- }
- mAtomMetricStats.clear();
- mActivationBroadcastGuardrailStats.clear();
- mPushedAtomErrorStats.clear();
-}
-
-string buildTimeString(int64_t timeSec) {
- time_t t = timeSec;
- struct tm* tm = localtime(&t);
- char timeBuffer[80];
- strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
- return string(timeBuffer);
-}
-
-int StatsdStats::getPushedAtomErrors(int atomId) const {
- const auto& it = mPushedAtomErrorStats.find(atomId);
- if (it != mPushedAtomErrorStats.end()) {
- return it->second;
- } else {
- return 0;
- }
-}
-
-void StatsdStats::dumpStats(int out) const {
- lock_guard<std::mutex> lock(mLock);
- time_t t = mStartTimeSec;
- struct tm* tm = localtime(&t);
- char timeBuffer[80];
- strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
- dprintf(out, "Stats collection start second: %s\n", timeBuffer);
- dprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
- for (const auto& configStats : mIceBox) {
- dprintf(out,
- "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
- "#matcher=%d, #alert=%d, valid=%d\n",
- configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
- configStats->deletion_time_sec, configStats->reset_time_sec,
- configStats->metric_count, configStats->condition_count, configStats->matcher_count,
- configStats->alert_count, configStats->is_valid);
-
- for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
- dprintf(out, "\tbroadcast time: %d\n", broadcastTime);
- }
-
- for (const int& activationTime : configStats->activation_time_sec) {
- dprintf(out, "\tactivation time: %d\n", activationTime);
- }
-
- for (const int& deactivationTime : configStats->deactivation_time_sec) {
- dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
- }
-
- auto dropTimePtr = configStats->data_drop_time_sec.begin();
- auto dropBytesPtr = configStats->data_drop_bytes.begin();
- for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
- i++, dropTimePtr++, dropBytesPtr++) {
- dprintf(out, "\tdata drop time: %d with size %lld", *dropTimePtr,
- (long long)*dropBytesPtr);
- }
- }
- dprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
- for (auto& pair : mConfigStats) {
- auto& configStats = pair.second;
- dprintf(out,
- "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
- "#matcher=%d, #alert=%d, valid=%d\n",
- configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
- configStats->deletion_time_sec, configStats->metric_count,
- configStats->condition_count, configStats->matcher_count, configStats->alert_count,
- configStats->is_valid);
- for (const auto& annotation : configStats->annotations) {
- dprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
- annotation.second);
- }
-
- for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
- dprintf(out, "\tbroadcast time: %s(%lld)\n", buildTimeString(broadcastTime).c_str(),
- (long long)broadcastTime);
- }
-
- for (const int& activationTime : configStats->activation_time_sec) {
- dprintf(out, "\tactivation time: %d\n", activationTime);
- }
-
- for (const int& deactivationTime : configStats->deactivation_time_sec) {
- dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
- }
-
- auto dropTimePtr = configStats->data_drop_time_sec.begin();
- auto dropBytesPtr = configStats->data_drop_bytes.begin();
- for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
- i++, dropTimePtr++, dropBytesPtr++) {
- dprintf(out, "\tdata drop time: %s(%lld) with %lld bytes\n",
- buildTimeString(*dropTimePtr).c_str(), (long long)*dropTimePtr,
- (long long)*dropBytesPtr);
- }
-
- for (const auto& dump : configStats->dump_report_stats) {
- dprintf(out, "\tdump report time: %s(%lld) bytes: %lld\n",
- buildTimeString(dump.first).c_str(), (long long)dump.first,
- (long long)dump.second);
- }
-
- for (const auto& stats : pair.second->matcher_stats) {
- dprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
- }
-
- for (const auto& stats : pair.second->condition_stats) {
- dprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
- stats.second);
- }
-
- for (const auto& stats : pair.second->condition_stats) {
- dprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
- stats.second);
- }
-
- for (const auto& stats : pair.second->alert_stats) {
- dprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
- }
- }
- dprintf(out, "********Disk Usage stats***********\n");
- StorageManager::printStats(out);
- dprintf(out, "********Pushed Atom stats***********\n");
- const size_t atomCounts = mPushedAtomStats.size();
- for (size_t i = 2; i < atomCounts; i++) {
- if (mPushedAtomStats[i] > 0) {
- dprintf(out, "Atom %zu->(total count)%d, (error count)%d\n", i, mPushedAtomStats[i],
- getPushedAtomErrors((int)i));
- }
- }
- for (const auto& pair : mNonPlatformPushedAtomStats) {
- dprintf(out, "Atom %d->(total count)%d, (error count)%d\n", pair.first, pair.second,
- getPushedAtomErrors(pair.first));
- }
-
- dprintf(out, "********Pulled Atom stats***********\n");
- for (const auto& pair : mPulledAtomStats) {
- dprintf(out,
- "Atom %d->(total pull)%ld, (pull from cache)%ld, "
- "(pull failed)%ld, (min pull interval)%ld \n"
- " (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
- "nanos)%lld, "
- " (max pull delay nanos)%lld, (data error)%ld\n"
- " (pull timeout)%ld, (pull exceed max delay)%ld"
- " (no uid provider count)%ld, (no puller found count)%ld\n"
- " (registered count) %ld, (unregistered count) %ld"
- " (atom error count) %d\n",
- (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
- (long)pair.second.pullFailed, (long)pair.second.minPullIntervalSec,
- (long long)pair.second.avgPullTimeNs, (long long)pair.second.maxPullTimeNs,
- (long long)pair.second.avgPullDelayNs, (long long)pair.second.maxPullDelayNs,
- pair.second.dataError, pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
- pair.second.pullUidProviderNotFound, pair.second.pullerNotFound,
- pair.second.registeredCount, pair.second.unregisteredCount,
- pair.second.atomErrorCount);
- if (pair.second.pullTimeoutMetadata.size() > 0) {
- string uptimeMillis = "(pull timeout system uptime millis) ";
- string pullTimeoutMillis = "(pull timeout elapsed time millis) ";
- for (const auto& stats : pair.second.pullTimeoutMetadata) {
- uptimeMillis.append(to_string(stats.pullTimeoutUptimeMillis)).append(",");;
- pullTimeoutMillis.append(to_string(stats.pullTimeoutElapsedMillis)).append(",");
- }
- uptimeMillis.pop_back();
- uptimeMillis.push_back('\n');
- pullTimeoutMillis.pop_back();
- pullTimeoutMillis.push_back('\n');
- dprintf(out, "%s", uptimeMillis.c_str());
- dprintf(out, "%s", pullTimeoutMillis.c_str());
- }
- }
-
- if (mAnomalyAlarmRegisteredStats > 0) {
- dprintf(out, "********AnomalyAlarmStats stats***********\n");
- dprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
- }
-
- if (mPeriodicAlarmRegisteredStats > 0) {
- dprintf(out, "********SubscriberAlarmStats stats***********\n");
- dprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
- }
-
- dprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
- mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps,
- mUidMapStats.dropped_changes);
-
- for (const auto& restart : mSystemServerRestartSec) {
- dprintf(out, "System server restarts at %s(%lld)\n", buildTimeString(restart).c_str(),
- (long long)restart);
- }
-
- for (const auto& loss : mLogLossStats) {
- dprintf(out,
- "Log loss: %lld (wall clock sec) - %d (count), %d (last error), %d (last tag), %d "
- "(uid), %d (pid)\n",
- (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag,
- loss.mUid, loss.mPid);
- }
-
- dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
- mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
-
- if (mActivationBroadcastGuardrailStats.size() > 0) {
- dprintf(out, "********mActivationBroadcastGuardrail stats***********\n");
- for (const auto& pair: mActivationBroadcastGuardrailStats) {
- dprintf(out, "Uid %d: Times: ", pair.first);
- for (const auto& guardrailHitTime : pair.second) {
- dprintf(out, "%d ", guardrailHitTime);
- }
- }
- dprintf(out, "\n");
- }
-}
-
-void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
- uint64_t token =
- proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec);
- if (configStats.reset_time_sec != 0) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec);
- }
- if (configStats.deletion_time_sec != 0) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION,
- configStats.deletion_time_sec);
- }
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_METRIC_COUNT, configStats.metric_count);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CONDITION_COUNT,
- configStats.condition_count);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_MATCHER_COUNT, configStats.matcher_count);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ALERT_COUNT, configStats.alert_count);
- proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_VALID, configStats.is_valid);
-
- for (const auto& broadcast : configStats.broadcast_sent_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_BROADCAST | FIELD_COUNT_REPEATED,
- broadcast);
- }
-
- for (const auto& activation : configStats.activation_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ACTIVATION | FIELD_COUNT_REPEATED,
- activation);
- }
-
- for (const auto& deactivation : configStats.deactivation_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DEACTIVATION | FIELD_COUNT_REPEATED,
- deactivation);
- }
-
- for (const auto& drop_time : configStats.data_drop_time_sec) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DATA_DROP_TIME | FIELD_COUNT_REPEATED,
- drop_time);
- }
-
- for (const auto& drop_bytes : configStats.data_drop_bytes) {
- proto->write(
- FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES | FIELD_COUNT_REPEATED,
- (long long)drop_bytes);
- }
-
- for (const auto& dump : configStats.dump_report_stats) {
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME |
- FIELD_COUNT_REPEATED,
- dump.first);
- }
-
- for (const auto& dump : configStats.dump_report_stats) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES |
- FIELD_COUNT_REPEATED,
- (long long)dump.second);
- }
-
- for (const auto& annotation : configStats.annotations) {
- uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_ANNOTATION);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64,
- (long long)annotation.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second);
- proto->end(token);
- }
-
- for (const auto& pair : configStats.matcher_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_MATCHER_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_MATCHER_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_MATCHER_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- for (const auto& pair : configStats.condition_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_CONDITION_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONDITION_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- for (const auto& pair : configStats.metric_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_METRIC_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
- for (const auto& pair : configStats.metric_dimension_in_condition_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- for (const auto& pair : configStats.alert_stats) {
- uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_CONFIG_STATS_ALERT_STATS);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_STATS_ID, (long long)pair.first);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_ALERT_STATS_COUNT, pair.second);
- proto->end(tmpToken);
- }
-
- proto->end(token);
-}
-
-void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
- lock_guard<std::mutex> lock(mLock);
-
- ProtoOutputStream proto;
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)getWallClockSec());
-
- for (const auto& configStats : mIceBox) {
- addConfigStatsToProto(*configStats, &proto);
- }
-
- for (auto& pair : mConfigStats) {
- addConfigStatsToProto(*(pair.second), &proto);
- }
-
- const size_t atomCounts = mPushedAtomStats.size();
- for (size_t i = 2; i < atomCounts; i++) {
- if (mPushedAtomStats[i] > 0) {
- uint64_t token =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]);
- int errors = getPushedAtomErrors(i);
- if (errors > 0) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors);
- }
- proto.end(token);
- }
- }
-
- for (const auto& pair : mNonPlatformPushedAtomStats) {
- uint64_t token =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, pair.first);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, pair.second);
- int errors = getPushedAtomErrors(pair.first);
- if (errors > 0) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors);
- }
- proto.end(token);
- }
-
- for (const auto& pair : mPulledAtomStats) {
- android::os::statsd::writePullerStatsToStream(pair, &proto);
- }
-
- for (const auto& pair : mAtomMetricStats) {
- android::os::statsd::writeAtomMetricStatsToStream(pair, &proto);
- }
-
- if (mAnomalyAlarmRegisteredStats > 0) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
- mAnomalyAlarmRegisteredStats);
- proto.end(token);
- }
-
- if (mPeriodicAlarmRegisteredStats > 0) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PERIODIC_ALARM_STATS);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_PERIODIC_ALARMS_REGISTERED,
- mPeriodicAlarmRegisteredStats);
- proto.end(token);
- }
-
- uint64_t uidMapToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_CHANGES, mUidMapStats.changes);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_BYTES_USED, mUidMapStats.bytes_used);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DROPPED_CHANGES, mUidMapStats.dropped_changes);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DELETED_APPS, mUidMapStats.deleted_apps);
- proto.end(uidMapToken);
-
- for (const auto& error : mLogLossStats) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
- FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TAG, error.mLastTag);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_UID, error.mUid);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_PID, error.mPid);
- proto.end(token);
- }
-
- if (mOverflowCount > 0) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount);
- proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY,
- (long long)mMaxQueueHistoryNs);
- proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY,
- (long long)mMinQueueHistoryNs);
- proto.end(token);
- }
-
- for (const auto& restart : mSystemServerRestartSec) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED,
- restart);
- }
-
- for (const auto& pair: mActivationBroadcastGuardrailStats) {
- uint64_t token = proto.start(FIELD_TYPE_MESSAGE |
- FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL |
- FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID,
- (int32_t) pair.first);
- for (const auto& guardrailHitTime : pair.second) {
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME |
- FIELD_COUNT_REPEATED,
- guardrailHitTime);
- }
- proto.end(token);
- }
-
- output->clear();
- size_t bufferSize = proto.size();
- output->resize(bufferSize);
-
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*output)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- if (reset) {
- resetInternalLocked();
- }
-
- VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
deleted file mode 100644
index 005048446fc3..000000000000
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include "config/ConfigKey.h"
-
-#include <gtest/gtest_prod.h>
-#include <log/log_time.h>
-#include <list>
-#include <mutex>
-#include <string>
-#include <vector>
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct ConfigStats {
- int32_t uid;
- int64_t id;
- int32_t creation_time_sec;
- int32_t deletion_time_sec = 0;
- int32_t reset_time_sec = 0;
- int32_t metric_count;
- int32_t condition_count;
- int32_t matcher_count;
- int32_t alert_count;
- bool is_valid;
-
- std::list<int32_t> broadcast_sent_time_sec;
-
- // Times at which this config is activated.
- std::list<int32_t> activation_time_sec;
-
- // Times at which this config is deactivated.
- std::list<int32_t> deactivation_time_sec;
-
- std::list<int32_t> data_drop_time_sec;
- // Number of bytes dropped at corresponding time.
- std::list<int64_t> data_drop_bytes;
- std::list<std::pair<int32_t, int64_t>> dump_report_stats;
-
- // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> matcher_stats;
-
- // Stores the number of output tuple of condition trackers when it's bigger than
- // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
- // it means some data has been dropped. The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> condition_stats;
-
- // Stores the number of output tuple of metric producers when it's bigger than
- // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
- // it means some data has been dropped. The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> metric_stats;
-
- // Stores the max number of output tuple of dimensions in condition across dimensions in what
- // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
- // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
- // kMaxConfigCount.
- std::map<const int64_t, int> metric_dimension_in_condition_stats;
-
- // Stores the number of times an anomaly detection alert has been declared.
- // The map size is capped by kMaxConfigCount.
- std::map<const int64_t, int> alert_stats;
-
- // Stores the config ID for each sub-config used.
- std::list<std::pair<const int64_t, const int32_t>> annotations;
-};
-
-struct UidMapStats {
- int32_t changes;
- int32_t bytes_used;
- int32_t dropped_changes;
- int32_t deleted_apps = 0;
-};
-
-// Keeps track of stats of statsd.
-// Single instance shared across the process. All public methods are thread safe.
-class StatsdStats {
-public:
- static StatsdStats& getInstance();
- ~StatsdStats(){};
-
- const static int kDimensionKeySizeSoftLimit = 500;
- const static int kDimensionKeySizeHardLimit = 800;
-
- // Per atom dimension key size limit
- static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
-
- const static int kMaxConfigCountPerUid = 20;
- const static int kMaxAlertCountPerConfig = 100;
- const static int kMaxConditionCountPerConfig = 300;
- const static int kMaxMetricCountPerConfig = 1000;
- const static int kMaxMatcherCountPerConfig = 800;
-
- // The max number of old config stats we keep.
- const static int kMaxIceBoxSize = 20;
-
- const static int kMaxLoggerErrors = 20;
-
- const static int kMaxSystemServerRestarts = 20;
-
- const static int kMaxTimestampCount = 20;
-
- const static int kMaxLogSourceCount = 50;
-
- const static int kMaxPullAtomPackages = 100;
-
- // Max memory allowed for storing metrics per configuration. If this limit is exceeded, statsd
- // drops the metrics data in memory.
- static const size_t kMaxMetricsBytesPerConfig = 2 * 1024 * 1024;
-
- // Soft memory limit per configuration. Once this limit is exceeded, we begin notifying the
- // data subscriber that it's time to call getData.
- static const size_t kBytesPerConfigTriggerGetData = 192 * 1024;
-
- // Cap the UID map's memory usage to this. This should be fairly high since the UID information
- // is critical for understanding the metrics.
- const static size_t kMaxBytesUsedUidMap = 50 * 1024;
-
- // The number of deleted apps that are stored in the uid map.
- const static int kMaxDeletedAppsInUidMap = 100;
-
- /* Minimum period between two broadcasts in nanoseconds. */
- static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
-
- /* Min period between two checks of byte size per config key in nanoseconds. */
- static const int64_t kMinByteSizeCheckPeriodNs = 60 * NS_PER_SEC;
-
- /* Minimum period between two activation broadcasts in nanoseconds. */
- static const int64_t kMinActivationBroadcastPeriodNs = 10 * NS_PER_SEC;
-
- // Maximum age (30 days) that files on disk can exist in seconds.
- static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
-
- // Maximum age (2 days) that local history files on disk can exist in seconds.
- static const int kMaxLocalHistoryAgeSecond = 60 * 60 * 24 * 2;
-
- // Maximum number of files (1000) that can be in stats directory on disk.
- static const int kMaxFileNumber = 1000;
-
- // Maximum size of all files that can be written to stats directory on disk.
- static const int kMaxFileSize = 50 * 1024 * 1024;
-
- // How long to try to clear puller cache from last time
- static const long kPullerCacheClearIntervalSec = 1;
-
- // Max time to do a pull.
- static const int64_t kPullMaxDelayNs = 30 * NS_PER_SEC;
-
- // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
- static const int kMaxNonPlatformPushedAtoms = 100;
-
- // Maximum atom id value that we consider a platform pushed atom.
- // This should be updated once highest pushed atom id in atoms.proto approaches this value.
- static const int kMaxPushedAtomId = 500;
-
- // Atom id that is the start of the pulled atoms.
- static const int kPullAtomStartTag = 10000;
-
- // Atom id that is the start of vendor atoms.
- static const int kVendorAtomStartTag = 100000;
-
- // Vendor pulled atom start id.
- static const int32_t kVendorPulledAtomStartTag = 150000;
-
- // Beginning of range for timestamp truncation.
- static const int32_t kTimestampTruncationStartTag = 300000;
-
- // End of range for timestamp truncation.
- static const int32_t kTimestampTruncationEndTag = 304999;
-
- // Max accepted atom id.
- static const int32_t kMaxAtomTag = 200000;
-
- static const int64_t kInt64Max = 0x7fffffffffffffffLL;
-
- static const int32_t kMaxLoggedBucketDropEvents = 10;
-
- /**
- * Report a new config has been received and report the static stats about the config.
- *
- * The static stats include: the count of metrics, conditions, matchers, and alerts.
- * If the config is not valid, this config stats will be put into icebox immediately.
- */
- void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
- int matchersCount, int alertCount,
- const std::list<std::pair<const int64_t, const int32_t>>& annotations,
- bool isValid);
- /**
- * Report a config has been removed.
- */
- void noteConfigRemoved(const ConfigKey& key);
- /**
- * Report a config has been reset when ttl expires.
- */
- void noteConfigReset(const ConfigKey& key);
-
- /**
- * Report a broadcast has been sent to a config owner to collect the data.
- */
- void noteBroadcastSent(const ConfigKey& key);
-
- /**
- * Report that a config has become activated or deactivated.
- * This can be different from whether or not a broadcast is sent if the
- * guardrail prevented the broadcast from being sent.
- */
- void noteActiveStatusChanged(const ConfigKey& key, bool activate);
-
- /**
- * Report a config's metrics data has been dropped.
- */
- void noteDataDropped(const ConfigKey& key, const size_t totalBytes);
-
- /**
- * Report metrics data report has been sent.
- *
- * The report may be requested via StatsManager API, or through adb cmd.
- */
- void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes);
-
- /**
- * Report the size of output tuple of a condition.
- *
- * Note: only report when the condition has an output dimension, and the tuple
- * count > kDimensionKeySizeSoftLimit.
- *
- * [key]: The config key that this condition belongs to.
- * [id]: The id of the condition.
- * [size]: The output tuple size.
- */
- void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
-
- /**
- * Report the size of output tuple of a metric.
- *
- * Note: only report when the metric has an output dimension, and the tuple
- * count > kDimensionKeySizeSoftLimit.
- *
- * [key]: The config key that this metric belongs to.
- * [id]: The id of the metric.
- * [size]: The output tuple size.
- */
- void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
-
- /**
- * Report the max size of output tuple of dimension in condition across dimensions in what.
- *
- * Note: only report when the metric has an output dimension in condition, and the max tuple
- * count > kDimensionKeySizeSoftLimit.
- *
- * [key]: The config key that this metric belongs to.
- * [id]: The id of the metric.
- * [size]: The output tuple size.
- */
- void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
-
- /**
- * Report a matcher has been matched.
- *
- * [key]: The config key that this matcher belongs to.
- * [id]: The id of the matcher.
- */
- void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
-
- /**
- * Report that an anomaly detection alert has been declared.
- *
- * [key]: The config key that this alert belongs to.
- * [id]: The id of the alert.
- */
- void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
-
- /**
- * Report an atom event has been logged.
- */
- void noteAtomLogged(int atomId, int32_t timeSec);
-
- /**
- * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
- */
- void noteRegisteredAnomalyAlarmChanged();
-
- /**
- * Report that statsd modified the periodic alarm registered with StatsCompanionService.
- */
- void noteRegisteredPeriodicAlarmChanged();
-
- /**
- * Records the number of delta entries that are being dropped from the uid map.
- */
- void noteUidMapDropped(int deltas);
-
- /**
- * Records that an app was deleted (from statsd's map).
- */
- void noteUidMapAppDeletionDropped();
-
- /**
- * Updates the number of changes currently stored in the uid map.
- */
- void setUidMapChanges(int changes);
- void setCurrentUidMapMemory(int bytes);
-
- /*
- * Updates minimum interval between pulls for an pulled atom.
- */
- void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
-
- /*
- * Notes an atom is pulled.
- */
- void notePull(int pullAtomId);
-
- /*
- * Notes an atom is served from puller cache.
- */
- void notePullFromCache(int pullAtomId);
-
- /*
- * Notify data error for pulled atom.
- */
- void notePullDataError(int pullAtomId);
-
- /*
- * Records time for actual pulling, not including those served from cache and not including
- * statsd processing delays.
- */
- void notePullTime(int pullAtomId, int64_t pullTimeNs);
-
- /*
- * Records pull delay for a pulled atom, including those served from cache and including statsd
- * processing delays.
- */
- void notePullDelay(int pullAtomId, int64_t pullDelayNs);
-
- /*
- * Records pull exceeds timeout for the puller.
- */
- void notePullTimeout(int pullAtomId, int64_t pullUptimeMillis, int64_t pullElapsedMillis);
-
- /*
- * Records pull exceeds max delay for a metric.
- */
- void notePullExceedMaxDelay(int pullAtomId);
-
- /*
- * Records when system server restarts.
- */
- void noteSystemServerRestart(int32_t timeSec);
-
- /**
- * Records statsd skipped an event.
- */
- void noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
- int32_t lastAtomTag, int32_t uid, int32_t pid);
-
- /**
- * Records that the pull of an atom has failed. Eg, if the client indicated the pull failed, if
- * the pull timed out, or if the outgoing binder call failed.
- * This count will only increment if the puller was actually invoked.
- *
- * It does not include a pull not occurring due to not finding the appropriate
- * puller. These cases are covered in other counts.
- */
- void notePullFailed(int atomId);
-
- /**
- * Records that the pull of an atom has failed due to not having a uid provider.
- */
- void notePullUidProviderNotFound(int atomId);
-
- /**
- * Records that the pull of an atom has failed due not finding a puller registered by a
- * trusted uid.
- */
- void notePullerNotFound(int atomId);
-
- /**
- * Records that the pull has failed due to the outgoing binder call failing.
- */
- void notePullBinderCallFailed(int atomId);
-
- /**
- * A pull with no data occurred
- */
- void noteEmptyData(int atomId);
-
- /**
- * Records that a puller callback for the given atomId was registered or unregistered.
- *
- * @param registered True if the callback was registered, false if was unregistered.
- */
- void notePullerCallbackRegistrationChanged(int atomId, bool registered);
-
- /**
- * Hard limit was reached in the cardinality of an atom
- */
- void noteHardDimensionLimitReached(int64_t metricId);
-
- /**
- * A log event was too late, arrived in the wrong bucket and was skipped
- */
- void noteLateLogEventSkipped(int64_t metricId);
-
- /**
- * Buckets were skipped as time elapsed without any data for them
- */
- void noteSkippedForwardBuckets(int64_t metricId);
-
- /**
- * An unsupported value type was received
- */
- void noteBadValueType(int64_t metricId);
-
- /**
- * Buckets were dropped due to reclaim memory.
- */
- void noteBucketDropped(int64_t metricId);
-
- /**
- * A condition change was too late, arrived in the wrong bucket and was skipped
- */
- void noteConditionChangeInNextBucket(int64_t metricId);
-
- /**
- * A bucket has been tagged as invalid.
- */
- void noteInvalidatedBucket(int64_t metricId);
-
- /**
- * Tracks the total number of buckets (include skipped/invalid buckets).
- */
- void noteBucketCount(int64_t metricId);
-
- /**
- * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and
- * the end of the bucket.
- */
- void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs);
-
- /**
- * Number of buckets with unknown condition.
- */
- void noteBucketUnknownCondition(int64_t metricId);
-
- /* Reports one event has been dropped due to queue overflow, and the oldest event timestamp in
- * the queue */
- void noteEventQueueOverflow(int64_t oldestEventTimestampNs);
-
- /**
- * Reports that the activation broadcast guardrail was hit for this uid. Namely, the broadcast
- * should have been sent, but instead was skipped due to hitting the guardrail.
- */
- void noteActivationBroadcastGuardrailHit(const int uid);
-
- /**
- * Reports that an atom is erroneous or cannot be parsed successfully by
- * statsd. An atom tag of 0 indicates that the client did not supply the
- * atom id within the encoding.
- *
- * For pushed atoms only, this call should be preceded by a call to
- * noteAtomLogged.
- */
- void noteAtomError(int atomTag, bool pull=false);
-
- /**
- * Reset the historical stats. Including all stats in icebox, and the tracked stats about
- * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
- * to collect stats after reset() has been called.
- */
- void reset();
-
- /**
- * Output the stats in protobuf binary format to [buffer].
- *
- * [reset]: whether to clear the historical stats after the call.
- */
- void dumpStats(std::vector<uint8_t>* buffer, bool reset);
-
- /**
- * Output statsd stats in human readable format to [out] file descriptor.
- */
- void dumpStats(int outFd) const;
-
- typedef struct PullTimeoutMetadata {
- int64_t pullTimeoutUptimeMillis;
- int64_t pullTimeoutElapsedMillis;
- PullTimeoutMetadata(int64_t uptimeMillis, int64_t elapsedMillis) :
- pullTimeoutUptimeMillis(uptimeMillis),
- pullTimeoutElapsedMillis(elapsedMillis) {/* do nothing */}
- } PullTimeoutMetadata;
-
- typedef struct {
- long totalPull = 0;
- long totalPullFromCache = 0;
- long minPullIntervalSec = LONG_MAX;
- int64_t avgPullTimeNs = 0;
- int64_t maxPullTimeNs = 0;
- long numPullTime = 0;
- int64_t avgPullDelayNs = 0;
- int64_t maxPullDelayNs = 0;
- long numPullDelay = 0;
- long dataError = 0;
- long pullTimeout = 0;
- long pullExceedMaxDelay = 0;
- long pullFailed = 0;
- long pullUidProviderNotFound = 0;
- long pullerNotFound = 0;
- long emptyData = 0;
- long registeredCount = 0;
- long unregisteredCount = 0;
- int32_t atomErrorCount = 0;
- long binderCallFailCount = 0;
- std::list<PullTimeoutMetadata> pullTimeoutMetadata;
- } PulledAtomStats;
-
- typedef struct {
- long hardDimensionLimitReached = 0;
- long lateLogEventSkipped = 0;
- long skippedForwardBuckets = 0;
- long badValueType = 0;
- long conditionChangeInNextBucket = 0;
- long invalidatedBucket = 0;
- long bucketDropped = 0;
- int64_t minBucketBoundaryDelayNs = 0;
- int64_t maxBucketBoundaryDelayNs = 0;
- long bucketUnknownCondition = 0;
- long bucketCount = 0;
- } AtomMetricStats;
-
-private:
- StatsdStats();
-
- mutable std::mutex mLock;
-
- int32_t mStartTimeSec;
-
- // Track the number of dropped entries used by the uid map.
- UidMapStats mUidMapStats;
-
- // The stats about the configs that are still in use.
- // The map size is capped by kMaxConfigCount.
- std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
-
- // Stores the stats for the configs that are no longer in use.
- // The size of the vector is capped by kMaxIceBoxSize.
- std::list<const std::shared_ptr<ConfigStats>> mIceBox;
-
- // Stores the number of times a pushed atom is logged.
- // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
- // out of that range will be put in mNonPlatformPushedAtomStats.
- // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
- std::vector<int> mPushedAtomStats;
-
- // Stores the number of times a pushed atom is logged for atom ids above kMaxPushedAtomId.
- // The max size of the map is kMaxNonPlatformPushedAtoms.
- std::unordered_map<int, int> mNonPlatformPushedAtomStats;
-
- // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
- std::map<int, PulledAtomStats> mPulledAtomStats;
-
- // Stores the number of times a pushed atom was logged erroneously. The
- // corresponding counts for pulled atoms are stored in PulledAtomStats.
- // The max size of this map is kMaxAtomErrorsStatsSize.
- std::map<int, int> mPushedAtomErrorStats;
- int kMaxPushedAtomErrorStatsSize = 100;
-
- // Maps metric ID to its stats. The size is capped by the number of metrics.
- std::map<int64_t, AtomMetricStats> mAtomMetricStats;
-
- // Maps uids to times when the activation changed broadcast not sent due to hitting the
- // guardrail. The size is capped by the number of configs, and up to 20 times per uid.
- std::map<int, std::list<int32_t>> mActivationBroadcastGuardrailStats;
-
- struct LogLossStats {
- LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
- int32_t pid)
- : mWallClockSec(sec),
- mCount(count),
- mLastError(error),
- mLastTag(tag),
- mUid(uid),
- mPid(pid) {
- }
- int32_t mWallClockSec;
- int32_t mCount;
- // error code defined in linux/errno.h
- int32_t mLastError;
- int32_t mLastTag;
- int32_t mUid;
- int32_t mPid;
- };
-
- // Max of {(now - oldestEventTimestamp) when overflow happens}.
- // This number is helpful to understand how SLOW statsd can be.
- int64_t mMaxQueueHistoryNs = 0;
-
- // Min of {(now - oldestEventTimestamp) when overflow happens}.
- // This number is helpful to understand how FAST the events floods to statsd.
- int64_t mMinQueueHistoryNs = kInt64Max;
-
- // Total number of events that are lost due to queue overflow.
- int32_t mOverflowCount = 0;
-
- // Timestamps when we detect log loss, and the number of logs lost.
- std::list<LogLossStats> mLogLossStats;
-
- std::list<int32_t> mSystemServerRestartSec;
-
- // Stores the number of times statsd modified the anomaly alarm registered with
- // StatsCompanionService.
- int mAnomalyAlarmRegisteredStats = 0;
-
- // Stores the number of times statsd registers the periodic alarm changes
- int mPeriodicAlarmRegisteredStats = 0;
-
- void noteConfigResetInternalLocked(const ConfigKey& key);
-
- void noteConfigRemovedInternalLocked(const ConfigKey& key);
-
- void resetInternalLocked();
-
- void noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec);
-
- void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec);
-
- void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
-
- void noteActiveStatusChanged(const ConfigKey& key, bool activate, int32_t timeSec);
-
- void noteActivationBroadcastGuardrailHit(const int uid, int32_t timeSec);
-
- void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
-
- int getPushedAtomErrors(int atomId) const;
-
- /**
- * Get a reference to AtomMetricStats for a metric. If none exists, create it. The reference
- * will live as long as `this`.
- */
- StatsdStats::AtomMetricStats& getAtomMetricStats(int64_t metricId);
-
- FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
- FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
- FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
- FRIEND_TEST(StatsdStatsTest, TestSubStats);
- FRIEND_TEST(StatsdStatsTest, TestAtomLog);
- FRIEND_TEST(StatsdStatsTest, TestNonPlatformAtomLog);
- FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
- FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
- FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
- FRIEND_TEST(StatsdStatsTest, TestPullAtomStats);
- FRIEND_TEST(StatsdStatsTest, TestAtomMetricsStats);
- FRIEND_TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit);
- FRIEND_TEST(StatsdStatsTest, TestAtomErrorStats);
-
- FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/hash.cpp b/cmds/statsd/src/hash.cpp
deleted file mode 100644
index 543a748adedb..000000000000
--- a/cmds/statsd/src/hash.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "hash.h"
-
-#ifndef FALLTHROUGH_INTENDED
-#define FALLTHROUGH_INTENDED [[fallthrough]]
-#endif
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-// Lower-level versions of Get... that read directly from a character buffer
-// without any bounds checking.
-inline uint32_t DecodeFixed32(const char *ptr) {
- return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0]))) |
- (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8) |
- (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16) |
- (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
-}
-
-inline uint64_t DecodeFixed64(const char* ptr) {
- uint64_t lo = DecodeFixed32(ptr);
- uint64_t hi = DecodeFixed32(ptr + 4);
- return (hi << 32) | lo;
-}
-
-// 0xff is in case char is signed.
-static inline uint32_t ByteAs32(char c) { return static_cast<uint32_t>(c) & 0xff; }
-static inline uint64_t ByteAs64(char c) { return static_cast<uint64_t>(c) & 0xff; }
-
-} // namespace
-
-uint32_t Hash32(const char *data, size_t n, uint32_t seed) {
- // 'm' and 'r' are mixing constants generated offline.
- // They're not really 'magic', they just happen to work well.
- const uint32_t m = 0x5bd1e995;
- const int r = 24;
-
- // Initialize the hash to a 'random' value
- uint32_t h = static_cast<uint32_t>(seed ^ n);
-
- // Mix 4 bytes at a time into the hash
- while (n >= 4) {
- uint32_t k = DecodeFixed32(data);
- k *= m;
- k ^= k >> r;
- k *= m;
- h *= m;
- h ^= k;
- data += 4;
- n -= 4;
- }
-
- // Handle the last few bytes of the input array
- switch (n) {
- case 3:
- h ^= ByteAs32(data[2]) << 16;
- FALLTHROUGH_INTENDED;
- case 2:
- h ^= ByteAs32(data[1]) << 8;
- FALLTHROUGH_INTENDED;
- case 1:
- h ^= ByteAs32(data[0]);
- h *= m;
- }
-
- // Do a few final mixes of the hash to ensure the last few
- // bytes are well-incorporated.
- h ^= h >> 13;
- h *= m;
- h ^= h >> 15;
- return h;
-}
-
-uint64_t Hash64(const char* data, size_t n, uint64_t seed) {
- const uint64_t m = 0xc6a4a7935bd1e995;
- const int r = 47;
-
- uint64_t h = seed ^ (n * m);
-
- while (n >= 8) {
- uint64_t k = DecodeFixed64(data);
- data += 8;
- n -= 8;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h ^= k;
- h *= m;
- }
-
- switch (n) {
- case 7:
- h ^= ByteAs64(data[6]) << 48;
- FALLTHROUGH_INTENDED;
- case 6:
- h ^= ByteAs64(data[5]) << 40;
- FALLTHROUGH_INTENDED;
- case 5:
- h ^= ByteAs64(data[4]) << 32;
- FALLTHROUGH_INTENDED;
- case 4:
- h ^= ByteAs64(data[3]) << 24;
- FALLTHROUGH_INTENDED;
- case 3:
- h ^= ByteAs64(data[2]) << 16;
- FALLTHROUGH_INTENDED;
- case 2:
- h ^= ByteAs64(data[1]) << 8;
- FALLTHROUGH_INTENDED;
- case 1:
- h ^= ByteAs64(data[0]);
- h *= m;
- }
-
- h ^= h >> r;
- h *= m;
- h ^= h >> r;
-
- return h;
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/hash.h b/cmds/statsd/src/hash.h
deleted file mode 100644
index cfe869f60202..000000000000
--- a/cmds/statsd/src/hash.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-extern uint32_t Hash32(const char *data, size_t n, uint32_t seed);
-extern uint64_t Hash64(const char* data, size_t n, uint64_t seed);
-
-inline uint32_t Hash32(const char *data, size_t n) {
- return Hash32(data, n, 0xBEEF);
-}
-
-inline uint32_t Hash32(const std::string &input) {
- return Hash32(input.data(), input.size());
-}
-
-inline uint64_t Hash64(const char* data, size_t n) {
- return Hash64(data, n, 0xDECAFCAFFE);
-}
-
-inline uint64_t Hash64(const std::string& str) {
- return Hash64(str.data(), str.size());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
deleted file mode 100644
index f56fa6221bc9..000000000000
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "logd/LogEvent.h"
-
-#include <android-base/stringprintf.h>
-#include <android/binder_ibinder.h>
-#include <private/android_filesystem_config.h>
-
-#include "annotations.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for TrainInfo experiment id serialization
-const int FIELD_ID_EXPERIMENT_ID = 1;
-
-using namespace android::util;
-using android::base::StringPrintf;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::vector;
-
-// stats_event.h socket types. Keep in sync.
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
-LogEvent::LogEvent(int32_t uid, int32_t pid)
- : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) {
-}
-
-LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging,
- bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
- const std::vector<uint8_t>& experimentIds, int32_t userId) {
- mLogdTimestampNs = getWallClockNs();
- mElapsedTimestampNs = getElapsedRealtimeNs();
- mTagId = util::BINARY_PUSH_STATE_CHANGED;
- mLogUid = AIBinder_getCallingUid();
- mLogPid = AIBinder_getCallingPid();
-
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value((int)requiresStaging)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value((int)rollbackEnabled)));
- mValues.push_back(
- FieldValue(Field(mTagId, getSimpleField(5)), Value((int)requiresLowLatencyMonitor)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)), Value(state)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)), Value(experimentIds)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(8)), Value(userId)));
-}
-
-LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
- const InstallTrainInfo& trainInfo) {
- mLogdTimestampNs = wallClockTimestampNs;
- mElapsedTimestampNs = elapsedTimestampNs;
- mTagId = util::TRAIN_INFO;
-
- mValues.push_back(
- FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
- std::vector<uint8_t> experimentIdsProto;
- writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto);
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName)));
- mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status)));
-}
-
-void LogEvent::parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t value = readNextValue<int32_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int64_t value = readNextValue<int64_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numBytes = readNextValue<int32_t>();
- if ((uint32_t)numBytes > mRemainingLen) {
- mValid = false;
- return;
- }
-
- string value = string((char*)mBuf, numBytes);
- mBuf += numBytes;
- mRemainingLen -= numBytes;
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- float value = readNextValue<float>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- // cast to int32_t because FieldValue does not support bools
- int32_t value = (int32_t)readNextValue<uint8_t>();
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numBytes = readNextValue<int32_t>();
- if ((uint32_t)numBytes > mRemainingLen) {
- mValid = false;
- return;
- }
-
- vector<uint8_t> value(mBuf, mBuf + numBytes);
- mBuf += numBytes;
- mRemainingLen -= numBytes;
- addToValues(pos, depth, value, last);
- parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
- int32_t numPairs = readNextValue<uint8_t>();
-
- for (pos[1] = 1; pos[1] <= numPairs; pos[1]++) {
- last[1] = (pos[1] == numPairs);
-
- // parse key
- pos[2] = 1;
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
- // parse value
- last[2] = true;
-
- uint8_t typeInfo = readNextValue<uint8_t>();
- switch (getTypeId(typeInfo)) {
- case INT32_TYPE:
- pos[2] = 2; // pos[2] determined by index of type in KeyValuePair in atoms.proto
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case INT64_TYPE:
- pos[2] = 3;
- parseInt64(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case STRING_TYPE:
- pos[2] = 4;
- parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- case FLOAT_TYPE:
- pos[2] = 5;
- parseFloat(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- break;
- default:
- mValid = false;
- }
- }
-
- parseAnnotations(numAnnotations);
-
- pos[1] = pos[2] = 1;
- last[1] = last[2] = false;
-}
-
-void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last,
- uint8_t numAnnotations) {
- const unsigned int firstUidInChainIndex = mValues.size();
- const int32_t numNodes = readNextValue<uint8_t>();
- for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) {
- last[1] = (pos[1] == numNodes);
-
- // parse uid
- pos[2] = 1;
- parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
- // parse tag
- pos[2] = 2;
- last[2] = true;
- parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
- }
- // Check if at least one node was successfully parsed.
- if (mValues.size() - 1 > firstUidInChainIndex) {
- mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex);
- mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1);
- }
-
- parseAnnotations(numAnnotations, firstUidInChainIndex);
-
- pos[1] = pos[2] = 1;
- last[1] = last[2] = false;
-}
-
-// Assumes that mValues is not empty
-bool LogEvent::checkPreviousValueType(Type expected) {
- return mValues[mValues.size() - 1].mValue.getType() == expected;
-}
-
-void LogEvent::parseIsUidAnnotation(uint8_t annotationType) {
- if (mValues.empty() || !checkPreviousValueType(INT) || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- bool isUid = readNextValue<uint8_t>();
- if (isUid) mUidFieldIndex = static_cast<int8_t>(mValues.size() - 1);
- mValues[mValues.size() - 1].mAnnotations.setUidField(isUid);
-}
-
-void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) {
- if (!mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- mTruncateTimestamp = readNextValue<uint8_t>();
-}
-
-void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- const bool primaryField = readNextValue<uint8_t>();
- mValues[mValues.size() - 1].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType,
- int firstUidInChainIndex) {
- if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) {
- mValid = false;
- return;
- }
-
- const bool primaryField = readNextValue<uint8_t>();
- mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- const bool exclusiveState = readNextValue<uint8_t>();
- mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1);
- mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState);
-}
-
-void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != INT32_TYPE) {
- mValid = false;
- return;
- }
-
- mResetState = readNextValue<int32_t>();
-}
-
-void LogEvent::parseStateNestedAnnotation(uint8_t annotationType) {
- if (mValues.empty() || annotationType != BOOL_TYPE) {
- mValid = false;
- return;
- }
-
- bool nested = readNextValue<uint8_t>();
- mValues[mValues.size() - 1].mAnnotations.setNested(nested);
-}
-
-// firstUidInChainIndex is a default parameter that is only needed when parsing
-// annotations for attribution chains.
-void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex) {
- for (uint8_t i = 0; i < numAnnotations; i++) {
- uint8_t annotationId = readNextValue<uint8_t>();
- uint8_t annotationType = readNextValue<uint8_t>();
-
- switch (annotationId) {
- case ANNOTATION_ID_IS_UID:
- parseIsUidAnnotation(annotationType);
- break;
- case ANNOTATION_ID_TRUNCATE_TIMESTAMP:
- parseTruncateTimestampAnnotation(annotationType);
- break;
- case ANNOTATION_ID_PRIMARY_FIELD:
- parsePrimaryFieldAnnotation(annotationType);
- break;
- case ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID:
- parsePrimaryFieldFirstUidAnnotation(annotationType, firstUidInChainIndex);
- break;
- case ANNOTATION_ID_EXCLUSIVE_STATE:
- parseExclusiveStateAnnotation(annotationType);
- break;
- case ANNOTATION_ID_TRIGGER_STATE_RESET:
- parseTriggerStateResetAnnotation(annotationType);
- break;
- case ANNOTATION_ID_STATE_NESTED:
- parseStateNestedAnnotation(annotationType);
- break;
- default:
- mValid = false;
- return;
- }
- }
-}
-
-// This parsing logic is tied to the encoding scheme used in StatsEvent.java and
-// stats_event.c
-bool LogEvent::parseBuffer(uint8_t* buf, size_t len) {
- mBuf = buf;
- mRemainingLen = (uint32_t)len;
-
- int32_t pos[] = {1, 1, 1};
- bool last[] = {false, false, false};
-
- // Beginning of buffer is OBJECT_TYPE | NUM_FIELDS | TIMESTAMP | ATOM_ID
- uint8_t typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != OBJECT_TYPE) mValid = false;
-
- uint8_t numElements = readNextValue<uint8_t>();
- if (numElements < 2 || numElements > 127) mValid = false;
-
- typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != INT64_TYPE) mValid = false;
- mElapsedTimestampNs = readNextValue<int64_t>();
- numElements--;
-
- typeInfo = readNextValue<uint8_t>();
- if (getTypeId(typeInfo) != INT32_TYPE) mValid = false;
- mTagId = readNextValue<int32_t>();
- numElements--;
- parseAnnotations(getNumAnnotations(typeInfo)); // atom-level annotations
-
- for (pos[0] = 1; pos[0] <= numElements && mValid; pos[0]++) {
- last[0] = (pos[0] == numElements);
-
- typeInfo = readNextValue<uint8_t>();
- uint8_t typeId = getTypeId(typeInfo);
-
- switch (typeId) {
- case BOOL_TYPE:
- parseBool(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case INT32_TYPE:
- parseInt32(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case INT64_TYPE:
- parseInt64(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case FLOAT_TYPE:
- parseFloat(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case BYTE_ARRAY_TYPE:
- parseByteArray(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case STRING_TYPE:
- parseString(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case KEY_VALUE_PAIRS_TYPE:
- parseKeyValuePairs(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case ATTRIBUTION_CHAIN_TYPE:
- parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- break;
- case ERROR_TYPE:
- /* mErrorBitmask =*/ readNextValue<int32_t>();
- mValid = false;
- break;
- default:
- mValid = false;
- break;
- }
- }
-
- if (mRemainingLen != 0) mValid = false;
- mBuf = nullptr;
- return mValid;
-}
-
-uint8_t LogEvent::getTypeId(uint8_t typeInfo) {
- return typeInfo & 0x0F; // type id in lower 4 bytes
-}
-
-uint8_t LogEvent::getNumAnnotations(uint8_t typeInfo) {
- return (typeInfo >> 4) & 0x0F; // num annotations in upper 4 bytes
-}
-
-int64_t LogEvent::GetLong(size_t key, status_t* err) const {
- // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == LONG) {
- return value.mValue.long_value;
- } else if (value.mValue.getType() == INT) {
- return value.mValue.int_value;
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0;
-}
-
-int LogEvent::GetInt(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == INT) {
- return value.mValue.int_value;
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0;
-}
-
-const char* LogEvent::GetString(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == STRING) {
- return value.mValue.str_value.c_str();
- } else {
- *err = BAD_TYPE;
- return 0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return NULL;
-}
-
-bool LogEvent::GetBool(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == INT) {
- return value.mValue.int_value != 0;
- } else if (value.mValue.getType() == LONG) {
- return value.mValue.long_value != 0;
- } else {
- *err = BAD_TYPE;
- return false;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return false;
-}
-
-float LogEvent::GetFloat(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == FLOAT) {
- return value.mValue.float_value;
- } else {
- *err = BAD_TYPE;
- return 0.0;
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return 0.0;
-}
-
-std::vector<uint8_t> LogEvent::GetStorage(size_t key, status_t* err) const {
- int field = getSimpleField(key);
- for (const auto& value : mValues) {
- if (value.mField.getField() == field) {
- if (value.mValue.getType() == STORAGE) {
- return value.mValue.storage_value;
- } else {
- *err = BAD_TYPE;
- return vector<uint8_t>();
- }
- }
- if ((size_t)value.mField.getPosAtDepth(0) > key) {
- break;
- }
- }
-
- *err = BAD_INDEX;
- return vector<uint8_t>();
-}
-
-string LogEvent::ToString() const {
- string result;
- result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
- (long long)mElapsedTimestampNs, mTagId);
- for (const auto& value : mValues) {
- result +=
- StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
- }
- result += " }";
- return result;
-}
-
-void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
- writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
-}
-
-bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const {
- if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) {
- return false;
- }
-
- if (nullptr != indexRange) {
- indexRange->first = static_cast<int>(mAttributionChainStartIndex);
- indexRange->second = static_cast<int>(mAttributionChainEndIndex);
- }
-
- return true;
-}
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds,
- std::vector<uint8_t>* protoOut) {
- ProtoOutputStream proto;
- for (const auto& expId : experimentIds) {
- proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID,
- (long long)expId);
- }
-
- protoOut->resize(proto.size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
deleted file mode 100644
index a5f24603585a..000000000000
--- a/cmds/statsd/src/logd/LogEvent.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "FieldValue.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <private/android_logger.h>
-
-#include <string>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct InstallTrainInfo {
- int64_t trainVersionCode;
- std::string trainName;
- int32_t status;
- std::vector<int64_t> experimentIds;
- bool requiresStaging;
- bool rollbackEnabled;
- bool requiresLowLatencyMonitor;
-};
-
-/**
- * This class decodes the structured, serialized encoding of an atom into a
- * vector of FieldValues.
- */
-class LogEvent {
-public:
- /**
- * \param uid user id of the logging caller
- * \param pid process id of the logging caller
- */
- explicit LogEvent(int32_t uid, int32_t pid);
-
- /**
- * Parses the atomId, timestamp, and vector of values from a buffer
- * containing the StatsEvent/AStatsEvent encoding of an atom.
- *
- * \param buf a buffer that begins at the start of the serialized atom (it
- * should not include the android_log_header_t or the StatsEventTag)
- * \param len size of the buffer
- *
- * \return success of the initialization
- */
- bool parseBuffer(uint8_t* buf, size_t len);
-
- // Constructs a BinaryPushStateChanged LogEvent from API call.
- explicit LogEvent(const std::string& trainName, int64_t trainVersionCode, bool requiresStaging,
- bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
- const std::vector<uint8_t>& experimentIds, int32_t userId);
-
- explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
- const InstallTrainInfo& installTrainInfo);
-
- ~LogEvent() {}
-
- /**
- * Get the timestamp associated with this event.
- */
- inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; }
- inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; }
-
- /**
- * Get the tag for this event.
- */
- inline int GetTagId() const { return mTagId; }
-
- /**
- * Get the uid of the logging client.
- * Returns -1 if the uid is unknown/has not been set.
- */
- inline int32_t GetUid() const { return mLogUid; }
-
- /**
- * Get the pid of the logging client.
- * Returns -1 if the pid is unknown/has not been set.
- */
- inline int32_t GetPid() const { return mLogPid; }
-
- /**
- * Get the nth value, starting at 1.
- *
- * Returns BAD_INDEX if the index is larger than the number of elements.
- * Returns BAD_TYPE if the index is available but the data is the wrong type.
- */
- int64_t GetLong(size_t key, status_t* err) const;
- int GetInt(size_t key, status_t* err) const;
- const char* GetString(size_t key, status_t* err) const;
- bool GetBool(size_t key, status_t* err) const;
- float GetFloat(size_t key, status_t* err) const;
- std::vector<uint8_t> GetStorage(size_t key, status_t* err) const;
-
- /**
- * Return a string representation of this event.
- */
- std::string ToString() const;
-
- /**
- * Write this object to a ProtoOutputStream.
- */
- void ToProto(android::util::ProtoOutputStream& out) const;
-
- /**
- * Set elapsed timestamp if the original timestamp is missing.
- */
- void setElapsedTimestampNs(int64_t timestampNs) {
- mElapsedTimestampNs = timestampNs;
- }
-
- /**
- * Set the timestamp if the original logd timestamp is missing.
- */
- void setLogdWallClockTimestampNs(int64_t timestampNs) {
- mLogdTimestampNs = timestampNs;
- }
-
- inline int size() const {
- return mValues.size();
- }
-
- const std::vector<FieldValue>& getValues() const {
- return mValues;
- }
-
- std::vector<FieldValue>* getMutableValues() {
- return &mValues;
- }
-
- // Default value = false
- inline bool shouldTruncateTimestamp() const {
- return mTruncateTimestamp;
- }
-
- // Returns the index of the uid field within the FieldValues vector if the
- // uid exists. If there is no uid field, returns -1.
- //
- // If the index within the atom definition is desired, do the following:
- // int vectorIndex = LogEvent.getUidFieldIndex();
- // if (vectorIndex != -1) {
- // FieldValue& v = LogEvent.getValues()[vectorIndex];
- // int atomIndex = v.mField.getPosAtDepth(0);
- // }
- // Note that atomIndex is 1-indexed.
- inline int getUidFieldIndex() {
- return static_cast<int>(mUidFieldIndex);
- }
-
- // Returns whether this LogEvent has an AttributionChain.
- // If it does and indexRange is not a nullptr, populate indexRange with the start and end index
- // of the AttributionChain within mValues.
- bool hasAttributionChain(std::pair<int, int>* indexRange = nullptr) const;
-
- // Returns the index of the exclusive state field within the FieldValues vector if
- // an exclusive state exists. If there is no exclusive state field, returns -1.
- //
- // If the index within the atom definition is desired, do the following:
- // int vectorIndex = LogEvent.getExclusiveStateFieldIndex();
- // if (vectorIndex != -1) {
- // FieldValue& v = LogEvent.getValues()[vectorIndex];
- // int atomIndex = v.mField.getPosAtDepth(0);
- // }
- // Note that atomIndex is 1-indexed.
- inline int getExclusiveStateFieldIndex() const {
- return static_cast<int>(mExclusiveStateFieldIndex);
- }
-
- // If a reset state is not sent in the StatsEvent, returns -1. Note that a
- // reset state is sent if and only if a reset should be triggered.
- inline int getResetState() const {
- return mResetState;
- }
-
- inline LogEvent makeCopy() {
- return LogEvent(*this);
- }
-
- template <class T>
- status_t updateValue(size_t key, T& value, Type type) {
- int field = getSimpleField(key);
- for (auto& fieldValue : mValues) {
- if (fieldValue.mField.getField() == field) {
- if (fieldValue.mValue.getType() == type) {
- fieldValue.mValue = Value(value);
- return OK;
- } else {
- return BAD_TYPE;
- }
- }
- }
- return BAD_INDEX;
- }
-
- bool isValid() const {
- return mValid;
- }
-
-private:
- /**
- * Only use this if copy is absolutely needed.
- */
- LogEvent(const LogEvent&) = default;
-
- void parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
- void parseAttributionChain(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-
- void parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex = -1);
- void parseIsUidAnnotation(uint8_t annotationType);
- void parseTruncateTimestampAnnotation(uint8_t annotationType);
- void parsePrimaryFieldAnnotation(uint8_t annotationType);
- void parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, int firstUidInChainIndex);
- void parseExclusiveStateAnnotation(uint8_t annotationType);
- void parseTriggerStateResetAnnotation(uint8_t annotationType);
- void parseStateNestedAnnotation(uint8_t annotationType);
- bool checkPreviousValueType(Type expected);
-
- /**
- * The below two variables are only valid during the execution of
- * parseBuffer. There are no guarantees about the state of these variables
- * before/after.
- */
- uint8_t* mBuf;
- uint32_t mRemainingLen; // number of valid bytes left in the buffer being parsed
-
- bool mValid = true; // stores whether the event we received from the socket is valid
-
- /**
- * Side-effects:
- * If there is enough space in buffer to read value of type T
- * - move mBuf past the value that was just read
- * - decrement mRemainingLen by size of T
- * Else
- * - set mValid to false
- */
- template <class T>
- T readNextValue() {
- T value;
- if (mRemainingLen < sizeof(T)) {
- mValid = false;
- value = 0; // all primitive types can successfully cast 0
- } else {
- // When alignof(T) == 1, hopefully the compiler can optimize away
- // this conditional as always true.
- if ((reinterpret_cast<uintptr_t>(mBuf) % alignof(T)) == 0) {
- // We're properly aligned, and can safely make this assignment.
- value = *((T*)mBuf);
- } else {
- // We need to use memcpy. It's slower, but safe.
- memcpy(&value, mBuf, sizeof(T));
- }
- mBuf += sizeof(T);
- mRemainingLen -= sizeof(T);
- }
- return value;
- }
-
- template <class T>
- void addToValues(int32_t* pos, int32_t depth, T& value, bool* last) {
- Field f = Field(mTagId, pos, depth);
- // do not decorate last position at depth 0
- for (int i = 1; i < depth; i++) {
- if (last[i]) f.decorateLastPos(i);
- }
-
- Value v = Value(value);
- mValues.push_back(FieldValue(f, v));
- }
-
- uint8_t getTypeId(uint8_t typeInfo);
- uint8_t getNumAnnotations(uint8_t typeInfo);
-
- // The items are naturally sorted in DFS order as we read them. this allows us to do fast
- // matching.
- std::vector<FieldValue> mValues;
-
- // The timestamp set by the logd.
- int64_t mLogdTimestampNs;
-
- // The elapsed timestamp set by statsd log writer.
- int64_t mElapsedTimestampNs;
-
- // The atom tag of the event (defaults to 0 if client does not
- // appropriately set the atom id).
- int mTagId = 0;
-
- // The uid of the logging client (defaults to -1).
- int32_t mLogUid = -1;
-
- // The pid of the logging client (defaults to -1).
- int32_t mLogPid = -1;
-
- // Annotations
- bool mTruncateTimestamp = false;
- int mResetState = -1;
-
- // Indexes within the FieldValue vector can be stored in 7 bits because
- // that's the assumption enforced by the encoding used in FieldValue.
- int8_t mUidFieldIndex = -1;
- int8_t mAttributionChainStartIndex = -1;
- int8_t mAttributionChainEndIndex = -1;
- int8_t mExclusiveStateFieldIndex = -1;
-};
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.cpp b/cmds/statsd/src/logd/LogEventQueue.cpp
deleted file mode 100644
index 146464bbe774..000000000000
--- a/cmds/statsd/src/logd/LogEventQueue.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "LogEventQueue.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unique_lock;
-using std::unique_ptr;
-
-unique_ptr<LogEvent> LogEventQueue::waitPop() {
- std::unique_lock<std::mutex> lock(mMutex);
-
- if (mQueue.empty()) {
- mCondition.wait(lock, [this] { return !this->mQueue.empty(); });
- }
-
- unique_ptr<LogEvent> item = std::move(mQueue.front());
- mQueue.pop();
-
- return item;
-}
-
-bool LogEventQueue::push(unique_ptr<LogEvent> item, int64_t* oldestTimestampNs) {
- bool success;
- {
- std::unique_lock<std::mutex> lock(mMutex);
- if (mQueue.size() < mQueueLimit) {
- mQueue.push(std::move(item));
- success = true;
- } else {
- // safe operation as queue must not be empty.
- *oldestTimestampNs = mQueue.front()->GetElapsedTimestampNs();
- success = false;
- }
- }
-
- mCondition.notify_one();
- return success;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.h b/cmds/statsd/src/logd/LogEventQueue.h
deleted file mode 100644
index 9dda3d24c571..000000000000
--- a/cmds/statsd/src/logd/LogEventQueue.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "LogEvent.h"
-
-#include <condition_variable>
-#include <mutex>
-#include <queue>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * A zero copy thread safe queue buffer for producing and consuming LogEvent.
- */
-class LogEventQueue {
-public:
- explicit LogEventQueue(size_t maxSize) : mQueueLimit(maxSize){};
-
- /**
- * Blocking read one event from the queue.
- */
- std::unique_ptr<LogEvent> waitPop();
-
- /**
- * Puts a LogEvent ptr to the end of the queue.
- * Returns false on failure when the queue is full, and output the oldest event timestamp
- * in the queue.
- */
- bool push(std::unique_ptr<LogEvent> event, int64_t* oldestTimestampNs);
-
-private:
- const size_t mQueueLimit;
- std::condition_variable mCondition;
- std::mutex mMutex;
- std::queue<std::unique_ptr<LogEvent>> mQueue;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
deleted file mode 100644
index 03b178a989eb..000000000000
--- a/cmds/statsd/src/main.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsService.h"
-#include "socket/StatsSocketListener.h"
-
-#include <android/binder_interface_utils.h>
-#include <android/binder_process.h>
-#include <android/binder_manager.h>
-#include <utils/Looper.h>
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-using namespace android;
-using namespace android::os::statsd;
-using ::ndk::SharedRefBase;
-using std::shared_ptr;
-using std::make_shared;
-
-shared_ptr<StatsService> gStatsService = nullptr;
-sp<StatsSocketListener> gSocketListener = nullptr;
-
-void signalHandler(int sig) {
- if (sig == SIGPIPE) {
- // ShellSubscriber uses SIGPIPE as a signal to detect the end of the
- // client process. Don't prematurely exit(1) here. Instead, ignore the
- // signal and allow the write call to return EPIPE.
- ALOGI("statsd received SIGPIPE. Ignoring signal.");
- return;
- }
-
- if (gSocketListener != nullptr) gSocketListener->stopListener();
- if (gStatsService != nullptr) gStatsService->Terminate();
- ALOGW("statsd terminated on receiving signal %d.", sig);
- exit(1);
-}
-
-void registerSignalHandlers()
-{
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = signalHandler;
- sigaction(SIGPIPE, &sa, nullptr);
- sigaction(SIGHUP, &sa, nullptr);
- sigaction(SIGINT, &sa, nullptr);
- sigaction(SIGQUIT, &sa, nullptr);
- sigaction(SIGTERM, &sa, nullptr);
-}
-
-int main(int /*argc*/, char** /*argv*/) {
- // Set up the looper
- sp<Looper> looper(Looper::prepare(0 /* opts */));
-
- // Set up the binder
- ABinderProcess_setThreadPoolMaxThreadCount(9);
- ABinderProcess_startThreadPool();
-
- std::shared_ptr<LogEventQueue> eventQueue =
- std::make_shared<LogEventQueue>(4000 /*buffer limit. Buffer is NOT pre-allocated*/);
-
- // Create the service
- gStatsService = SharedRefBase::make<StatsService>(looper, eventQueue);
- // TODO(b/149582373): Set DUMP_FLAG_PROTO once libbinder_ndk supports
- // setting dumpsys priorities.
- binder_status_t status = AServiceManager_addService(gStatsService->asBinder().get(), "stats");
- if (status != STATUS_OK) {
- ALOGE("Failed to add service as AIDL service");
- return -1;
- }
-
- registerSignalHandlers();
-
- gStatsService->sayHiToStatsCompanion();
-
- gStatsService->Startup();
-
- gSocketListener = new StatsSocketListener(eventQueue);
-
- ALOGI("Statsd starts to listen to socket.");
- // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
- if (gSocketListener->startListener(600)) {
- exit(1);
- }
-
- // Loop forever -- the reports run on this thread in a handler, and the
- // binder calls remain responsive in their pool of one thread.
- while (true) {
- looper->pollAll(-1 /* timeoutMillis */);
- }
- ALOGW("statsd escaped from its loop.");
-
- return 1;
-}
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
deleted file mode 100644
index b94a9572113e..000000000000
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Log.h"
-
-#include "CombinationLogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-CombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index)
- : LogMatchingTracker(id, index) {
-}
-
-CombinationLogMatchingTracker::~CombinationLogMatchingTracker() {
-}
-
-bool CombinationLogMatchingTracker::init(const vector<AtomMatcher>& allLogMatchers,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- const unordered_map<int64_t, int>& matcherMap,
- vector<bool>& stack) {
- if (mInitialized) {
- return true;
- }
-
- // mark this node as visited in the recursion stack.
- stack[mIndex] = true;
-
- AtomMatcher_Combination matcher = allLogMatchers[mIndex].combination();
-
- // LogicalOperation is missing in the config
- if (!matcher.has_operation()) {
- return false;
- }
-
- mLogicalOperation = matcher.operation();
-
- if (mLogicalOperation == LogicalOperation::NOT && matcher.matcher_size() != 1) {
- return false;
- }
-
- for (const auto& child : matcher.matcher()) {
- auto pair = matcherMap.find(child);
- if (pair == matcherMap.end()) {
- ALOGW("Matcher %lld not found in the config", (long long)child);
- return false;
- }
-
- int childIndex = pair->second;
-
- // if the child is a visited node in the recursion -> circle detected.
- if (stack[childIndex]) {
- ALOGE("Circle detected in matcher config");
- return false;
- }
-
- if (!allTrackers[childIndex]->init(allLogMatchers, allTrackers, matcherMap, stack)) {
- ALOGW("child matcher init failed %lld", (long long)child);
- return false;
- }
-
- mChildren.push_back(childIndex);
-
- const set<int>& childTagIds = allTrackers[childIndex]->getAtomIds();
- mAtomIds.insert(childTagIds.begin(), childTagIds.end());
- }
-
- mInitialized = true;
- // unmark this node in the recursion stack.
- stack[mIndex] = false;
- return true;
-}
-
-void CombinationLogMatchingTracker::onLogEvent(const LogEvent& event,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- vector<MatchingState>& matcherResults) {
- // this event has been processed.
- if (matcherResults[mIndex] != MatchingState::kNotComputed) {
- return;
- }
-
- if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) {
- matcherResults[mIndex] = MatchingState::kNotMatched;
- return;
- }
-
- // evaluate children matchers if they haven't been evaluated.
- for (const int childIndex : mChildren) {
- if (matcherResults[childIndex] == MatchingState::kNotComputed) {
- const sp<LogMatchingTracker>& child = allTrackers[childIndex];
- child->onLogEvent(event, allTrackers, matcherResults);
- }
- }
-
- bool matched = combinationMatch(mChildren, mLogicalOperation, matcherResults);
- matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
deleted file mode 100644
index 55bc46059fc1..000000000000
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef COMBINATION_LOG_MATCHING_TRACKER_H
-#define COMBINATION_LOG_MATCHING_TRACKER_H
-
-#include <unordered_map>
-#include <vector>
-#include "LogMatchingTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Represents a AtomMatcher_Combination in the StatsdConfig.
-class CombinationLogMatchingTracker : public virtual LogMatchingTracker {
-public:
- CombinationLogMatchingTracker(const int64_t& id, const int index);
-
- bool init(const std::vector<AtomMatcher>& allLogMatchers,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- const std::unordered_map<int64_t, int>& matcherMap,
- std::vector<bool>& stack);
-
- ~CombinationLogMatchingTracker();
-
- void onLogEvent(const LogEvent& event,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- std::vector<MatchingState>& matcherResults) override;
-
-private:
- LogicalOperation mLogicalOperation;
-
- std::vector<int> mChildren;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // COMBINATION_LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.cpp b/cmds/statsd/src/matchers/EventMatcherWizard.cpp
deleted file mode 100644
index 025c9a87b16b..000000000000
--- a/cmds/statsd/src/matchers/EventMatcherWizard.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "EventMatcherWizard.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-MatchingState EventMatcherWizard::matchLogEvent(const LogEvent& event, int matcher_index) {
- if (matcher_index < 0 || matcher_index >= (int)mAllEventMatchers.size()) {
- return MatchingState::kNotComputed;
- }
- vector<MatchingState> matcherCache(mAllEventMatchers.size(), MatchingState::kNotComputed);
- mAllEventMatchers[matcher_index]->onLogEvent(event, mAllEventMatchers, matcherCache);
- return matcherCache[matcher_index];
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.h b/cmds/statsd/src/matchers/EventMatcherWizard.h
deleted file mode 100644
index 57ec2b35ba32..000000000000
--- a/cmds/statsd/src/matchers/EventMatcherWizard.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "LogMatchingTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class EventMatcherWizard : public virtual android::RefBase {
-public:
- EventMatcherWizard(){}; // for testing
- EventMatcherWizard(const std::vector<sp<LogMatchingTracker>>& eventTrackers)
- : mAllEventMatchers(eventTrackers){};
-
- virtual ~EventMatcherWizard(){};
-
- MatchingState matchLogEvent(const LogEvent& event, int matcher_index);
-
-private:
- std::vector<sp<LogMatchingTracker>> mAllEventMatchers;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
deleted file mode 100644
index 88ab4e6f683a..000000000000
--- a/cmds/statsd/src/matchers/LogMatchingTracker.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LOG_MATCHING_TRACKER_H
-#define LOG_MATCHING_TRACKER_H
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "logd/LogEvent.h"
-#include "matchers/matcher_util.h"
-
-#include <utils/RefBase.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class LogMatchingTracker : public virtual RefBase {
-public:
- LogMatchingTracker(const int64_t& id, const int index)
- : mId(id), mIndex(index), mInitialized(false){};
-
- virtual ~LogMatchingTracker(){};
-
- // Initialize this LogMatchingTracker.
- // allLogMatchers: the list of the AtomMatcher proto config. This is needed because we don't
- // store the proto object in memory. We only need it during initilization.
- // allTrackers: the list of the LogMatchingTracker objects. It's a one-to-one mapping with
- // allLogMatchers. This is needed because the initialization is done recursively
- // for CombinationLogMatchingTrackers using DFS.
- // stack: a bit map to record which matcher has been visited on the stack. This is for detecting
- // circle dependency.
- virtual bool init(const std::vector<AtomMatcher>& allLogMatchers,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- const std::unordered_map<int64_t, int>& matcherMap,
- std::vector<bool>& stack) = 0;
-
- // Called when a log event comes.
- // event: the log event.
- // allTrackers: the list of all LogMatchingTrackers. This is needed because the log processing
- // is done recursively.
- // matcherResults: The cached results for all matchers for this event. Parent matchers can
- // directly access the children's matching results if they have been evaluated.
- // Otherwise, call children matchers' onLogEvent.
- virtual void onLogEvent(const LogEvent& event,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- std::vector<MatchingState>& matcherResults) = 0;
-
- // Get the tagIds that this matcher cares about. The combined collection is stored
- // in MetricMananger, so that we can pass any LogEvents that are not interest of us. It uses
- // some memory but hopefully it can save us much CPU time when there is flood of events.
- virtual const std::set<int>& getAtomIds() const {
- return mAtomIds;
- }
-
- const int64_t& getId() const {
- return mId;
- }
-
-protected:
- // Name of this matching. We don't really need the name, but it makes log message easy to debug.
- const int64_t mId;
-
- // Index of this LogMatchingTracker in MetricsManager's container.
- const int mIndex;
-
- // Whether this LogMatchingTracker has been properly initialized.
- bool mInitialized;
-
- // The collection of the event tag ids that this LogMatchingTracker cares. So we can quickly
- // return kNotMatched when we receive an event with an id not in the list. This is especially
- // useful when we have a complex CombinationLogMatcherTracker.
- std::set<int> mAtomIds;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
deleted file mode 100644
index 082daf5a1916..000000000000
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "SimpleLogMatchingTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-using std::vector;
-
-
-SimpleLogMatchingTracker::SimpleLogMatchingTracker(const int64_t& id, const int index,
- const SimpleAtomMatcher& matcher,
- const UidMap& uidMap)
- : LogMatchingTracker(id, index), mMatcher(matcher), mUidMap(uidMap) {
- if (!matcher.has_atom_id()) {
- mInitialized = false;
- } else {
- mAtomIds.insert(matcher.atom_id());
- mInitialized = true;
- }
-}
-
-SimpleLogMatchingTracker::~SimpleLogMatchingTracker() {
-}
-
-bool SimpleLogMatchingTracker::init(const vector<AtomMatcher>& allLogMatchers,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- const unordered_map<int64_t, int>& matcherMap,
- vector<bool>& stack) {
- // no need to do anything.
- return mInitialized;
-}
-
-void SimpleLogMatchingTracker::onLogEvent(const LogEvent& event,
- const vector<sp<LogMatchingTracker>>& allTrackers,
- vector<MatchingState>& matcherResults) {
- if (matcherResults[mIndex] != MatchingState::kNotComputed) {
- VLOG("Matcher %lld already evaluated ", (long long)mId);
- return;
- }
-
- if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) {
- matcherResults[mIndex] = MatchingState::kNotMatched;
- return;
- }
-
- bool matched = matchesSimple(mUidMap, mMatcher, event);
- matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
- VLOG("Stats SimpleLogMatcher %lld matched? %d", (long long)mId, matched);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
deleted file mode 100644
index a0f6a888bd44..000000000000
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SIMPLE_LOG_MATCHING_TRACKER_H
-#define SIMPLE_LOG_MATCHING_TRACKER_H
-
-#include <unordered_map>
-#include <vector>
-#include "LogMatchingTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class SimpleLogMatchingTracker : public virtual LogMatchingTracker {
-public:
- SimpleLogMatchingTracker(const int64_t& id, const int index,
- const SimpleAtomMatcher& matcher,
- const UidMap& uidMap);
-
- ~SimpleLogMatchingTracker();
-
- bool init(const std::vector<AtomMatcher>& allLogMatchers,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- const std::unordered_map<int64_t, int>& matcherMap,
- std::vector<bool>& stack) override;
-
- void onLogEvent(const LogEvent& event,
- const std::vector<sp<LogMatchingTracker>>& allTrackers,
- std::vector<MatchingState>& matcherResults) override;
-
-private:
- const SimpleAtomMatcher mMatcher;
- const UidMap& mUidMap;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // SIMPLE_LOG_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
deleted file mode 100644
index 2b4c6a3cbf1e..000000000000
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/LogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
- const vector<MatchingState>& matcherResults) {
- bool matched;
- switch (operation) {
- case LogicalOperation::AND: {
- matched = true;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] != MatchingState::kMatched) {
- matched = false;
- break;
- }
- }
- break;
- }
- case LogicalOperation::OR: {
- matched = false;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] == MatchingState::kMatched) {
- matched = true;
- break;
- }
- }
- break;
- }
- case LogicalOperation::NOT:
- matched = matcherResults[children[0]] == MatchingState::kNotMatched;
- break;
- case LogicalOperation::NAND:
- matched = false;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] != MatchingState::kMatched) {
- matched = true;
- break;
- }
- }
- break;
- case LogicalOperation::NOR:
- matched = true;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] == MatchingState::kMatched) {
- matched = false;
- break;
- }
- }
- break;
- case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
- matched = false;
- break;
- }
- return matched;
-}
-
-bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const string& str_match) {
- if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
- int uid = fieldValue.mValue.int_value;
- auto aidIt = UidMap::sAidToUidMapping.find(str_match);
- if (aidIt != UidMap::sAidToUidMapping.end()) {
- return ((int)aidIt->second) == uid;
- }
- std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
- return packageNames.find(str_match) != packageNames.end();
- } else if (fieldValue.mValue.getType() == STRING) {
- return fieldValue.mValue.str_value == str_match;
- }
- return false;
-}
-
-bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
- const vector<FieldValue>& values, int start, int end, int depth) {
- if (depth > 2) {
- ALOGE("Depth > 3 not supported");
- return false;
- }
-
- if (start >= end) {
- return false;
- }
-
- // Filter by entry field first
- int newStart = -1;
- int newEnd = end;
- // because the fields are naturally sorted in the DFS order. we can safely
- // break when pos is larger than the one we are searching for.
- for (int i = start; i < end; i++) {
- int pos = values[i].mField.getPosAtDepth(depth);
- if (pos == matcher.field()) {
- if (newStart == -1) {
- newStart = i;
- }
- newEnd = i + 1;
- } else if (pos > matcher.field()) {
- break;
- }
- }
-
- // Now we have zoomed in to a new range
- start = newStart;
- end = newEnd;
-
- if (start == -1) {
- // No such field found.
- return false;
- }
-
- vector<pair<int, int>> ranges; // the ranges are for matching ANY position
- if (matcher.has_position()) {
- // Repeated fields position is stored as a node in the path.
- depth++;
- if (depth > 2) {
- return false;
- }
- switch (matcher.position()) {
- case Position::FIRST: {
- for (int i = start; i < end; i++) {
- int pos = values[i].mField.getPosAtDepth(depth);
- if (pos != 1) {
- // Again, the log elements are stored in sorted order. so
- // once the position is > 1, we break;
- end = i;
- break;
- }
- }
- ranges.push_back(std::make_pair(start, end));
- break;
- }
- case Position::LAST: {
- // move the starting index to the first LAST field at the depth.
- for (int i = start; i < end; i++) {
- if (values[i].mField.isLastPos(depth)) {
- start = i;
- break;
- }
- }
- ranges.push_back(std::make_pair(start, end));
- break;
- }
- case Position::ANY: {
- // ANY means all the children matchers match in any of the sub trees, it's a match
- newStart = start;
- newEnd = end;
- // Here start is guaranteed to be a valid index.
- int currentPos = values[start].mField.getPosAtDepth(depth);
- // Now find all sub trees ranges.
- for (int i = start; i < end; i++) {
- int newPos = values[i].mField.getPosAtDepth(depth);
- if (newPos != currentPos) {
- ranges.push_back(std::make_pair(newStart, i));
- newStart = i;
- currentPos = newPos;
- }
- }
- ranges.push_back(std::make_pair(newStart, end));
- break;
- }
- case Position::ALL:
- ALOGE("Not supported: field matcher with ALL position.");
- break;
- case Position::POSITION_UNKNOWN:
- break;
- }
- } else {
- // No position
- ranges.push_back(std::make_pair(start, end));
- }
- // start and end are still pointing to the matched range.
- switch (matcher.value_matcher_case()) {
- case FieldValueMatcher::kMatchesTuple: {
- ++depth;
- // If any range matches all matchers, good.
- for (const auto& range : ranges) {
- bool matched = true;
- for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
- if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
- depth)) {
- matched = false;
- break;
- }
- }
- if (matched) return true;
- }
- return false;
- }
- // Finally, we get to the point of real value matching.
- // If the field matcher ends with ANY, then we have [start, end) range > 1.
- // In the following, we should return true, when ANY of the values matches.
- case FieldValueMatcher::ValueMatcherCase::kEqBool: {
- for (int i = start; i < end; i++) {
- if ((values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
- (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqString: {
- for (int i = start; i < end; i++) {
- if (tryMatchString(uidMap, values[i], matcher.eq_string())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
- const auto& str_list = matcher.neq_any_string();
- for (int i = start; i < end; i++) {
- bool notEqAll = true;
- for (const auto& str : str_list.str_value()) {
- if (tryMatchString(uidMap, values[i], str)) {
- notEqAll = false;
- break;
- }
- }
- if (notEqAll) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
- const auto& str_list = matcher.eq_any_string();
- for (int i = start; i < end; i++) {
- for (const auto& str : str_list.str_value()) {
- if (tryMatchString(uidMap, values[i], str)) {
- return true;
- }
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (matcher.eq_int() == values[i].mValue.int_value)) {
- return true;
- }
- // eq_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (matcher.eq_int() == values[i].mValue.long_value)) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value < matcher.lt_int())) {
- return true;
- }
- // lt_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value < matcher.lt_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value > matcher.gt_int())) {
- return true;
- }
- // gt_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value > matcher.gt_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == FLOAT &&
- (values[i].mValue.float_value < matcher.lt_float())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == FLOAT &&
- (values[i].mValue.float_value > matcher.gt_float())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLteInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value <= matcher.lte_int())) {
- return true;
- }
- // lte_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value <= matcher.lte_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGteInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value >= matcher.gte_int())) {
- return true;
- }
- // gte_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value >= matcher.gte_int())) {
- return true;
- }
- }
- return false;
- }
- default:
- return false;
- }
-}
-
-bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
- const LogEvent& event) {
- if (event.GetTagId() != simpleMatcher.atom_id()) {
- return false;
- }
-
- for (const auto& matcher : simpleMatcher.field_value_matcher()) {
- if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
- return false;
- }
- }
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
deleted file mode 100644
index 1ab3e87b5fed..000000000000
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "logd/LogEvent.h"
-
-#include <vector>
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "packages/UidMap.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum MatchingState {
- kNotComputed = -1,
- kNotMatched = 0,
- kMatched = 1,
-};
-
-bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
- const std::vector<MatchingState>& matcherResults);
-
-bool matchesSimple(const UidMap& uidMap,
- const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metadata_util.cpp b/cmds/statsd/src/metadata_util.cpp
deleted file mode 100644
index 27ee59b36242..000000000000
--- a/cmds/statsd/src/metadata_util.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "FieldValue.h"
-#include "metadata_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using google::protobuf::RepeatedPtrField;
-
-void writeValueToProto(metadata::FieldValue* metadataFieldValue, const Value& value) {
- std::string storage_value;
- switch (value.getType()) {
- case INT:
- metadataFieldValue->set_value_int(value.int_value);
- break;
- case LONG:
- metadataFieldValue->set_value_long(value.long_value);
- break;
- case FLOAT:
- metadataFieldValue->set_value_float(value.float_value);
- break;
- case DOUBLE:
- metadataFieldValue->set_value_double(value.double_value);
- break;
- case STRING:
- metadataFieldValue->set_value_str(value.str_value.c_str());
- break;
- case STORAGE: // byte array
- storage_value = ((char*) value.storage_value.data());
- metadataFieldValue->set_value_storage(storage_value);
- break;
- default:
- break;
- }
-}
-
-void writeMetricDimensionKeyToMetadataDimensionKey(
- const MetricDimensionKey& metricKey,
- metadata::MetricDimensionKey* metadataMetricKey) {
- for (const FieldValue& fieldValue : metricKey.getDimensionKeyInWhat().getValues()) {
- metadata::FieldValue* metadataFieldValue = metadataMetricKey->add_dimension_key_in_what();
- metadata::Field* metadataField = metadataFieldValue->mutable_field();
- metadataField->set_tag(fieldValue.mField.getTag());
- metadataField->set_field(fieldValue.mField.getField());
- writeValueToProto(metadataFieldValue, fieldValue.mValue);
- }
-
- for (const FieldValue& fieldValue : metricKey.getStateValuesKey().getValues()) {
- metadata::FieldValue* metadataFieldValue = metadataMetricKey->add_state_values_key();
- metadata::Field* metadataField = metadataFieldValue->mutable_field();
- metadataField->set_tag(fieldValue.mField.getTag());
- metadataField->set_field(fieldValue.mField.getField());
- writeValueToProto(metadataFieldValue, fieldValue.mValue);
- }
-}
-
-void writeFieldValuesFromMetadata(
- const RepeatedPtrField<metadata::FieldValue>& repeatedFieldValueList,
- std::vector<FieldValue>* fieldValues) {
- for (const metadata::FieldValue& metadataFieldValue : repeatedFieldValueList) {
- Field field(metadataFieldValue.field().tag(), metadataFieldValue.field().field());
- Value value;
- switch (metadataFieldValue.value_case()) {
- case metadata::FieldValue::ValueCase::kValueInt:
- value = Value(metadataFieldValue.value_int());
- break;
- case metadata::FieldValue::ValueCase::kValueLong:
- value = Value(metadataFieldValue.value_long());
- break;
- case metadata::FieldValue::ValueCase::kValueFloat:
- value = Value(metadataFieldValue.value_float());
- break;
- case metadata::FieldValue::ValueCase::kValueDouble:
- value = Value(metadataFieldValue.value_double());
- break;
- case metadata::FieldValue::ValueCase::kValueStr:
- value = Value(metadataFieldValue.value_str());
- break;
- case metadata::FieldValue::ValueCase::kValueStorage:
- value = Value(metadataFieldValue.value_storage());
- break;
- default:
- break;
- }
- FieldValue fieldValue(field, value);
- fieldValues->emplace_back(field, value);
- }
-}
-
-MetricDimensionKey loadMetricDimensionKeyFromProto(
- const metadata::MetricDimensionKey& metricDimensionKey) {
- std::vector<FieldValue> dimKeyInWhatFieldValues;
- writeFieldValuesFromMetadata(metricDimensionKey.dimension_key_in_what(),
- &dimKeyInWhatFieldValues);
- std::vector<FieldValue> stateValuesFieldValues;
- writeFieldValuesFromMetadata(metricDimensionKey.state_values_key(), &stateValuesFieldValues);
-
- HashableDimensionKey dimKeyInWhat(dimKeyInWhatFieldValues);
- HashableDimensionKey stateValues(stateValuesFieldValues);
- MetricDimensionKey metricKey(dimKeyInWhat, stateValues);
- return metricKey;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/src/metadata_util.h b/cmds/statsd/src/metadata_util.h
deleted file mode 100644
index 84a39ff872b5..000000000000
--- a/cmds/statsd/src/metadata_util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "HashableDimensionKey.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h" // AlertMetadata
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void writeMetricDimensionKeyToMetadataDimensionKey(const MetricDimensionKey& metricKey,
- metadata::MetricDimensionKey* metadataMetricKey);
-
-MetricDimensionKey loadMetricDimensionKeyFromProto(
- const metadata::MetricDimensionKey& metricDimensionKey);
-
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
deleted file mode 100644
index 573961276e5b..000000000000
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "CountMetricProducer.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_COUNT_METRICS = 5;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-
-// for CountMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for CountMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-// for CountBucketInfo
-const int FIELD_ID_COUNT = 3;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-
-CountMetricProducer::CountMetricProducer(
- const ConfigKey& key, const CountMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
- if (metric.has_bucket()) {
- mBucketSizeNs =
- TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
- } else {
- mBucketSizeNs = LLONG_MAX;
- }
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- }
-
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
-
- for (const auto& stateLink : metric.state_link()) {
- Metric2State ms;
- ms.stateAtomId = stateLink.state_atom_id();
- translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
- translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
- }
-
- flushIfNeededLocked(startTimeNs);
- // Adjust start for partial bucket
- mCurrentBucketStartTimeNs = startTimeNs;
-
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-CountMetricProducer::~CountMetricProducer() {
- VLOG("~CountMetricProducer() called");
-}
-
-void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) {
- VLOG("CountMetric %lld onStateChanged time %lld, State%d, key %s, %d -> %d",
- (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
- oldState.mValue.int_value, newState.mValue.int_value);
-}
-
-void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedCounter == nullptr ||
- mCurrentSlicedCounter->size() == 0) {
- return;
- }
-
- fprintf(out, "CountMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedCounter->size());
- if (verbose) {
- for (const auto& it : *mCurrentSlicedCounter) {
- fprintf(out, "\t(what)%s\t(state)%s %lld\n",
- it.first.getDimensionKeyInWhat().toString().c_str(),
- it.first.getStateValuesKey().toString().c_str(), (unsigned long long)it.second);
- }
- }
-}
-
-void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-}
-
-
-void CountMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- mPastBuckets.clear();
-}
-
-void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (include_current_partial_bucket) {
- flushLocked(dumpTimeNs);
- } else {
- flushIfNeededLocked(dumpTimeNs);
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
-
- if (mPastBuckets.empty()) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
- // Fills the dimension path if not slicing by ALL.
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS);
-
- for (const auto& counter : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = counter.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
-
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
- // Then fill slice_by_state.
- for (auto state : dimensionKey.getStateValuesKey().getValues()) {
- uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SLICE_BY_STATE);
- writeStateToProto(state, protoOutput);
- protoOutput->end(stateToken);
- }
- // Then fill bucket_info (CountBucketInfo).
- for (const auto& bucket : counter.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
- // Partial bucket.
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_COUNT, (long long)bucket.mCount);
- protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] count: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (long long)bucket.mCount);
- }
- protoOutput->end(wrapperToken);
- }
-
- protoOutput->end(protoToken);
-
- if (erase_data) {
- mPastBuckets.clear();
- }
-}
-
-void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- flushIfNeededLocked(dropTimeNs);
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
- mPastBuckets.clear();
-}
-
-void CountMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-}
-
-bool CountMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- if (mCurrentSlicedCounter->find(newKey) != mCurrentSlicedCounter->end()) {
- return false;
- }
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedCounter->size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedCounter->size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("CountMetric %lld dropping data for dimension key %s",
- (long long)mMetricId, newKey.toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
-
- return false;
-}
-
-void CountMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- flushIfNeededLocked(eventTimeNs);
-
- if (!condition) {
- return;
- }
-
- auto it = mCurrentSlicedCounter->find(eventKey);
- if (it == mCurrentSlicedCounter->end()) {
- // ===========GuardRail==============
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
- // create a counter for the new key
- (*mCurrentSlicedCounter)[eventKey] = 1;
- } else {
- // increment the existing value
- auto& count = it->second;
- count++;
- }
- for (auto& tracker : mAnomalyTrackers) {
- int64_t countWholeBucket = mCurrentSlicedCounter->find(eventKey)->second;
- auto prev = mCurrentFullCounters->find(eventKey);
- if (prev != mCurrentFullCounters->end()) {
- countWholeBucket += prev->second;
- }
- tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId, eventKey,
- countWholeBucket);
- }
-
- VLOG("metric %lld %s->%lld", (long long)mMetricId, eventKey.toString().c_str(),
- (long long)(*mCurrentSlicedCounter)[eventKey]);
-}
-
-// When a new matched event comes in, we check if event falls into the current
-// bucket. If not, flush the old counter to past buckets and initialize the new bucket.
-void CountMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
- if (eventTimeNs < currentBucketEndTimeNs) {
- return;
- }
-
- // Setup the bucket start time and number.
- int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
- int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
- mCurrentBucketNum += numBucketsForward;
- VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
- (long long)mCurrentBucketStartTimeNs);
-}
-
-void CountMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- CountBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- if (eventTimeNs < fullBucketEndTimeNs) {
- info.mBucketEndNs = eventTimeNs;
- } else {
- info.mBucketEndNs = fullBucketEndTimeNs;
- }
- for (const auto& counter : *mCurrentSlicedCounter) {
- info.mCount = counter.second;
- auto& bucketList = mPastBuckets[counter.first];
- bucketList.push_back(info);
- VLOG("metric %lld, dump key value: %s -> %lld", (long long)mMetricId,
- counter.first.toString().c_str(),
- (long long)counter.second);
- }
-
- // If we have finished a full bucket, then send this to anomaly tracker.
- if (eventTimeNs > fullBucketEndTimeNs) {
- // Accumulate partial buckets with current value and then send to anomaly tracker.
- if (mCurrentFullCounters->size() > 0) {
- for (const auto& keyValuePair : *mCurrentSlicedCounter) {
- (*mCurrentFullCounters)[keyValuePair.first] += keyValuePair.second;
- }
- for (auto& tracker : mAnomalyTrackers) {
- tracker->addPastBucket(mCurrentFullCounters, mCurrentBucketNum);
- }
- mCurrentFullCounters = std::make_shared<DimToValMap>();
- } else {
- // Skip aggregating the partial buckets since there's no previous partial bucket.
- for (auto& tracker : mAnomalyTrackers) {
- tracker->addPastBucket(mCurrentSlicedCounter, mCurrentBucketNum);
- }
- }
- } else {
- // Accumulate partial bucket.
- for (const auto& keyValuePair : *mCurrentSlicedCounter) {
- (*mCurrentFullCounters)[keyValuePair.first] += keyValuePair.second;
- }
- }
-
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- // Only resets the counters, but doesn't setup the times nor numbers.
- // (Do not clear since the old one is still referenced in mAnomalyTrackers).
- mCurrentSlicedCounter = std::make_shared<DimToValMap>();
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-}
-
-// Rough estimate of CountMetricProducer buffer stored. This number will be
-// greater than actual data size as it contains each dimension of
-// CountMetricData is duplicated.
-size_t CountMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- totalSize += pair.second.size() * kBucketSize;
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
deleted file mode 100644
index f05fb061ccc1..000000000000
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COUNT_METRIC_PRODUCER_H
-#define COUNT_METRIC_PRODUCER_H
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest_prod.h>
-
-#include <unordered_map>
-
-#include "MetricProducer.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct CountBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- int64_t mCount;
-};
-
-class CountMetricProducer : public MetricProducer {
-public:
- CountMetricProducer(
- const ConfigKey& key, const CountMetric& countMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~CountMetricProducer();
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) override;
-
-protected:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
-
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
-
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Util function to flush the old packet.
- void flushIfNeededLocked(const int64_t& newEventTime) override;
-
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
-
- // The current bucket (may be a partial bucket).
- std::shared_ptr<DimToValMap> mCurrentSlicedCounter = std::make_shared<DimToValMap>();
-
- // The sum of previous partial buckets in the current full bucket (excluding the current
- // partial bucket). This is only updated while flushing the current bucket.
- std::shared_ptr<DimToValMap> mCurrentFullCounters = std::make_shared<DimToValMap>();
-
- static const size_t kBucketSize = sizeof(CountBucket{});
-
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- FRIEND_TEST(CountMetricProducerTest, TestNonDimensionalEvents);
- FRIEND_TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition);
- FRIEND_TEST(CountMetricProducerTest, TestEventsWithSlicedCondition);
- FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
- FRIEND_TEST(CountMetricProducerTest, TestFirstBucket);
- FRIEND_TEST(CountMetricProducerTest, TestOneWeekTimeUnit);
-
- FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket);
- FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // COUNT_METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
deleted file mode 100644
index e9b043876d3d..000000000000
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-
-#include "Log.h"
-#include "DurationMetricProducer.h"
-#include "guardrail/StatsdStats.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_DURATION_METRICS = 6;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for DurationMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for DurationMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-// for DurationBucketInfo
-const int FIELD_ID_DURATION = 3;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-
-DurationMetricProducer::DurationMetricProducer(
- const ConfigKey& key, const DurationMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const size_t startIndex,
- const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
- const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap),
- mAggregationType(metric.aggregation_type()),
- mStartIndex(startIndex),
- mStopIndex(stopIndex),
- mStopAllIndex(stopAllIndex),
- mNested(nesting),
- mContainANYPositionInInternalDimensions(false) {
- if (metric.has_bucket()) {
- mBucketSizeNs =
- TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
- } else {
- mBucketSizeNs = LLONG_MAX;
- }
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- }
-
- if (internalDimensions.has_field()) {
- translateFieldMatcher(internalDimensions, &mInternalDimensions);
- mContainANYPositionInInternalDimensions = HasPositionANY(internalDimensions);
- }
- if (mContainANYPositionInInternalDimensions) {
- ALOGE("Position ANY in internal dimension not supported.");
- }
- if (mContainANYPositionInDimensionsInWhat) {
- ALOGE("Position ANY in dimension_in_what not supported.");
- }
-
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
- mUnSlicedPartCondition = ConditionState::kUnknown;
-
- for (const auto& stateLink : metric.state_link()) {
- Metric2State ms;
- ms.stateAtomId = stateLink.state_atom_id();
- translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
- translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
- }
-
- mUseWhatDimensionAsInternalDimension = equalDimensions(mDimensionsInWhat, mInternalDimensions);
- if (mWizard != nullptr && mConditionTrackerIndex >= 0 &&
- mMetric2ConditionLinks.size() == 1) {
- mHasLinksToAllConditionDimensionsInTracker = mWizard->equalOutputDimensions(
- mConditionTrackerIndex, mMetric2ConditionLinks.begin()->conditionFields);
- }
- flushIfNeededLocked(startTimeNs);
- // Adjust start for partial bucket
- mCurrentBucketStartTimeNs = startTimeNs;
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-DurationMetricProducer::~DurationMetricProducer() {
- VLOG("~DurationMetric() called");
-}
-
-sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
- const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mAggregationType == DurationMetric_AggregationType_SUM) {
- if (alert.trigger_if_sum_gt() > alert.num_buckets() * mBucketSizeNs) {
- ALOGW("invalid alert for SUM: threshold (%f) > possible recordable value (%d x %lld)",
- alert.trigger_if_sum_gt(), alert.num_buckets(), (long long)mBucketSizeNs);
- return nullptr;
- }
- }
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
- if (anomalyTracker != nullptr) {
- mAnomalyTrackers.push_back(anomalyTracker);
- }
- return anomalyTracker;
-}
-
-void DurationMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState,
- const FieldValue& newState) {
- // Check if this metric has a StateMap. If so, map the new state value to
- // the correct state group id.
- FieldValue newStateCopy = newState;
- mapStateValue(atomId, &newStateCopy);
-
- flushIfNeededLocked(eventTimeNs);
-
- // Each duration tracker is mapped to a different whatKey (a set of values from the
- // dimensionsInWhat fields). We notify all trackers iff the primaryKey field values from the
- // state change event are a subset of the tracker's whatKey field values.
- //
- // Ex. For a duration metric dimensioned on uid and tag:
- // DurationTracker1 whatKey = uid: 1001, tag: 1
- // DurationTracker2 whatKey = uid: 1002, tag 1
- //
- // If the state change primaryKey = uid: 1001, we only notify DurationTracker1 of a state
- // change.
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- if (!containsLinkedStateValues(whatIt.first, primaryKey, mMetric2StateLinks, atomId)) {
- continue;
- }
- whatIt.second->onStateChanged(eventTimeNs, atomId, newStateCopy);
- }
-}
-
-unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
- const MetricDimensionKey& eventKey) const {
- switch (mAggregationType) {
- case DurationMetric_AggregationType_SUM:
- return make_unique<OringDurationTracker>(
- mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs,
- mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
- case DurationMetric_AggregationType_MAX_SPARSE:
- return make_unique<MaxDurationTracker>(
- mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs,
- mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
- }
-}
-
-// SlicedConditionChange optimization case 1:
-// 1. If combination condition, logical operation is AND, only one sliced child predicate.
-// 2. The links covers all dimension fields in the sliced child condition predicate.
-void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
- const int64_t eventTime) {
- if (mMetric2ConditionLinks.size() != 1 ||
- !mHasLinksToAllConditionDimensionsInTracker) {
- return;
- }
-
- bool currentUnSlicedPartCondition = true;
- if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) {
- ConditionState unslicedPartState =
- mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex);
- // When the unsliced part is still false, return directly.
- if (mUnSlicedPartCondition == ConditionState::kFalse &&
- unslicedPartState == ConditionState::kFalse) {
- return;
- }
- mUnSlicedPartCondition = unslicedPartState;
- currentUnSlicedPartCondition = mUnSlicedPartCondition > 0;
- }
-
- auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex);
- auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex);
-
- // The condition change is from the unsliced predicates.
- // We need to find out the true dimensions from the sliced predicate and flip their condition
- // state based on the new unsliced condition state.
- if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
- (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
- std::set<HashableDimensionKey> trueConditionDimensions;
- mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, &trueConditionDimensions);
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- HashableDimensionKey linkedConditionDimensionKey;
- getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
- &linkedConditionDimensionKey);
- if (trueConditionDimensions.find(linkedConditionDimensionKey) !=
- trueConditionDimensions.end()) {
- whatIt.second->onConditionChanged(currentUnSlicedPartCondition, eventTime);
- }
- }
- } else {
- // Handle the condition change from the sliced predicate.
- if (currentUnSlicedPartCondition) {
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- HashableDimensionKey linkedConditionDimensionKey;
- getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
- &linkedConditionDimensionKey);
- if (dimensionsChangedToTrue->find(linkedConditionDimensionKey) !=
- dimensionsChangedToTrue->end()) {
- whatIt.second->onConditionChanged(true, eventTime);
- }
- if (dimensionsChangedToFalse->find(linkedConditionDimensionKey) !=
- dimensionsChangedToFalse->end()) {
- whatIt.second->onConditionChanged(false, eventTime);
- }
- }
- }
- }
-}
-
-void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition,
- const int64_t eventTimeNs) {
- bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
- if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker) {
- onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs);
- return;
- }
-
- // Now for each of the on-going event, check if the condition has changed for them.
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onSlicedConditionMayChange(overallCondition, eventTimeNs);
- }
-}
-
-void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTime);
-
- if (!mConditionSliced) {
- return;
- }
-
- onSlicedConditionMayChangeInternalLocked(overallCondition, eventTime);
-}
-
-void DurationMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-
- if (!mConditionSliced) {
- if (ConditionState::kTrue != mCondition) {
- return;
- }
-
- if (mIsActive) {
- flushIfNeededLocked(eventTimeNs);
- }
-
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onConditionChanged(mIsActive, eventTimeNs);
- }
- } else if (mIsActive) {
- flushIfNeededLocked(eventTimeNs);
- onSlicedConditionMayChangeInternalLocked(mIsActive, eventTimeNs);
- } else { // mConditionSliced == true && !mIsActive
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onConditionChanged(mIsActive, eventTimeNs);
- }
- }
-}
-
-void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTime);
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->onConditionChanged(conditionMet, eventTime);
- }
-}
-
-void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- flushIfNeededLocked(dropTimeNs);
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
- mPastBuckets.clear();
-}
-
-void DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- flushIfNeededLocked(dumpTimeNs);
- mPastBuckets.clear();
-}
-
-void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (include_current_partial_bucket) {
- flushLocked(dumpTimeNs);
- } else {
- flushIfNeededLocked(dumpTimeNs);
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
- if (mPastBuckets.empty()) {
- VLOG(" Duration metric, empty return");
- return;
- }
-
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
-
- VLOG("Duration metric %lld dump report now...", (long long)mMetricId);
-
- for (const auto& pair : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = pair.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
-
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
- // Then fill slice_by_state.
- for (auto state : dimensionKey.getStateValuesKey().getValues()) {
- uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SLICE_BY_STATE);
- writeStateToProto(state, protoOutput);
- protoOutput->end(stateToken);
- }
- // Then fill bucket_info (DurationBucketInfo).
- for (const auto& bucket : pair.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration);
- protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (long long)bucket.mDuration);
- }
-
- protoOutput->end(wrapperToken);
- }
-
- protoOutput->end(protoToken);
- if (erase_data) {
- mPastBuckets.clear();
- }
-}
-
-void DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
- if (currentBucketEndTimeNs > eventTimeNs) {
- return;
- }
- VLOG("flushing...........");
- int numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
- int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
- mCurrentBucketNum += numBucketsForward;
-}
-
-void DurationMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
- whatIt != mCurrentSlicedDurationTrackerMap.end();) {
- if (whatIt->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) {
- VLOG("erase bucket for key %s", whatIt->first.toString().c_str());
- whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
- } else {
- ++whatIt;
- }
- }
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-}
-
-void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedDurationTrackerMap.size() == 0) {
- return;
- }
-
- fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedDurationTrackerMap.size());
- if (verbose) {
- for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- fprintf(out, "\t(what)%s\n", whatIt.first.toString().c_str());
- whatIt.second->dumpStates(out, verbose);
- }
- }
-}
-
-bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(newKey.getDimensionKeyInWhat());
- if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(
- mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("DurationMetric %lld dropping data for what dimension key %s",
- (long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
- }
- return false;
-}
-
-void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKeys,
- bool condition, const LogEvent& event) {
- const auto& whatKey = eventKey.getDimensionKeyInWhat();
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
- if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
- mCurrentSlicedDurationTrackerMap[whatKey] = createDurationTracker(eventKey);
- }
-
- auto it = mCurrentSlicedDurationTrackerMap.find(whatKey);
- if (mUseWhatDimensionAsInternalDimension) {
- it->second->noteStart(whatKey, condition, event.GetElapsedTimestampNs(), conditionKeys);
- return;
- }
-
- if (mInternalDimensions.empty()) {
- it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, event.GetElapsedTimestampNs(),
- conditionKeys);
- } else {
- HashableDimensionKey dimensionKey = DEFAULT_DIMENSION_KEY;
- filterValues(mInternalDimensions, event.getValues(), &dimensionKey);
- it->second->noteStart(dimensionKey, condition, event.GetElapsedTimestampNs(),
- conditionKeys);
- }
-
-}
-
-void DurationMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKeys, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- ALOGW("Not used in duration tracker.");
-}
-
-void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
- const LogEvent& event) {
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- if (eventTimeNs < mTimeBaseNs) {
- return;
- }
-
- if (mIsActive) {
- flushIfNeededLocked(event.GetElapsedTimestampNs());
- }
-
- // Handles Stopall events.
- if (matcherIndex == mStopAllIndex) {
- for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
- whatIt.second->noteStopAll(event.GetElapsedTimestampNs());
- }
- return;
- }
-
- HashableDimensionKey dimensionInWhat = DEFAULT_DIMENSION_KEY;
- if (!mDimensionsInWhat.empty()) {
- filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
- }
-
- // Stores atom id to primary key pairs for each state atom that the metric is
- // sliced by.
- std::map<int, HashableDimensionKey> statePrimaryKeys;
-
- // For states with primary fields, use MetricStateLinks to get the primary
- // field values from the log event. These values will form a primary key
- // that will be used to query StateTracker for the correct state value.
- for (const auto& stateLink : mMetric2StateLinks) {
- getDimensionForState(event.getValues(), stateLink,
- &statePrimaryKeys[stateLink.stateAtomId]);
- }
-
- // For each sliced state, query StateTracker for the state value using
- // either the primary key from the previous step or the DEFAULT_DIMENSION_KEY.
- //
- // Expected functionality: for any case where the MetricStateLinks are
- // initialized incorrectly (ex. # of state links != # of primary fields, no
- // links are provided for a state with primary fields, links are provided
- // in the wrong order, etc.), StateTracker will simply return kStateUnknown
- // when queried using an incorrect key.
- HashableDimensionKey stateValuesKey = DEFAULT_DIMENSION_KEY;
- for (auto atomId : mSlicedStateAtoms) {
- FieldValue value;
- if (statePrimaryKeys.find(atomId) != statePrimaryKeys.end()) {
- // found a primary key for this state, query using the key
- queryStateValue(atomId, statePrimaryKeys[atomId], &value);
- } else {
- // if no MetricStateLinks exist for this state atom,
- // query using the default dimension key (empty HashableDimensionKey)
- queryStateValue(atomId, DEFAULT_DIMENSION_KEY, &value);
- }
- mapStateValue(atomId, &value);
- stateValuesKey.addValue(value);
- }
-
- // Handles Stop events.
- if (matcherIndex == mStopIndex) {
- if (mUseWhatDimensionAsInternalDimension) {
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
- if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
- whatIt->second->noteStop(dimensionInWhat, event.GetElapsedTimestampNs(), false);
- }
- return;
- }
-
- HashableDimensionKey internalDimensionKey = DEFAULT_DIMENSION_KEY;
- if (!mInternalDimensions.empty()) {
- filterValues(mInternalDimensions, event.getValues(), &internalDimensionKey);
- }
-
- auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
- if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
- whatIt->second->noteStop(internalDimensionKey, event.GetElapsedTimestampNs(), false);
- }
- return;
- }
-
- bool condition;
- ConditionKey conditionKey;
- if (mConditionSliced) {
- for (const auto& link : mMetric2ConditionLinks) {
- getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
- }
-
- auto conditionState =
- mWizard->query(mConditionTrackerIndex, conditionKey,
- !mHasLinksToAllConditionDimensionsInTracker);
- condition = conditionState == ConditionState::kTrue;
- } else {
- // TODO: The unknown condition state is not handled here, we should fix it.
- condition = mCondition == ConditionState::kTrue;
- }
-
- condition = condition && mIsActive;
-
- handleStartEvent(MetricDimensionKey(dimensionInWhat, stateValuesKey), conditionKey, condition,
- event);
-}
-
-size_t DurationMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- totalSize += pair.second.size() * kBucketSize;
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
deleted file mode 100644
index bfe1010c89de..000000000000
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-#include "../anomaly/DurationAnomalyTracker.h"
-#include "../condition/ConditionTracker.h"
-#include "../matchers/matcher_util.h"
-#include "MetricProducer.h"
-#include "duration_helper/DurationTracker.h"
-#include "duration_helper/MaxDurationTracker.h"
-#include "duration_helper/OringDurationTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class DurationMetricProducer : public MetricProducer {
-public:
- DurationMetricProducer(
- const ConfigKey& key, const DurationMetric& durationMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const size_t startIndex,
- const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
- const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {},
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~DurationMetricProducer();
-
- sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
- const sp<AlarmMonitor>& anomalyAlarmMonitor) override;
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) override;
-
-protected:
- void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override;
-
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKeys, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
- void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys,
- bool condition, const LogEvent& event);
-
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
-
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle active state change.
- void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- void onSlicedConditionMayChangeInternalLocked(bool overallCondition,
- const int64_t eventTimeNs);
-
- void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime);
- void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime);
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Util function to flush the old packet.
- void flushIfNeededLocked(const int64_t& eventTime);
-
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- const DurationMetric_AggregationType mAggregationType;
-
- // Index of the SimpleAtomMatcher which defines the start.
- const size_t mStartIndex;
-
- // Index of the SimpleAtomMatcher which defines the stop.
- const size_t mStopIndex;
-
- // Index of the SimpleAtomMatcher which defines the stop all for all dimensions.
- const size_t mStopAllIndex;
-
- // nest counting -- for the same key, stops must match the number of starts to make real stop
- const bool mNested;
-
- // The dimension from the atom predicate. e.g., uid, wakelock name.
- vector<Matcher> mInternalDimensions;
-
- bool mContainANYPositionInInternalDimensions;
-
- // This boolean is true iff When mInternalDimensions == mDimensionsInWhat
- bool mUseWhatDimensionAsInternalDimension;
-
- // Caches the current unsliced part condition.
- ConditionState mUnSlicedPartCondition;
-
- // Save the past buckets and we can clear when the StatsLogReport is dumped.
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets;
-
- // The duration trackers in the current bucket.
- std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>>
- mCurrentSlicedDurationTrackerMap;
-
- // Helper function to create a duration tracker given the metric aggregation type.
- std::unique_ptr<DurationTracker> createDurationTracker(
- const MetricDimensionKey& eventKey) const;
-
- // This hides the base class's std::vector<sp<AnomalyTracker>> mAnomalyTrackers
- std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
-
- // Util function to check whether the specified dimension hits the guardrail.
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- static const size_t kBucketSize = sizeof(DurationBucket{});
-
- FRIEND_TEST(DurationMetricTrackerTest, TestNoCondition);
- FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedCondition);
- FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState);
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicates);
- FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket);
-
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestSumDuration);
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket,
- TestSumDurationWithSplitInFollowingBucket);
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDuration);
- FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
deleted file mode 100644
index dc0036a687f3..000000000000
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "EventMetricProducer.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_STRING;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_EVENT_METRICS = 4;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for EventMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for EventMetricData
-const int FIELD_ID_ELAPSED_TIMESTAMP_NANOS = 1;
-const int FIELD_ID_ATOMS = 2;
-
-EventMetricProducer::EventMetricProducer(
- const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t startTimeNs,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap) {
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
- mProto = std::make_unique<ProtoOutputStream>();
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-EventMetricProducer::~EventMetricProducer() {
- VLOG("~EventMetricProducer() called");
-}
-
-void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- mProto->clear();
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
-}
-
-void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
-}
-
-std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
- size_t bufferSize = protoOutput.size();
-
- std::unique_ptr<std::vector<uint8_t>> buffer(new std::vector<uint8_t>(bufferSize));
-
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = protoOutput.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*buffer)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- return buffer;
-}
-
-void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- mProto->clear();
-}
-
-void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
- if (mProto->size() <= 0) {
- return;
- }
-
- size_t bufferSize = mProto->size();
- VLOG("metric %lld dump report now... proto size: %zu ",
- (long long)mMetricId, bufferSize);
- std::unique_ptr<std::vector<uint8_t>> buffer = serializeProtoLocked(*mProto);
-
- protoOutput->write(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS,
- reinterpret_cast<char*>(buffer.get()->data()), buffer.get()->size());
-
- if (erase_data) {
- mProto->clear();
- }
-}
-
-void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-}
-
-void EventMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- if (!condition) {
- return;
- }
-
- uint64_t wrapperToken =
- mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
- const int64_t elapsedTimeNs = truncateTimestampIfNecessary(event);
- mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs);
-
- uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
- event.ToProto(*mProto);
- mProto->end(eventToken);
- mProto->end(wrapperToken);
-}
-
-size_t EventMetricProducer::byteSizeLocked() const {
- return mProto->bytesWritten();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
deleted file mode 100644
index bfb2de36fad4..000000000000
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef EVENT_METRIC_PRODUCER_H
-#define EVENT_METRIC_PRODUCER_H
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-
-#include "../condition/ConditionTracker.h"
-#include "../matchers/matcher_util.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class EventMetricProducer : public MetricProducer {
-public:
- EventMetricProducer(
- const ConfigKey& key, const EventMetric& eventMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int64_t startTimeNs,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~EventMetricProducer();
-
-private:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override{};
-
- // Maps to a EventMetricDataWrapper. Storing atom events in ProtoOutputStream
- // is more space efficient than storing LogEvent.
- std::unique_ptr<android::util::ProtoOutputStream> mProto;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // EVENT_METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
deleted file mode 100644
index 020f4b638f4d..000000000000
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "../guardrail/StatsdStats.h"
-#include "GaugeMetricProducer.h"
-#include "../stats_log_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::make_shared;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_GAUGE_METRICS = 8;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for GaugeMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-const int FIELD_ID_SKIPPED = 2;
-// for SkippedBuckets
-const int FIELD_ID_SKIPPED_START_MILLIS = 3;
-const int FIELD_ID_SKIPPED_END_MILLIS = 4;
-const int FIELD_ID_SKIPPED_DROP_EVENT = 5;
-// for DumpEvent Proto
-const int FIELD_ID_BUCKET_DROP_REASON = 1;
-const int FIELD_ID_DROP_TIME = 2;
-// for GaugeMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-// for GaugeBucketInfo
-const int FIELD_ID_ATOM = 3;
-const int FIELD_ID_ELAPSED_ATOM_TIMESTAMP = 4;
-const int FIELD_ID_BUCKET_NUM = 6;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 7;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 8;
-
-GaugeMetricProducer::GaugeMetricProducer(
- const ConfigKey& key, const GaugeMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
- const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
- const int pullTagId, const int triggerAtomId, const int atomId, const int64_t timeBaseNs,
- const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
- eventActivationMap, eventDeactivationMap, /*slicedStateAtoms=*/{},
- /*stateGroupMap=*/{}),
- mWhatMatcherIndex(whatMatcherIndex),
- mEventMatcherWizard(matcherWizard),
- mPullerManager(pullerManager),
- mPullTagId(pullTagId),
- mTriggerAtomId(triggerAtomId),
- mAtomId(atomId),
- mIsPulled(pullTagId != -1),
- mMinBucketSizeNs(metric.min_bucket_size_nanos()),
- mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
- : StatsdStats::kPullMaxDelayNs),
- mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first
- : StatsdStats::kDimensionKeySizeSoftLimit),
- mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
- : StatsdStats::kDimensionKeySizeHardLimit),
- mGaugeAtomsPerDimensionLimit(metric.max_num_gauge_atoms_per_bucket()),
- mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()) {
- mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
- mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
- int64_t bucketSizeMills = 0;
- if (metric.has_bucket()) {
- bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
- } else {
- bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
- }
- mBucketSizeNs = bucketSizeMills * 1000000;
-
- mSamplingType = metric.sampling_type();
- if (!metric.gauge_fields_filter().include_all()) {
- translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers);
- }
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- }
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
- flushIfNeededLocked(startTimeNs);
- // Kicks off the puller immediately.
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- mPullerManager->RegisterReceiver(mPullTagId, mConfigKey, this, getCurrentBucketEndTimeNs(),
- mBucketSizeNs);
- }
-
- // Adjust start for partial first bucket and then pull if needed
- mCurrentBucketStartTimeNs = startTimeNs;
-
- VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
- (long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs,
- mConditionSliced);
-}
-
-GaugeMetricProducer::~GaugeMetricProducer() {
- VLOG("~GaugeMetricProducer() called");
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- mPullerManager->UnRegisterReceiver(mPullTagId, mConfigKey, this);
- }
-}
-
-void GaugeMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedBucket == nullptr ||
- mCurrentSlicedBucket->size() == 0) {
- return;
- }
-
- fprintf(out, "GaugeMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedBucket->size());
- if (verbose) {
- for (const auto& it : *mCurrentSlicedBucket) {
- fprintf(out, "\t(what)%s\t(states)%s %d atoms\n",
- it.first.getDimensionKeyInWhat().toString().c_str(),
- it.first.getStateValuesKey().toString().c_str(), (int)it.second.size());
- }
- }
-}
-
-void GaugeMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- flushIfNeededLocked(dumpTimeNs);
- mPastBuckets.clear();
- mSkippedBuckets.clear();
-}
-
-void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- VLOG("Gauge metric %lld report now...", (long long)mMetricId);
- if (include_current_partial_bucket) {
- flushLocked(dumpTimeNs);
- } else {
- flushIfNeededLocked(dumpTimeNs);
- }
-
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
- if (mPastBuckets.empty() && mSkippedBuckets.empty()) {
- return;
- }
-
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
- // Fills the dimension path if not slicing by ALL.
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_GAUGE_METRICS);
-
- for (const auto& skippedBucket : mSkippedBuckets) {
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SKIPPED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_START_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketStartTimeNs)));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_END_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketEndTimeNs)));
-
- for (const auto& dropEvent : skippedBucket.dropEvents) {
- uint64_t dropEventToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SKIPPED_DROP_EVENT);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_BUCKET_DROP_REASON, dropEvent.reason);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DROP_TIME, (long long) (NanoToMillis(dropEvent.dropTimeNs)));
- protoOutput->end(dropEventToken);
- }
- protoOutput->end(wrapperToken);
- }
-
- for (const auto& pair : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = pair.first;
-
- VLOG("Gauge dimension key %s", dimensionKey.toString().c_str());
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
-
- // Then fill bucket_info (GaugeBucketInfo).
- for (const auto& bucket : pair.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
-
- if (!bucket.mGaugeAtoms.empty()) {
- for (const auto& atom : bucket.mGaugeAtoms) {
- uint64_t atomsToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ATOM);
- writeFieldValueTreeToStream(mAtomId, *(atom.mFields), protoOutput);
- protoOutput->end(atomsToken);
- }
- for (const auto& atom : bucket.mGaugeAtoms) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
- FIELD_ID_ELAPSED_ATOM_TIMESTAMP,
- (long long)atom.mElapsedTimestampNs);
- }
- }
- protoOutput->end(bucketInfoToken);
- VLOG("Gauge \t bucket [%lld - %lld] includes %d atoms.",
- (long long)bucket.mBucketStartNs, (long long)bucket.mBucketEndNs,
- (int)bucket.mGaugeAtoms.size());
- }
- protoOutput->end(wrapperToken);
- }
- protoOutput->end(protoToken);
-
-
- if (erase_data) {
- mPastBuckets.clear();
- mSkippedBuckets.clear();
- }
-}
-
-void GaugeMetricProducer::prepareFirstBucketLocked() {
- if (mIsActive && mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
- }
-}
-
-void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
- bool triggerPuller = false;
- switch(mSamplingType) {
- // When the metric wants to do random sampling and there is already one gauge atom for the
- // current bucket, do not do it again.
- case GaugeMetric::RANDOM_ONE_SAMPLE: {
- triggerPuller = mCondition == ConditionState::kTrue && mCurrentSlicedBucket->empty();
- break;
- }
- case GaugeMetric::CONDITION_CHANGE_TO_TRUE: {
- triggerPuller = mCondition == ConditionState::kTrue;
- break;
- }
- case GaugeMetric::FIRST_N_SAMPLES: {
- triggerPuller = mCondition == ConditionState::kTrue;
- break;
- }
- default:
- break;
- }
- if (!triggerPuller) {
- return;
- }
- vector<std::shared_ptr<LogEvent>> allData;
- if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
- ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
- return;
- }
- const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs;
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- if (pullDelayNs > mMaxPullDelayNs) {
- ALOGE("Pull finish too late for atom %d", mPullTagId);
- StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- return;
- }
- for (const auto& data : allData) {
- LogEvent localCopy = data->makeCopy();
- localCopy.setElapsedTimestampNs(timestampNs);
- if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
- MatchingState::kMatched) {
- onMatchedLogEventLocked(mWhatMatcherIndex, localCopy);
- }
- }
-}
-
-void GaugeMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- MetricProducer::onActiveStateChangedLocked(eventTimeNs);
- if (ConditionState::kTrue != mCondition || !mIsPulled) {
- return;
- }
- if (mTriggerAtomId == -1 || (mIsActive && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE)) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
-
-}
-
-void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const int64_t eventTimeNs) {
- VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
-
- mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTimeNs);
- if (mIsPulled && mTriggerAtomId == -1) {
- pullAndMatchEventsLocked(eventTimeNs);
- } // else: Push mode. No need to proactively pull the gauge data.
-}
-
-void GaugeMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTimeNs) {
- VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
- overallCondition);
- mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
- if (!mIsActive) {
- return;
- }
-
- flushIfNeededLocked(eventTimeNs);
- // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
- // pull for every dimension.
- if (mIsPulled && mTriggerAtomId == -1) {
- pullAndMatchEventsLocked(eventTimeNs);
- } // else: Push mode. No need to proactively pull the gauge data.
-}
-
-std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
- std::shared_ptr<vector<FieldValue>> gaugeFields;
- if (mFieldMatchers.size() > 0) {
- gaugeFields = std::make_shared<vector<FieldValue>>();
- filterGaugeValues(mFieldMatchers, event.getValues(), gaugeFields.get());
- } else {
- gaugeFields = std::make_shared<vector<FieldValue>>(event.getValues());
- }
- // Trim all dimension fields from output. Dimensions will appear in output report and will
- // benefit from dictionary encoding. For large pulled atoms, this can give the benefit of
- // optional repeated field.
- for (const auto& field : mDimensionsInWhat) {
- for (auto it = gaugeFields->begin(); it != gaugeFields->end();) {
- if (it->mField.matches(field)) {
- it = gaugeFields->erase(it);
- } else {
- it++;
- }
- }
- }
- return gaugeFields;
-}
-
-void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
- bool pullSuccess, int64_t originalPullTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!pullSuccess || allData.size() == 0) {
- return;
- }
- const int64_t pullDelayNs = getElapsedRealtimeNs() - originalPullTimeNs;
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- if (pullDelayNs > mMaxPullDelayNs) {
- ALOGE("Pull finish too late for atom %d", mPullTagId);
- StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- return;
- }
- for (const auto& data : allData) {
- if (mEventMatcherWizard->matchLogEvent(
- *data, mWhatMatcherIndex) == MatchingState::kMatched) {
- onMatchedLogEventLocked(mWhatMatcherIndex, *data);
- }
- }
-}
-
-bool GaugeMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- if (mCurrentSlicedBucket->find(newKey) != mCurrentSlicedBucket->end()) {
- return false;
- }
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedBucket->size() > mDimensionSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedBucket->size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > mDimensionHardLimit) {
- ALOGE("GaugeMetric %lld dropping data for dimension key %s",
- (long long)mMetricId, newKey.toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
-
- return false;
-}
-
-void GaugeMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- if (condition == false) {
- return;
- }
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- if (eventTimeNs < mCurrentBucketStartTimeNs) {
- VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- return;
- }
- flushIfNeededLocked(eventTimeNs);
-
- if (mTriggerAtomId == event.GetTagId()) {
- pullAndMatchEventsLocked(eventTimeNs);
- return;
- }
-
- // When gauge metric wants to randomly sample the output atom, we just simply use the first
- // gauge in the given bucket.
- if (mCurrentSlicedBucket->find(eventKey) != mCurrentSlicedBucket->end() &&
- mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- return;
- }
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
- if ((*mCurrentSlicedBucket)[eventKey].size() >= mGaugeAtomsPerDimensionLimit) {
- return;
- }
-
- const int64_t truncatedElapsedTimestampNs = truncateTimestampIfNecessary(event);
- GaugeAtom gaugeAtom(getGaugeFields(event), truncatedElapsedTimestampNs);
- (*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom);
- // Anomaly detection on gauge metric only works when there is one numeric
- // field specified.
- if (mAnomalyTrackers.size() > 0) {
- if (gaugeAtom.mFields->size() == 1) {
- const Value& value = gaugeAtom.mFields->begin()->mValue;
- long gaugeVal = 0;
- if (value.getType() == INT) {
- gaugeVal = (long)value.int_value;
- } else if (value.getType() == LONG) {
- gaugeVal = value.long_value;
- }
- for (auto& tracker : mAnomalyTrackers) {
- tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId,
- eventKey, gaugeVal);
- }
- }
- }
-}
-
-void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() {
- for (const auto& slice : *mCurrentSlicedBucket) {
- if (slice.second.empty()) {
- continue;
- }
- const Value& value = slice.second.front().mFields->front().mValue;
- long gaugeVal = 0;
- if (value.getType() == INT) {
- gaugeVal = (long)value.int_value;
- } else if (value.getType() == LONG) {
- gaugeVal = value.long_value;
- }
- (*mCurrentSlicedBucketForAnomaly)[slice.first] = gaugeVal;
- }
-}
-
-void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- flushIfNeededLocked(dropTimeNs);
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
- mPastBuckets.clear();
-}
-
-// When a new matched event comes in, we check if event falls into the current
-// bucket. If not, flush the old counter to past buckets and initialize the new
-// bucket.
-// if data is pushed, onMatchedLogEvent will only be called through onConditionChanged() inside
-// the GaugeMetricProducer while holding the lock.
-void GaugeMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
- if (eventTimeNs < currentBucketEndTimeNs) {
- VLOG("Gauge eventTime is %lld, less than next bucket start time %lld",
- (long long)eventTimeNs, (long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
- return;
- }
-
- // Adjusts the bucket start and end times.
- int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
- int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
- mCurrentBucketNum += numBucketsForward;
- VLOG("Gauge metric %lld: new bucket start time: %lld", (long long)mMetricId,
- (long long)mCurrentBucketStartTimeNs);
-}
-
-void GaugeMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- int64_t bucketEndTime = eventTimeNs < fullBucketEndTimeNs ? eventTimeNs : fullBucketEndTimeNs;
-
- GaugeBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- info.mBucketEndNs = bucketEndTime;
-
- // Add bucket to mPastBuckets if bucket is large enough.
- // Otherwise, drop the bucket data and add bucket metadata to mSkippedBuckets.
- bool isBucketLargeEnough = info.mBucketEndNs - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
- if (isBucketLargeEnough) {
- for (const auto& slice : *mCurrentSlicedBucket) {
- info.mGaugeAtoms = slice.second;
- auto& bucketList = mPastBuckets[slice.first];
- bucketList.push_back(info);
- VLOG("Gauge gauge metric %lld, dump key value: %s", (long long)mMetricId,
- slice.first.toString().c_str());
- }
- } else {
- mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs;
- mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime;
- if (!maxDropEventsReached()) {
- mCurrentSkippedBucket.dropEvents.emplace_back(
- buildDropEvent(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL));
- }
- mSkippedBuckets.emplace_back(mCurrentSkippedBucket);
- }
-
- // If we have anomaly trackers, we need to update the partial bucket values.
- if (mAnomalyTrackers.size() > 0) {
- updateCurrentSlicedBucketForAnomaly();
-
- if (eventTimeNs > fullBucketEndTimeNs) {
- // This is known to be a full bucket, so send this data to the anomaly tracker.
- for (auto& tracker : mAnomalyTrackers) {
- tracker->addPastBucket(mCurrentSlicedBucketForAnomaly, mCurrentBucketNum);
- }
- mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
- }
- }
-
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
- mCurrentSkippedBucket.reset();
-}
-
-size_t GaugeMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- for (const auto& bucket : pair.second) {
- totalSize += bucket.mGaugeAtoms.size() * sizeof(GaugeAtom);
- for (const auto& atom : bucket.mGaugeAtoms) {
- if (atom.mFields != nullptr) {
- totalSize += atom.mFields->size() * sizeof(FieldValue);
- }
- }
- }
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
deleted file mode 100644
index 2fc772b6b641..000000000000
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest_prod.h>
-#include "../condition/ConditionTracker.h"
-#include "../external/PullDataReceiver.h"
-#include "../external/StatsPullerManager.h"
-#include "../matchers/matcher_util.h"
-#include "../matchers/EventMatcherWizard.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "../stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct GaugeAtom {
- GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t elapsedTimeNs)
- : mFields(fields), mElapsedTimestampNs(elapsedTimeNs) {
- }
- std::shared_ptr<vector<FieldValue>> mFields;
- int64_t mElapsedTimestampNs;
-};
-
-struct GaugeBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- std::vector<GaugeAtom> mGaugeAtoms;
-};
-
-typedef std::unordered_map<MetricDimensionKey, std::vector<GaugeAtom>>
- DimToGaugeAtomsMap;
-
-// This gauge metric producer first register the puller to automatically pull the gauge at the
-// beginning of each bucket. If the condition is met, insert it to the bucket info. Otherwise
-// proactively pull the gauge when the condition is changed to be true. Therefore, the gauge metric
-// producer always reports the guage at the earliest time of the bucket when the condition is met.
-class GaugeMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
-public:
- GaugeMetricProducer(
- const ConfigKey& key, const GaugeMetric& gaugeMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
- const sp<EventMatcherWizard>& matcherWizard, const int pullTagId,
- const int triggerAtomId, const int atomId, const int64_t timeBaseNs,
- const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {});
-
- virtual ~GaugeMetricProducer();
-
- // Handles when the pulled data arrives.
- void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
- bool pullSuccess, int64_t originalPullTimeNs) override;
-
- // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
- void notifyAppUpgrade(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
-
- if (!mSplitBucketForAppUpgrade) {
- return;
- }
- flushLocked(eventTimeNs);
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- };
-
- // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
- void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
-
- flushLocked(eventTimeNs);
- if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- };
-
-protected:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle active state change.
- void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Util function to flush the old packet.
- void flushIfNeededLocked(const int64_t& eventTime) override;
-
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- void prepareFirstBucketLocked() override;
-
- void pullAndMatchEventsLocked(const int64_t timestampNs);
-
- const int mWhatMatcherIndex;
-
- sp<EventMatcherWizard> mEventMatcherWizard;
-
- sp<StatsPullerManager> mPullerManager;
- // tagId for pulled data. -1 if this is not pulled
- const int mPullTagId;
-
- // tagId for atoms that trigger the pulling, if any
- const int mTriggerAtomId;
-
- // tagId for output atom
- const int mAtomId;
-
- // if this is pulled metric
- const bool mIsPulled;
-
- // Save the past buckets and we can clear when the StatsLogReport is dumped.
- std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
-
- // The current partial bucket.
- std::shared_ptr<DimToGaugeAtomsMap> mCurrentSlicedBucket;
-
- // The current full bucket for anomaly detection. This is updated to the latest value seen for
- // this slice (ie, for partial buckets, we use the last partial bucket in this full bucket).
- std::shared_ptr<DimToValMap> mCurrentSlicedBucketForAnomaly;
-
- const int64_t mMinBucketSizeNs;
-
- // Translate Atom based bucket to single numeric value bucket for anomaly and updates the map
- // for each slice with the latest value.
- void updateCurrentSlicedBucketForAnomaly();
-
- // Whitelist of fields to report. Empty means all are reported.
- std::vector<Matcher> mFieldMatchers;
-
- GaugeMetric::SamplingType mSamplingType;
-
- const int64_t mMaxPullDelayNs;
-
- // apply a whitelist on the original input
- std::shared_ptr<vector<FieldValue>> getGaugeFields(const LogEvent& event);
-
- // Util function to check whether the specified dimension hits the guardrail.
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- static const size_t kBucketSize = sizeof(GaugeBucket{});
-
- const size_t mDimensionSoftLimit;
-
- const size_t mDimensionHardLimit;
-
- const size_t mGaugeAtomsPerDimensionLimit;
-
- const bool mSplitBucketForAppUpgrade;
-
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled);
- FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection);
- FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket);
- FRIEND_TEST(GaugeMetricProducerTest, TestPullOnTrigger);
- FRIEND_TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput);
-
- FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPushedEvents);
- FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPulled);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
deleted file mode 100644
index fe143e496373..000000000000
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "MetricProducer.h"
-
-#include "../guardrail/StatsdStats.h"
-#include "state/StateTracker.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_ENUM;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-// for ActiveMetric
-const int FIELD_ID_ACTIVE_METRIC_ID = 1;
-const int FIELD_ID_ACTIVE_METRIC_ACTIVATION = 2;
-
-// for ActiveEventActivation
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX = 1;
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS = 2;
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE = 3;
-
-MetricProducer::MetricProducer(
- const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
- const int conditionIndex, const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& wizard,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : mMetricId(metricId),
- mConfigKey(key),
- mTimeBaseNs(timeBaseNs),
- mCurrentBucketStartTimeNs(timeBaseNs),
- mCurrentBucketNum(0),
- mCondition(initialCondition(conditionIndex, initialConditionCache)),
- mConditionTrackerIndex(conditionIndex),
- mConditionSliced(false),
- mWizard(wizard),
- mContainANYPositionInDimensionsInWhat(false),
- mSliceByPositionALL(false),
- mHasLinksToAllConditionDimensionsInTracker(false),
- mEventActivationMap(eventActivationMap),
- mEventDeactivationMap(eventDeactivationMap),
- mIsActive(mEventActivationMap.empty()),
- mSlicedStateAtoms(slicedStateAtoms),
- mStateGroupMap(stateGroupMap) {
-}
-
-void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) {
- if (!mIsActive) {
- return;
- }
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- // this is old event, maybe statsd restarted?
- if (eventTimeNs < mTimeBaseNs) {
- return;
- }
-
- bool condition;
- ConditionKey conditionKey;
- if (mConditionSliced) {
- for (const auto& link : mMetric2ConditionLinks) {
- getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
- }
- auto conditionState =
- mWizard->query(mConditionTrackerIndex, conditionKey,
- !mHasLinksToAllConditionDimensionsInTracker);
- condition = (conditionState == ConditionState::kTrue);
- } else {
- // TODO: The unknown condition state is not handled here, we should fix it.
- condition = mCondition == ConditionState::kTrue;
- }
-
- // Stores atom id to primary key pairs for each state atom that the metric is
- // sliced by.
- std::map<int32_t, HashableDimensionKey> statePrimaryKeys;
-
- // For states with primary fields, use MetricStateLinks to get the primary
- // field values from the log event. These values will form a primary key
- // that will be used to query StateTracker for the correct state value.
- for (const auto& stateLink : mMetric2StateLinks) {
- getDimensionForState(event.getValues(), stateLink,
- &statePrimaryKeys[stateLink.stateAtomId]);
- }
-
- // For each sliced state, query StateTracker for the state value using
- // either the primary key from the previous step or the DEFAULT_DIMENSION_KEY.
- //
- // Expected functionality: for any case where the MetricStateLinks are
- // initialized incorrectly (ex. # of state links != # of primary fields, no
- // links are provided for a state with primary fields, links are provided
- // in the wrong order, etc.), StateTracker will simply return kStateUnknown
- // when queried using an incorrect key.
- HashableDimensionKey stateValuesKey;
- for (auto atomId : mSlicedStateAtoms) {
- FieldValue value;
- if (statePrimaryKeys.find(atomId) != statePrimaryKeys.end()) {
- // found a primary key for this state, query using the key
- queryStateValue(atomId, statePrimaryKeys[atomId], &value);
- } else {
- // if no MetricStateLinks exist for this state atom,
- // query using the default dimension key (empty HashableDimensionKey)
- queryStateValue(atomId, DEFAULT_DIMENSION_KEY, &value);
- }
- mapStateValue(atomId, &value);
- stateValuesKey.addValue(value);
- }
-
- HashableDimensionKey dimensionInWhat;
- filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
- MetricDimensionKey metricKey(dimensionInWhat, stateValuesKey);
- onMatchedLogEventInternalLocked(matcherIndex, metricKey, conditionKey, condition, event,
- statePrimaryKeys);
-}
-
-bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
- bool isActive = mEventActivationMap.empty();
- for (auto& it : mEventActivationMap) {
- if (it.second->state == ActivationState::kActive &&
- elapsedTimestampNs > it.second->ttl_ns + it.second->start_ns) {
- it.second->state = ActivationState::kNotActive;
- }
- if (it.second->state == ActivationState::kActive) {
- isActive = true;
- }
- }
- return isActive;
-}
-
-void MetricProducer::flushIfExpire(int64_t elapsedTimestampNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mIsActive) {
- return;
- }
- mIsActive = evaluateActiveStateLocked(elapsedTimestampNs);
- if (!mIsActive) {
- onActiveStateChangedLocked(elapsedTimestampNs);
- }
-}
-
-void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs) {
- auto it = mEventActivationMap.find(activationTrackerIndex);
- if (it == mEventActivationMap.end()) {
- return;
- }
- auto& activation = it->second;
- if (ACTIVATE_ON_BOOT == activation->activationType) {
- if (ActivationState::kNotActive == activation->state) {
- activation->state = ActivationState::kActiveOnBoot;
- }
- // If the Activation is already active or set to kActiveOnBoot, do nothing.
- return;
- }
- activation->start_ns = elapsedTimestampNs;
- activation->state = ActivationState::kActive;
- bool oldActiveState = mIsActive;
- mIsActive = true;
- if (!oldActiveState) { // Metric went from not active to active.
- onActiveStateChangedLocked(elapsedTimestampNs);
- }
-}
-
-void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
- auto it = mEventDeactivationMap.find(deactivationTrackerIndex);
- if (it == mEventDeactivationMap.end()) {
- return;
- }
- for (auto activationToCancelIt : it->second) {
- activationToCancelIt->state = ActivationState::kNotActive;
- }
-}
-
-void MetricProducer::loadActiveMetricLocked(const ActiveMetric& activeMetric,
- int64_t currentTimeNs) {
- if (mEventActivationMap.size() == 0) {
- return;
- }
- for (int i = 0; i < activeMetric.activation_size(); i++) {
- const auto& activeEventActivation = activeMetric.activation(i);
- auto it = mEventActivationMap.find(activeEventActivation.atom_matcher_index());
- if (it == mEventActivationMap.end()) {
- ALOGE("Saved event activation not found");
- continue;
- }
- auto& activation = it->second;
- // If the event activation does not have a state, assume it is active.
- if (!activeEventActivation.has_state() ||
- activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
- // We don't want to change the ttl for future activations, so we set the start_ns
- // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
- activation->start_ns =
- currentTimeNs + activeEventActivation.remaining_ttl_nanos() - activation->ttl_ns;
- activation->state = ActivationState::kActive;
- mIsActive = true;
- } else if (activeEventActivation.state() == ActiveEventActivation::ACTIVATE_ON_BOOT) {
- activation->state = ActivationState::kActiveOnBoot;
- }
- }
-}
-
-void MetricProducer::writeActiveMetricToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_METRIC_ID, (long long)mMetricId);
- for (auto& it : mEventActivationMap) {
- const int atom_matcher_index = it.first;
- const std::shared_ptr<Activation>& activation = it.second;
-
- if (ActivationState::kNotActive == activation->state ||
- (ActivationState::kActive == activation->state &&
- activation->start_ns + activation->ttl_ns < currentTimeNs)) {
- continue;
- }
-
- const uint64_t activationToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_METRIC_ACTIVATION);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX,
- atom_matcher_index);
- if (ActivationState::kActive == activation->state) {
- const int64_t remainingTtlNs =
- activation->start_ns + activation->ttl_ns - currentTimeNs;
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
- (long long)remainingTtlNs);
- proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
- ActiveEventActivation::ACTIVE);
-
- } else if (ActivationState::kActiveOnBoot == activation->state) {
- if (reason == DEVICE_SHUTDOWN || reason == TERMINATION_SIGNAL_RECEIVED) {
- proto->write(
- FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
- (long long)activation->ttl_ns);
- proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
- ActiveEventActivation::ACTIVE);
- } else if (reason == STATSCOMPANION_DIED) {
- // We are saving because of system server death, not due to a device shutdown.
- // Next time we load, we do not want to activate metrics that activate on boot.
- proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
- ActiveEventActivation::ACTIVATE_ON_BOOT);
- }
- }
- proto->end(activationToken);
- }
-}
-
-void MetricProducer::queryStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
- FieldValue* value) {
- if (!StateManager::getInstance().getStateValue(atomId, queryKey, value)) {
- value->mValue = Value(StateTracker::kStateUnknown);
- value->mField.setTag(atomId);
- ALOGW("StateTracker not found for state atom %d", atomId);
- return;
- }
-}
-
-void MetricProducer::mapStateValue(const int32_t atomId, FieldValue* value) {
- // check if there is a state map for this atom
- auto atomIt = mStateGroupMap.find(atomId);
- if (atomIt == mStateGroupMap.end()) {
- return;
- }
- auto valueIt = atomIt->second.find(value->mValue.int_value);
- if (valueIt == atomIt->second.end()) {
- // state map exists, but value was not put in a state group
- // so set mValue to kStateUnknown
- // TODO(tsaichristine): handle incomplete state maps
- value->mValue.setInt(StateTracker::kStateUnknown);
- } else {
- // set mValue to group_id
- value->mValue.setLong(valueIt->second);
- }
-}
-
-HashableDimensionKey MetricProducer::getUnknownStateKey() {
- HashableDimensionKey stateKey;
- for (auto atom : mSlicedStateAtoms) {
- FieldValue fieldValue;
- fieldValue.mField.setTag(atom);
- fieldValue.mValue.setInt(StateTracker::kStateUnknown);
- stateKey.addValue(fieldValue);
- }
- return stateKey;
-}
-
-DropEvent MetricProducer::buildDropEvent(const int64_t dropTimeNs, const BucketDropReason reason) {
- DropEvent event;
- event.reason = reason;
- event.dropTimeNs = dropTimeNs;
- return event;
-}
-
-bool MetricProducer::maxDropEventsReached() {
- return mCurrentSkippedBucket.dropEvents.size() >= StatsdStats::kMaxLoggedBucketDropEvents;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
deleted file mode 100644
index be4cd6724bb1..000000000000
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef METRIC_PRODUCER_H
-#define METRIC_PRODUCER_H
-
-#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
-#include <utils/RefBase.h>
-
-#include <unordered_map>
-
-#include "HashableDimensionKey.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionWizard.h"
-#include "config/ConfigKey.h"
-#include "matchers/matcher_util.h"
-#include "packages/PackageInfoListener.h"
-#include "state/StateListener.h"
-#include "state/StateManager.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Keep this in sync with DumpReportReason enum in stats_log.proto
-enum DumpReportReason {
- DEVICE_SHUTDOWN = 1,
- CONFIG_UPDATED = 2,
- CONFIG_REMOVED = 3,
- GET_DATA_CALLED = 4,
- ADB_DUMP = 5,
- CONFIG_RESET = 6,
- STATSCOMPANION_DIED = 7,
- TERMINATION_SIGNAL_RECEIVED = 8
-};
-
-// If the metric has no activation requirement, it will be active once the metric producer is
-// created.
-// If the metric needs to be activated by atoms, the metric producer will start
-// with kNotActive state, turn to kActive or kActiveOnBoot when the activation event arrives, become
-// kNotActive when it reaches the duration limit (timebomb). If the activation event arrives again
-// before or after it expires, the event producer will be re-activated and ttl will be reset.
-enum ActivationState {
- kNotActive = 0,
- kActive = 1,
- kActiveOnBoot = 2,
-};
-
-enum DumpLatency {
- // In some cases, we only have a short time range to do the dump, e.g. statsd is being killed.
- // We might be able to return all the data in this mode. For instance, pull metrics might need
- // to be pulled when the current bucket is requested.
- FAST = 1,
- // In other cases, it is fine for a dump to take more than a few milliseconds, e.g. config
- // updates.
- NO_TIME_CONSTRAINTS = 2
-};
-
-// Keep this in sync with BucketDropReason enum in stats_log.proto
-enum BucketDropReason {
- // For ValueMetric, a bucket is dropped during a dump report request iff
- // current bucket should be included, a pull is needed (pulled metric and
- // condition is true), and we are under fast time constraints.
- DUMP_REPORT_REQUESTED = 1,
- EVENT_IN_WRONG_BUCKET = 2,
- CONDITION_UNKNOWN = 3,
- PULL_FAILED = 4,
- PULL_DELAYED = 5,
- DIMENSION_GUARDRAIL_REACHED = 6,
- MULTIPLE_BUCKETS_SKIPPED = 7,
- // Not an invalid bucket case, but the bucket is dropped.
- BUCKET_TOO_SMALL = 8,
- // Not an invalid bucket case, but the bucket is skipped.
- NO_DATA = 9
-};
-
-struct Activation {
- Activation(const ActivationType& activationType, const int64_t ttlNs)
- : ttl_ns(ttlNs),
- start_ns(0),
- state(ActivationState::kNotActive),
- activationType(activationType) {}
-
- const int64_t ttl_ns;
- int64_t start_ns;
- ActivationState state;
- const ActivationType activationType;
-};
-
-struct DropEvent {
- // Reason for dropping the bucket and/or marking the bucket invalid.
- BucketDropReason reason;
- // The timestamp of the drop event.
- int64_t dropTimeNs;
-};
-
-struct SkippedBucket {
- // Start time of the dropped bucket.
- int64_t bucketStartTimeNs;
- // End time of the dropped bucket.
- int64_t bucketEndTimeNs;
- // List of events that invalidated this bucket.
- std::vector<DropEvent> dropEvents;
-
- void reset() {
- bucketStartTimeNs = 0;
- bucketEndTimeNs = 0;
- dropEvents.clear();
- }
-};
-
-// A MetricProducer is responsible for compute one single metrics, creating stats log report, and
-// writing the report to dropbox. MetricProducers should respond to package changes as required in
-// PackageInfoListener, but if none of the metrics are slicing by package name, then the update can
-// be a no-op.
-class MetricProducer : public virtual android::RefBase, public virtual StateListener {
-public:
- MetricProducer(const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
- const int conditionIndex, const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& wizard,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap);
-
- virtual ~MetricProducer(){};
-
- ConditionState initialCondition(const int conditionIndex,
- const vector<ConditionState>& initialConditionCache) const {
- return conditionIndex >= 0 ? initialConditionCache[conditionIndex] : ConditionState::kTrue;
- }
-
- /**
- * Force a partial bucket split on app upgrade
- */
- virtual void notifyAppUpgrade(const int64_t& eventTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- flushLocked(eventTimeNs);
- };
-
- void notifyAppRemoved(const int64_t& eventTimeNs) {
- // Force buckets to split on removal also.
- notifyAppUpgrade(eventTimeNs);
- };
-
- /**
- * Force a partial bucket split on boot complete.
- */
- virtual void onStatsdInitCompleted(const int64_t& eventTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- flushLocked(eventTimeNs);
- }
- // Consume the parsed stats log entry that already matched the "what" of the metric.
- void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
- std::lock_guard<std::mutex> lock(mMutex);
- onMatchedLogEventLocked(matcherIndex, event);
- }
-
- void onConditionChanged(const bool condition, const int64_t eventTime) {
- std::lock_guard<std::mutex> lock(mMutex);
- onConditionChangedLocked(condition, eventTime);
- }
-
- void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
- std::lock_guard<std::mutex> lock(mMutex);
- onSlicedConditionMayChangeLocked(overallCondition, eventTime);
- }
-
- bool isConditionSliced() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return mConditionSliced;
- };
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState){};
-
- // Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp.
- // This method clears all the past buckets.
- void onDumpReport(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) {
- std::lock_guard<std::mutex> lock(mMutex);
- return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, erase_data,
- dumpLatency, str_set, protoOutput);
- }
-
- void clearPastBuckets(const int64_t dumpTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- return clearPastBucketsLocked(dumpTimeNs);
- }
-
- void prepareFirstBucket() {
- std::lock_guard<std::mutex> lock(mMutex);
- prepareFirstBucketLocked();
- }
-
- // Returns the memory in bytes currently used to store this metric's data. Does not change
- // state.
- size_t byteSize() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return byteSizeLocked();
- }
-
- void dumpStates(FILE* out, bool verbose) const {
- std::lock_guard<std::mutex> lock(mMutex);
- dumpStatesLocked(out, verbose);
- }
-
- // Let MetricProducer drop in-memory data to save memory.
- // We still need to keep future data valid and anomaly tracking work, which means we will
- // have to flush old data, informing anomaly trackers then safely drop old data.
- // We still keep current bucket data for future metrics' validity.
- void dropData(const int64_t dropTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- dropDataLocked(dropTimeNs);
- }
-
- void loadActiveMetric(const ActiveMetric& activeMetric, int64_t currentTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- loadActiveMetricLocked(activeMetric, currentTimeNs);
- }
-
- void activate(int activationTrackerIndex, int64_t elapsedTimestampNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- activateLocked(activationTrackerIndex, elapsedTimestampNs);
- }
-
- void cancelEventActivation(int deactivationTrackerIndex) {
- std::lock_guard<std::mutex> lock(mMutex);
- cancelEventActivationLocked(deactivationTrackerIndex);
- }
-
- bool isActive() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return isActiveLocked();
- }
-
- void flushIfExpire(int64_t elapsedTimestampNs);
-
- void writeActiveMetricToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- // Start: getters/setters
- inline const int64_t& getMetricId() const {
- return mMetricId;
- }
-
- // For test only.
- inline int64_t getCurrentBucketNum() const {
- return mCurrentBucketNum;
- }
-
- int64_t getBucketSizeInNs() const {
- std::lock_guard<std::mutex> lock(mMutex);
- return mBucketSizeNs;
- }
-
- inline const std::vector<int> getSlicedStateAtoms() {
- std::lock_guard<std::mutex> lock(mMutex);
- return mSlicedStateAtoms;
- }
-
- /* If alert is valid, adds an AnomalyTracker and returns it. If invalid, returns nullptr. */
- virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
- const sp<AlarmMonitor>& anomalyAlarmMonitor) {
- std::lock_guard<std::mutex> lock(mMutex);
- sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, mConfigKey);
- if (anomalyTracker != nullptr) {
- mAnomalyTrackers.push_back(anomalyTracker);
- }
- return anomalyTracker;
- }
- // End: getters/setters
-protected:
- /**
- * Flushes the current bucket if the eventTime is after the current bucket's end time.
- */
- virtual void flushIfNeededLocked(const int64_t& eventTime){};
-
- /**
- * For metrics that aggregate (ie, every metric producer except for EventMetricProducer),
- * we need to be able to flush the current buckets on demand (ie, end the current bucket and
- * start new bucket). If this function is called when eventTimeNs is greater than the current
- * bucket's end timestamp, than we flush up to the end of the latest full bucket; otherwise,
- * we assume that we want to flush a partial bucket. The bucket start timestamp and bucket
- * number are not changed by this function. This method should only be called by
- * flushIfNeededLocked or flushLocked or the app upgrade handler; the caller MUST update the
- * bucket timestamp and bucket number as needed.
- */
- virtual void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {};
-
- /**
- * Flushes all the data including the current partial bucket.
- */
- virtual void flushLocked(const int64_t& eventTimeNs) {
- flushIfNeededLocked(eventTimeNs);
- flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
- };
-
- /*
- * Individual metrics can implement their own business logic here. All pre-processing is done.
- *
- * [matcherIndex]: the index of the matcher which matched this event. This is interesting to
- * DurationMetric, because it has start/stop/stop_all 3 matchers.
- * [eventKey]: the extracted dimension key for the final output. if the metric doesn't have
- * dimensions, it will be DEFAULT_DIMENSION_KEY
- * [conditionKey]: the keys of conditions which should be used to query the condition for this
- * target event (from MetricConditionLink). This is passed to individual metrics
- * because DurationMetric needs it to be cached.
- * [condition]: whether condition is met. If condition is sliced, this is the result coming from
- * query with ConditionWizard; If condition is not sliced, this is the
- * nonSlicedCondition.
- * [event]: the log event, just in case the metric needs its data, e.g., EventMetric.
- */
- virtual void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) = 0;
-
- // Consume the parsed stats log entry that already matched the "what" of the metric.
- virtual void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event);
- virtual void onConditionChangedLocked(const bool condition, const int64_t eventTime) = 0;
- virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) = 0;
- virtual void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) = 0;
- virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
- virtual void prepareFirstBucketLocked(){};
- virtual size_t byteSizeLocked() const = 0;
- virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
- virtual void dropDataLocked(const int64_t dropTimeNs) = 0;
- void loadActiveMetricLocked(const ActiveMetric& activeMetric, int64_t currentTimeNs);
- void activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs);
- void cancelEventActivationLocked(int deactivationTrackerIndex);
-
- bool evaluateActiveStateLocked(int64_t elapsedTimestampNs);
-
- virtual void onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- if (!mIsActive) {
- flushLocked(eventTimeNs);
- }
- }
-
- inline bool isActiveLocked() const {
- return mIsActive;
- }
-
- // Convenience to compute the current bucket's end time, which is always aligned with the
- // start time of the metric.
- int64_t getCurrentBucketEndTimeNs() const {
- return mTimeBaseNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
- }
-
- int64_t getBucketNumFromEndTimeNs(const int64_t endNs) {
- return (endNs - mTimeBaseNs) / mBucketSizeNs - 1;
- }
-
- // Query StateManager for original state value using the queryKey.
- // The field and value are output.
- void queryStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
- FieldValue* value);
-
- // If a state map exists for the given atom, replace the original state
- // value with the group id mapped to the value.
- // If no state map exists, keep the original state value.
- void mapStateValue(const int32_t atomId, FieldValue* value);
-
- // Returns a HashableDimensionKey with unknown state value for each state
- // atom.
- HashableDimensionKey getUnknownStateKey();
-
- DropEvent buildDropEvent(const int64_t dropTimeNs, const BucketDropReason reason);
-
- // Returns true if the number of drop events in the current bucket has
- // exceeded the maximum number allowed, which is currently capped at 10.
- bool maxDropEventsReached();
-
- const int64_t mMetricId;
-
- const ConfigKey mConfigKey;
-
- // The time when this metric producer was first created. The end time for the current bucket
- // can be computed from this based on mCurrentBucketNum.
- int64_t mTimeBaseNs;
-
- // Start time may not be aligned with the start of statsd if there is an app upgrade in the
- // middle of a bucket.
- int64_t mCurrentBucketStartTimeNs;
-
- // Used by anomaly detector to track which bucket we are in. This is not sent with the produced
- // report.
- int64_t mCurrentBucketNum;
-
- int64_t mBucketSizeNs;
-
- ConditionState mCondition;
-
- int mConditionTrackerIndex;
-
- bool mConditionSliced;
-
- sp<ConditionWizard> mWizard;
-
- bool mContainANYPositionInDimensionsInWhat;
-
- bool mSliceByPositionALL;
-
- vector<Matcher> mDimensionsInWhat; // The dimensions_in_what defined in statsd_config
-
- // True iff the metric to condition links cover all dimension fields in the condition tracker.
- // This field is always false for combinational condition trackers.
- bool mHasLinksToAllConditionDimensionsInTracker;
-
- std::vector<Metric2Condition> mMetric2ConditionLinks;
-
- std::vector<sp<AnomalyTracker>> mAnomalyTrackers;
-
- mutable std::mutex mMutex;
-
- // When the metric producer has multiple activations, these activations are ORed to determine
- // whether the metric producer is ready to generate metrics.
- std::unordered_map<int, std::shared_ptr<Activation>> mEventActivationMap;
-
- // Maps index of atom matcher for deactivation to a list of Activation structs.
- std::unordered_map<int, std::vector<std::shared_ptr<Activation>>> mEventDeactivationMap;
-
- bool mIsActive;
-
- // The slice_by_state atom ids defined in statsd_config.
- const std::vector<int32_t> mSlicedStateAtoms;
-
- // Maps atom ids and state values to group_ids (<atom_id, <value, group_id>>).
- const std::unordered_map<int32_t, std::unordered_map<int, int64_t>> mStateGroupMap;
-
- // MetricStateLinks defined in statsd_config that link fields in the state
- // atom to fields in the "what" atom.
- std::vector<Metric2State> mMetric2StateLinks;
-
- SkippedBucket mCurrentSkippedBucket;
- // Buckets that were invalidated and had their data dropped.
- std::vector<SkippedBucket> mSkippedBuckets;
-
- FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
- FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
- FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
-
- FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
- FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
- FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
- FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
- FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
- FRIEND_TEST(StatsLogProcessorTest,
- TestActivationOnBootMultipleActivationsDifferentActivationTypes);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
-
- FRIEND_TEST(MetricsManagerTest, TestInitialConditions);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#endif // METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
deleted file mode 100644
index 60de1a24cce5..000000000000
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "MetricsManager.h"
-
-#include <private/android_filesystem_config.h>
-
-#include "CountMetricProducer.h"
-#include "condition/CombinationConditionTracker.h"
-#include "condition/SimpleConditionTracker.h"
-#include "guardrail/StatsdStats.h"
-#include "matchers/CombinationLogMatchingTracker.h"
-#include "matchers/SimpleLogMatchingTracker.h"
-#include "metrics_manager_util.h"
-#include "state/StateManager.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statslog_statsd.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int FIELD_ID_METRICS = 1;
-const int FIELD_ID_ANNOTATIONS = 7;
-const int FIELD_ID_ANNOTATIONS_INT64 = 1;
-const int FIELD_ID_ANNOTATIONS_INT32 = 2;
-
-// for ActiveConfig
-const int FIELD_ID_ACTIVE_CONFIG_ID = 1;
-const int FIELD_ID_ACTIVE_CONFIG_UID = 2;
-const int FIELD_ID_ACTIVE_CONFIG_METRIC = 3;
-
-MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
- const int64_t timeBaseNs, const int64_t currentTimeNs,
- const sp<UidMap>& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor)
- : mConfigKey(key),
- mUidMap(uidMap),
- mTtlNs(config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1),
- mTtlEndNs(-1),
- mLastReportTimeNs(currentTimeNs),
- mLastReportWallClockNs(getWallClockNs()),
- mPullerManager(pullerManager),
- mWhitelistedAtomIds(config.whitelisted_atom_ids().begin(),
- config.whitelisted_atom_ids().end()),
- mShouldPersistHistory(config.persist_locally()) {
- // Init the ttl end timestamp.
- refreshTtl(timeBaseNs);
-
- mConfigValid = initStatsdConfig(
- key, config, *uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers,
- mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
- mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
- mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
- mAlertTrackerMap, mMetricIndexesWithActivation, mNoReportMetricIds);
-
- mHashStringsInReport = config.hash_strings_in_metric_report();
- mVersionStringsInReport = config.version_strings_in_metric_report();
- mInstallerInReport = config.installer_in_metric_report();
-
- // Init allowed pushed atom uids.
- if (config.allowed_log_source_size() == 0) {
- mConfigValid = false;
- ALOGE("Log source whitelist is empty! This config won't get any data. Suggest adding at "
- "least AID_SYSTEM and AID_STATSD to the allowed_log_source field.");
- } else {
- for (const auto& source : config.allowed_log_source()) {
- auto it = UidMap::sAidToUidMapping.find(source);
- if (it != UidMap::sAidToUidMapping.end()) {
- mAllowedUid.push_back(it->second);
- } else {
- mAllowedPkg.push_back(source);
- }
- }
-
- if (mAllowedUid.size() + mAllowedPkg.size() > StatsdStats::kMaxLogSourceCount) {
- ALOGE("Too many log sources. This is likely to be an error in the config.");
- mConfigValid = false;
- } else {
- initLogSourceWhiteList();
- }
- }
-
- // Init default allowed pull atom uids.
- int numPullPackages = 0;
- for (const string& pullSource : config.default_pull_packages()) {
- auto it = UidMap::sAidToUidMapping.find(pullSource);
- if (it != UidMap::sAidToUidMapping.end()) {
- numPullPackages++;
- mDefaultPullUids.insert(it->second);
- } else {
- ALOGE("Default pull atom packages must be in sAidToUidMapping");
- mConfigValid = false;
- }
- }
- // Init per-atom pull atom packages.
- for (const PullAtomPackages& pullAtomPackages : config.pull_atom_packages()) {
- int32_t atomId = pullAtomPackages.atom_id();
- for (const string& pullPackage : pullAtomPackages.packages()) {
- numPullPackages++;
- auto it = UidMap::sAidToUidMapping.find(pullPackage);
- if (it != UidMap::sAidToUidMapping.end()) {
- mPullAtomUids[atomId].insert(it->second);
- } else {
- mPullAtomPackages[atomId].insert(pullPackage);
- }
- }
- }
- if (numPullPackages > StatsdStats::kMaxPullAtomPackages) {
- ALOGE("Too many sources in default_pull_packages and pull_atom_packages. This is likely to "
- "be an error in the config");
- mConfigValid = false;
- } else {
- initPullAtomSources();
- }
- mPullerManager->RegisterPullUidProvider(mConfigKey, this);
-
- // Store the sub-configs used.
- for (const auto& annotation : config.annotation()) {
- mAnnotations.emplace_back(annotation.field_int64(), annotation.field_int32());
- }
-
- // Guardrail. Reject the config if it's too big.
- if (mAllMetricProducers.size() > StatsdStats::kMaxMetricCountPerConfig ||
- mAllConditionTrackers.size() > StatsdStats::kMaxConditionCountPerConfig ||
- mAllAtomMatchers.size() > StatsdStats::kMaxMatcherCountPerConfig) {
- ALOGE("This config is too big! Reject!");
- mConfigValid = false;
- }
- if (mAllAnomalyTrackers.size() > StatsdStats::kMaxAlertCountPerConfig) {
- ALOGE("This config has too many alerts! Reject!");
- mConfigValid = false;
- }
-
- mIsAlwaysActive = (mMetricIndexesWithActivation.size() != mAllMetricProducers.size()) ||
- (mAllMetricProducers.size() == 0);
- bool isActive = mIsAlwaysActive;
- for (int metric : mMetricIndexesWithActivation) {
- isActive |= mAllMetricProducers[metric]->isActive();
- }
- mIsActive = isActive;
- VLOG("mIsActive is initialized to %d", mIsActive)
-
- // no matter whether this config is valid, log it in the stats.
- StatsdStats::getInstance().noteConfigReceived(
- key, mAllMetricProducers.size(), mAllConditionTrackers.size(), mAllAtomMatchers.size(),
- mAllAnomalyTrackers.size(), mAnnotations, mConfigValid);
- // Check active
- for (const auto& metric : mAllMetricProducers) {
- if (metric->isActive()) {
- mIsActive = true;
- break;
- }
- }
-}
-
-MetricsManager::~MetricsManager() {
- for (auto it : mAllMetricProducers) {
- for (int atomId : it->getSlicedStateAtoms()) {
- StateManager::getInstance().unregisterListener(atomId, it);
- }
- }
- mPullerManager->UnregisterPullUidProvider(mConfigKey, this);
-
- VLOG("~MetricsManager()");
-}
-
-void MetricsManager::initLogSourceWhiteList() {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- mAllowedLogSources.clear();
- mAllowedLogSources.insert(mAllowedUid.begin(), mAllowedUid.end());
-
- for (const auto& pkg : mAllowedPkg) {
- auto uids = mUidMap->getAppUid(pkg);
- mAllowedLogSources.insert(uids.begin(), uids.end());
- }
- if (DEBUG) {
- for (const auto& uid : mAllowedLogSources) {
- VLOG("Allowed uid %d", uid);
- }
- }
-}
-
-void MetricsManager::initPullAtomSources() {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- mCombinedPullAtomUids.clear();
- for (const auto& [atomId, uids] : mPullAtomUids) {
- mCombinedPullAtomUids[atomId].insert(uids.begin(), uids.end());
- }
- for (const auto& [atomId, packages] : mPullAtomPackages) {
- for (const string& pkg : packages) {
- set<int32_t> uids = mUidMap->getAppUid(pkg);
- mCombinedPullAtomUids[atomId].insert(uids.begin(), uids.end());
- }
- }
-}
-
-bool MetricsManager::isConfigValid() const {
- return mConfigValid;
-}
-
-void MetricsManager::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
- const int64_t version) {
- // Inform all metric producers.
- for (const auto& it : mAllMetricProducers) {
- it->notifyAppUpgrade(eventTimeNs);
- }
- // check if we care this package
- if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
- // We will re-initialize the whole list because we don't want to keep the multi mapping of
- // UID<->pkg inside MetricsManager to reduce the memory usage.
- initLogSourceWhiteList();
- }
-
- for (const auto& it : mPullAtomPackages) {
- if (it.second.find(apk) != it.second.end()) {
- initPullAtomSources();
- return;
- }
- }
-}
-
-void MetricsManager::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
- const int uid) {
- // Inform all metric producers.
- for (const auto& it : mAllMetricProducers) {
- it->notifyAppRemoved(eventTimeNs);
- }
- // check if we care this package
- if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
- // We will re-initialize the whole list because we don't want to keep the multi mapping of
- // UID<->pkg inside MetricsManager to reduce the memory usage.
- initLogSourceWhiteList();
- }
-
- for (const auto& it : mPullAtomPackages) {
- if (it.second.find(apk) != it.second.end()) {
- initPullAtomSources();
- return;
- }
- }
-}
-
-void MetricsManager::onUidMapReceived(const int64_t& eventTimeNs) {
- // Purposefully don't inform metric producers on a new snapshot
- // because we don't need to flush partial buckets.
- // This occurs if a new user is added/removed or statsd crashes.
- initPullAtomSources();
-
- if (mAllowedPkg.size() == 0) {
- return;
- }
- initLogSourceWhiteList();
-}
-
-void MetricsManager::onStatsdInitCompleted(const int64_t& eventTimeNs) {
- // Inform all metric producers.
- for (const auto& it : mAllMetricProducers) {
- it->onStatsdInitCompleted(eventTimeNs);
- }
-}
-
-void MetricsManager::init() {
- for (const auto& producer : mAllMetricProducers) {
- producer->prepareFirstBucket();
- }
-}
-
-vector<int32_t> MetricsManager::getPullAtomUids(int32_t atomId) {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- vector<int32_t> uids;
- const auto& it = mCombinedPullAtomUids.find(atomId);
- if (it != mCombinedPullAtomUids.end()) {
- uids.insert(uids.end(), it->second.begin(), it->second.end());
- }
- uids.insert(uids.end(), mDefaultPullUids.begin(), mDefaultPullUids.end());
- return uids;
-}
-
-void MetricsManager::dumpStates(FILE* out, bool verbose) {
- fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
- {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- for (const auto& source : mAllowedLogSources) {
- fprintf(out, "%d ", source);
- }
- }
- fprintf(out, "\n");
- for (const auto& producer : mAllMetricProducers) {
- producer->dumpStates(out, verbose);
- }
-}
-
-void MetricsManager::dropData(const int64_t dropTimeNs) {
- for (const auto& producer : mAllMetricProducers) {
- producer->dropData(dropTimeNs);
- }
-}
-
-void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- VLOG("=========================Metric Reports Start==========================");
- // one StatsLogReport per MetricProduer
- for (const auto& producer : mAllMetricProducers) {
- if (mNoReportMetricIds.find(producer->getMetricId()) == mNoReportMetricIds.end()) {
- uint64_t token = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
- if (mHashStringsInReport) {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpLatency, str_set, protoOutput);
- } else {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
- dumpLatency, nullptr, protoOutput);
- }
- protoOutput->end(token);
- } else {
- producer->clearPastBuckets(dumpTimeStampNs);
- }
- }
- for (const auto& annotation : mAnnotations) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ANNOTATIONS);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ANNOTATIONS_INT64,
- (long long)annotation.first);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ANNOTATIONS_INT32, annotation.second);
- protoOutput->end(token);
- }
-
- // Do not update the timestamps when data is not cleared to avoid timestamps from being
- // misaligned.
- if (erase_data) {
- mLastReportTimeNs = dumpTimeStampNs;
- mLastReportWallClockNs = getWallClockNs();
- }
- VLOG("=========================Metric Reports End==========================");
-}
-
-
-bool MetricsManager::checkLogCredentials(const LogEvent& event) {
- if (mWhitelistedAtomIds.find(event.GetTagId()) != mWhitelistedAtomIds.end()) {
- return true;
- }
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
- VLOG("log source %d not on the whitelist", event.GetUid());
- return false;
- }
- return true;
-}
-
-bool MetricsManager::eventSanityCheck(const LogEvent& event) {
- if (event.GetTagId() == util::APP_BREADCRUMB_REPORTED) {
- // Check that app breadcrumb reported fields are valid.
- status_t err = NO_ERROR;
-
- // Uid is 3rd from last field and must match the caller's uid,
- // unless that caller is statsd itself (statsd is allowed to spoof uids).
- long appHookUid = event.GetLong(event.size()-2, &err);
- if (err != NO_ERROR) {
- VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
- return false;
- }
-
- // Because the uid within the LogEvent may have been mapped from
- // isolated to host, map the loggerUid similarly before comparing.
- int32_t loggerUid = mUidMap->getHostUidOrSelf(event.GetUid());
- if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
- VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
- appHookUid, loggerUid);
- return false;
- }
-
- // The state must be from 0,3. This part of code must be manually updated.
- long appHookState = event.GetLong(event.size(), &err);
- if (err != NO_ERROR) {
- VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
- return false;
- } else if (appHookState < 0 || appHookState > 3) {
- VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
- return false;
- }
- } else if (event.GetTagId() == util::DAVEY_OCCURRED) {
- // Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
- // Check that the davey duration is reasonable. Max length check is for privacy.
- status_t err = NO_ERROR;
-
- // Uid is the first field provided.
- long jankUid = event.GetLong(1, &err);
- if (err != NO_ERROR) {
- VLOG("Davey occurred had error when parsing the uid");
- return false;
- }
- int32_t loggerUid = event.GetUid();
- if (loggerUid != jankUid && loggerUid != AID_STATSD) {
- VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
- loggerUid);
- return false;
- }
-
- long duration = event.GetLong(event.size(), &err);
- if (err != NO_ERROR) {
- VLOG("Davey occurred had error when parsing the duration");
- return false;
- } else if (duration > 100000) {
- VLOG("Davey duration is unreasonably long: %ld", duration);
- return false;
- }
- }
-
- return true;
-}
-
-// Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const LogEvent& event) {
- if (!mConfigValid) {
- return;
- }
-
- if (!checkLogCredentials(event)) {
- return;
- }
-
- if (!eventSanityCheck(event)) {
- return;
- }
-
- int tagId = event.GetTagId();
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
-
- bool isActive = mIsAlwaysActive;
-
- // Set of metrics that are still active after flushing.
- unordered_set<int> activeMetricsIndices;
-
- // Update state of all metrics w/ activation conditions as of eventTimeNs.
- for (int metricIndex : mMetricIndexesWithActivation) {
- const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
- metric->flushIfExpire(eventTimeNs);
- if (metric->isActive()) {
- // If this metric w/ activation condition is still active after
- // flushing, remember it.
- activeMetricsIndices.insert(metricIndex);
- }
- }
-
- mIsActive = isActive || !activeMetricsIndices.empty();
-
- if (mTagIds.find(tagId) == mTagIds.end()) {
- // Not interesting...
- return;
- }
-
- vector<MatchingState> matcherCache(mAllAtomMatchers.size(), MatchingState::kNotComputed);
-
- // Evaluate all atom matchers.
- for (auto& matcher : mAllAtomMatchers) {
- matcher->onLogEvent(event, mAllAtomMatchers, matcherCache);
- }
-
- // Set of metrics that received an activation cancellation.
- unordered_set<int> metricIndicesWithCanceledActivations;
-
- // Determine which metric activations received a cancellation and cancel them.
- for (const auto& it : mDeactivationAtomTrackerToMetricMap) {
- if (matcherCache[it.first] == MatchingState::kMatched) {
- for (int metricIndex : it.second) {
- mAllMetricProducers[metricIndex]->cancelEventActivation(it.first);
- metricIndicesWithCanceledActivations.insert(metricIndex);
- }
- }
- }
-
- // Determine whether any metrics are no longer active after cancelling metric activations.
- for (const int metricIndex : metricIndicesWithCanceledActivations) {
- const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
- metric->flushIfExpire(eventTimeNs);
- if (!metric->isActive()) {
- activeMetricsIndices.erase(metricIndex);
- }
- }
-
- isActive |= !activeMetricsIndices.empty();
-
-
- // Determine which metric activations should be turned on and turn them on
- for (const auto& it : mActivationAtomTrackerToMetricMap) {
- if (matcherCache[it.first] == MatchingState::kMatched) {
- for (int metricIndex : it.second) {
- mAllMetricProducers[metricIndex]->activate(it.first, eventTimeNs);
- isActive |= mAllMetricProducers[metricIndex]->isActive();
- }
- }
- }
-
- mIsActive = isActive;
-
- // A bitmap to see which ConditionTracker needs to be re-evaluated.
- vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
-
- for (const auto& pair : mTrackerToConditionMap) {
- if (matcherCache[pair.first] == MatchingState::kMatched) {
- const auto& conditionList = pair.second;
- for (const int conditionIndex : conditionList) {
- conditionToBeEvaluated[conditionIndex] = true;
- }
- }
- }
-
- vector<ConditionState> conditionCache(mAllConditionTrackers.size(),
- ConditionState::kNotEvaluated);
- // A bitmap to track if a condition has changed value.
- vector<bool> changedCache(mAllConditionTrackers.size(), false);
- for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
- if (conditionToBeEvaluated[i] == false) {
- continue;
- }
- sp<ConditionTracker>& condition = mAllConditionTrackers[i];
- condition->evaluateCondition(event, matcherCache, mAllConditionTrackers, conditionCache,
- changedCache);
- }
-
- for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
- if (changedCache[i] == false) {
- continue;
- }
- auto pair = mConditionToMetricMap.find(i);
- if (pair != mConditionToMetricMap.end()) {
- auto& metricList = pair->second;
- for (auto metricIndex : metricList) {
- // Metric cares about non sliced condition, and it's changed.
- // Push the new condition to it directly.
- if (!mAllMetricProducers[metricIndex]->isConditionSliced()) {
- mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i],
- eventTimeNs);
- // Metric cares about sliced conditions, and it may have changed. Send
- // notification, and the metric can query the sliced conditions that are
- // interesting to it.
- } else {
- mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(conditionCache[i],
- eventTimeNs);
- }
- }
- }
- }
-
- // For matched AtomMatchers, tell relevant metrics that a matched event has come.
- for (size_t i = 0; i < mAllAtomMatchers.size(); i++) {
- if (matcherCache[i] == MatchingState::kMatched) {
- StatsdStats::getInstance().noteMatcherMatched(mConfigKey,
- mAllAtomMatchers[i]->getId());
- auto pair = mTrackerToMetricMap.find(i);
- if (pair != mTrackerToMetricMap.end()) {
- auto& metricList = pair->second;
- for (const int metricIndex : metricList) {
- // pushed metrics are never scheduled pulls
- mAllMetricProducers[metricIndex]->onMatchedLogEvent(i, event);
- }
- }
- }
- }
-}
-
-void MetricsManager::onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
- for (const auto& itr : mAllAnomalyTrackers) {
- itr->informAlarmsFired(timestampNs, alarmSet);
- }
-}
-
-void MetricsManager::onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
- for (const auto& itr : mAllPeriodicAlarmTrackers) {
- itr->informAlarmsFired(timestampNs, alarmSet);
- }
-}
-
-// Returns the total byte size of all metrics managed by a single config source.
-size_t MetricsManager::byteSize() {
- size_t totalSize = 0;
- for (const auto& metricProducer : mAllMetricProducers) {
- totalSize += metricProducer->byteSize();
- }
- return totalSize;
-}
-
-void MetricsManager::loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs) {
- if (config.metric_size() == 0) {
- ALOGW("No active metric for config %s", mConfigKey.ToString().c_str());
- return;
- }
-
- for (int i = 0; i < config.metric_size(); i++) {
- const auto& activeMetric = config.metric(i);
- for (int metricIndex : mMetricIndexesWithActivation) {
- const auto& metric = mAllMetricProducers[metricIndex];
- if (metric->getMetricId() == activeMetric.id()) {
- VLOG("Setting active metric: %lld", (long long)metric->getMetricId());
- metric->loadActiveMetric(activeMetric, currentTimeNs);
- if (!mIsActive && metric->isActive()) {
- StatsdStats::getInstance().noteActiveStatusChanged(mConfigKey,
- /*activate=*/ true);
- }
- mIsActive |= metric->isActive();
- }
- }
- }
-}
-
-void MetricsManager::writeActiveConfigToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_CONFIG_ID, (long long)mConfigKey.GetId());
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_CONFIG_UID, mConfigKey.GetUid());
- for (int metricIndex : mMetricIndexesWithActivation) {
- const auto& metric = mAllMetricProducers[metricIndex];
- const uint64_t metricToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_CONFIG_METRIC);
- metric->writeActiveMetricToProtoOutputStream(currentTimeNs, reason, proto);
- proto->end(metricToken);
- }
-}
-
-bool MetricsManager::writeMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadata* statsMetadata) {
- bool metadataWritten = false;
- metadata::ConfigKey* configKey = statsMetadata->mutable_config_key();
- configKey->set_config_id(mConfigKey.GetId());
- configKey->set_uid(mConfigKey.GetUid());
- for (const auto& anomalyTracker : mAllAnomalyTrackers) {
- metadata::AlertMetadata* alertMetadata = statsMetadata->add_alert_metadata();
- bool alertWritten = anomalyTracker->writeAlertMetadataToProto(currentWallClockTimeNs,
- systemElapsedTimeNs, alertMetadata);
- if (!alertWritten) {
- statsMetadata->mutable_alert_metadata()->RemoveLast();
- }
- metadataWritten |= alertWritten;
- }
- return metadataWritten;
-}
-
-void MetricsManager::loadMetadata(const metadata::StatsMetadata& metadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs) {
- for (const metadata::AlertMetadata& alertMetadata : metadata.alert_metadata()) {
- int64_t alertId = alertMetadata.alert_id();
- auto it = mAlertTrackerMap.find(alertId);
- if (it == mAlertTrackerMap.end()) {
- ALOGE("No anomalyTracker found for alertId %lld", (long long) alertId);
- continue;
- }
- mAllAnomalyTrackers[it->second]->loadAlertMetadata(alertMetadata,
- currentWallClockTimeNs,
- systemElapsedTimeNs);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
deleted file mode 100644
index ad30a88c5d19..000000000000
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "anomaly/AlarmMonitor.h"
-#include "anomaly/AlarmTracker.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTracker.h"
-#include "config/ConfigKey.h"
-#include "external/StatsPullerManager.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-#include "logd/LogEvent.h"
-#include "matchers/LogMatchingTracker.h"
-#include "metrics/MetricProducer.h"
-#include "packages/UidMap.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// A MetricsManager is responsible for managing metrics from one single config source.
-class MetricsManager : public virtual android::RefBase, public virtual PullUidProvider {
-public:
- MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const int64_t timeBaseNs,
- const int64_t currentTimeNs, const sp<UidMap>& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor);
-
- virtual ~MetricsManager();
-
- // Return whether the configuration is valid.
- bool isConfigValid() const;
-
- bool checkLogCredentials(const LogEvent& event);
-
- bool eventSanityCheck(const LogEvent& event);
-
- void onLogEvent(const LogEvent& event);
-
- void onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
-
- void onPeriodicAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
-
- void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
- const int64_t version);
-
- void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid);
-
- void onUidMapReceived(const int64_t& eventTimeNs);
-
- void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
-
- void init();
-
- vector<int32_t> getPullAtomUids(int32_t atomId) override;
-
- bool shouldWriteToDisk() const {
- return mNoReportMetricIds.size() != mAllMetricProducers.size();
- }
-
- bool shouldPersistLocalHistory() const {
- return mShouldPersistHistory;
- }
-
- void dumpStates(FILE* out, bool verbose);
-
- inline bool isInTtl(const int64_t timestampNs) const {
- return mTtlNs <= 0 || timestampNs < mTtlEndNs;
- };
-
- inline bool hashStringInReport() const {
- return mHashStringsInReport;
- };
-
- inline bool versionStringsInReport() const {
- return mVersionStringsInReport;
- };
-
- inline bool installerInReport() const {
- return mInstallerInReport;
- };
-
- void refreshTtl(const int64_t currentTimestampNs) {
- if (mTtlNs > 0) {
- mTtlEndNs = currentTimestampNs + mTtlNs;
- }
- };
-
- // Returns the elapsed realtime when this metric manager last reported metrics. If this config
- // has not yet dumped any reports, this is the time the metricsmanager was initialized.
- inline int64_t getLastReportTimeNs() const {
- return mLastReportTimeNs;
- };
-
- inline int64_t getLastReportWallClockNs() const {
- return mLastReportWallClockNs;
- };
-
- inline size_t getNumMetrics() const {
- return mAllMetricProducers.size();
- }
-
- virtual void dropData(const int64_t dropTimeNs);
-
- virtual void onDumpReport(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput);
-
- // Computes the total byte size of all metrics managed by a single config source.
- // Does not change the state.
- virtual size_t byteSize();
-
- // Returns whether or not this config is active.
- // The config is active if any metric in the config is active.
- inline bool isActive() const {
- return mIsActive;
- }
-
- void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs);
-
- void writeActiveConfigToProtoOutputStream(
- int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
- // Returns true if at least one piece of metadata is written.
- bool writeMetadataToProto(int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs,
- metadata::StatsMetadata* statsMetadata);
-
- void loadMetadata(const metadata::StatsMetadata& metadata,
- int64_t currentWallClockTimeNs,
- int64_t systemElapsedTimeNs);
-private:
- // For test only.
- inline int64_t getTtlEndNs() const { return mTtlEndNs; }
-
- const ConfigKey mConfigKey;
-
- sp<UidMap> mUidMap;
-
- bool mConfigValid = false;
-
- bool mHashStringsInReport = false;
- bool mVersionStringsInReport = false;
- bool mInstallerInReport = false;
-
- const int64_t mTtlNs;
- int64_t mTtlEndNs;
-
- int64_t mLastReportTimeNs;
- int64_t mLastReportWallClockNs;
-
- sp<StatsPullerManager> mPullerManager;
-
- // The uid log sources from StatsdConfig.
- std::vector<int32_t> mAllowedUid;
-
- // The pkg log sources from StatsdConfig.
- std::vector<std::string> mAllowedPkg;
-
- // The combined uid sources (after translating pkg name to uid).
- // Logs from uids that are not in the list will be ignored to avoid spamming.
- std::set<int32_t> mAllowedLogSources;
-
- // To guard access to mAllowedLogSources
- mutable std::mutex mAllowedLogSourcesMutex;
-
- const std::set<int32_t> mWhitelistedAtomIds;
-
- // We can pull any atom from these uids.
- std::set<int32_t> mDefaultPullUids;
-
- // Uids that specific atoms can pull from.
- // This is a map<atom id, set<uids>>
- std::map<int32_t, std::set<int32_t>> mPullAtomUids;
-
- // Packages that specific atoms can be pulled from.
- std::map<int32_t, std::set<std::string>> mPullAtomPackages;
-
- // All uids to pull for this atom. NOTE: Does not include the default uids for memory.
- std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids;
-
- // Contains the annotations passed in with StatsdConfig.
- std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
-
- const bool mShouldPersistHistory;
-
-
- // All event tags that are interesting to my metrics.
- std::set<int> mTagIds;
-
- // We only store the sp of LogMatchingTracker, MetricProducer, and ConditionTracker in
- // MetricsManager. There are relationships between them, and the relationships are denoted by
- // index instead of pointers. The reasons for this are: (1) the relationship between them are
- // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B
- // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get
- // the related results from a cache using the index.
-
- // Hold all the atom matchers from the config.
- std::vector<sp<LogMatchingTracker>> mAllAtomMatchers;
-
- // Hold all the conditions from the config.
- std::vector<sp<ConditionTracker>> mAllConditionTrackers;
-
- // Hold all metrics from the config.
- std::vector<sp<MetricProducer>> mAllMetricProducers;
-
- // Hold all alert trackers.
- std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
-
- // Hold all periodic alarm trackers.
- std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
-
- // To make the log processing more efficient, we want to do as much filtering as possible
- // before we go into individual trackers and conditions to match.
-
- // 1st filter: check if the event tag id is in mTagIds.
- // 2nd filter: if it is, we parse the event because there is at least one member is interested.
- // then pass to all LogMatchingTrackers (itself also filter events by ids).
- // 3nd filter: for LogMatchingTrackers that matched this event, we pass this event to the
- // ConditionTrackers and MetricProducers that use this matcher.
- // 4th filter: for ConditionTrackers that changed value due to this event, we pass
- // new conditions to metrics that use this condition.
-
- // The following map is initialized from the statsd_config.
-
- // Maps from the index of the LogMatchingTracker to index of MetricProducer.
- std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
-
- // Maps from LogMatchingTracker to ConditionTracker
- std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
-
- // Maps from ConditionTracker to MetricProducer
- std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
-
- // Maps from life span triggering event to MetricProducers.
- std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;
-
- // Maps deactivation triggering event to MetricProducers.
- std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap;
-
- // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers.
- // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId.
- std::unordered_map<int64_t, int> mAlertTrackerMap;
-
- std::vector<int> mMetricIndexesWithActivation;
-
- void initLogSourceWhiteList();
-
- void initPullAtomSources();
-
- // The metrics that don't need to be uploaded or even reported.
- std::set<int64_t> mNoReportMetricIds;
-
- // The config is active if any metric in the config is active.
- bool mIsActive;
-
- // The config is always active if any metric in the config does not have an activation signal.
- bool mIsAlwaysActive;
-
- FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
- FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
- FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
- FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
- FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
- FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
-
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
- FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
- FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
- FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
- FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
- FRIEND_TEST(MetricsManagerTest, TestLogSources);
-
- FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
- FRIEND_TEST(StatsLogProcessorTest,
- TestActivationOnBootMultipleActivationsDifferentActivationTypes);
- FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
- FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
- FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
- FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-
- FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
- FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
- FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSuperset);
- FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
- FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
- FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
- FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
deleted file mode 100644
index 9b684f1248c5..000000000000
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ /dev/null
@@ -1,1160 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "ValueMetricProducer.h"
-#include "../guardrail/StatsdStats.h"
-#include "../stats_log_util.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_DOUBLE;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::shared_ptr;
-using std::unordered_map;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_VALUE_METRICS = 7;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for ValueMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-const int FIELD_ID_SKIPPED = 2;
-// for SkippedBuckets
-const int FIELD_ID_SKIPPED_START_MILLIS = 3;
-const int FIELD_ID_SKIPPED_END_MILLIS = 4;
-const int FIELD_ID_SKIPPED_DROP_EVENT = 5;
-// for DumpEvent Proto
-const int FIELD_ID_BUCKET_DROP_REASON = 1;
-const int FIELD_ID_DROP_TIME = 2;
-// for ValueMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-// for ValueBucketInfo
-const int FIELD_ID_VALUE_INDEX = 1;
-const int FIELD_ID_VALUE_LONG = 2;
-const int FIELD_ID_VALUE_DOUBLE = 3;
-const int FIELD_ID_VALUES = 9;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-const int FIELD_ID_CONDITION_TRUE_NS = 10;
-
-const Value ZERO_LONG((int64_t)0);
-const Value ZERO_DOUBLE((int64_t)0);
-
-// ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
-ValueMetricProducer::ValueMetricProducer(
- const ConfigKey& key, const ValueMetric& metric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
- const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int64_t timeBaseNs,
- const int64_t startTimeNs, const sp<StatsPullerManager>& pullerManager,
- const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
- const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache,
- conditionWizard, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
- stateGroupMap),
- mWhatMatcherIndex(whatMatcherIndex),
- mEventMatcherWizard(matcherWizard),
- mPullerManager(pullerManager),
- mPullTagId(pullTagId),
- mIsPulled(pullTagId != -1),
- mMinBucketSizeNs(metric.min_bucket_size_nanos()),
- mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first
- : StatsdStats::kDimensionKeySizeSoftLimit),
- mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
- StatsdStats::kAtomDimensionKeySizeLimitMap.end()
- ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
- : StatsdStats::kDimensionKeySizeHardLimit),
- mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()),
- mAggregationType(metric.aggregation_type()),
- mUseDiff(metric.has_use_diff() ? metric.use_diff() : (mIsPulled ? true : false)),
- mValueDirection(metric.value_direction()),
- mSkipZeroDiffOutput(metric.skip_zero_diff_output()),
- mUseZeroDefaultBase(metric.use_zero_default_base()),
- mHasGlobalBase(false),
- mCurrentBucketIsSkipped(false),
- mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
- : StatsdStats::kPullMaxDelayNs),
- mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()),
- // Condition timer will be set later within the constructor after pulling events
- mConditionTimer(false, timeBaseNs) {
- int64_t bucketSizeMills = 0;
- if (metric.has_bucket()) {
- bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
- } else {
- bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
- }
-
- mBucketSizeNs = bucketSizeMills * 1000000;
-
- translateFieldMatcher(metric.value_field(), &mFieldMatchers);
-
- if (metric.has_dimensions_in_what()) {
- translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
- mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
- mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
- }
-
- if (metric.links().size() > 0) {
- for (const auto& link : metric.links()) {
- Metric2Condition mc;
- mc.conditionId = link.condition();
- translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
- translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
- mMetric2ConditionLinks.push_back(mc);
- }
- mConditionSliced = true;
- }
-
- for (const auto& stateLink : metric.state_link()) {
- Metric2State ms;
- ms.stateAtomId = stateLink.state_atom_id();
- translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
- translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
- }
-
- int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs);
- mCurrentBucketNum += numBucketsForward;
-
- flushIfNeededLocked(startTimeNs);
-
- if (mIsPulled) {
- mPullerManager->RegisterReceiver(mPullTagId, mConfigKey, this, getCurrentBucketEndTimeNs(),
- mBucketSizeNs);
- }
-
- // Only do this for partial buckets like first bucket. All other buckets should use
- // flushIfNeeded to adjust start and end to bucket boundaries.
- // Adjust start for partial bucket
- mCurrentBucketStartTimeNs = startTimeNs;
- mConditionTimer.newBucketStart(mCurrentBucketStartTimeNs);
-
- // Now that activations are processed, start the condition timer if needed.
- mConditionTimer.onConditionChanged(mIsActive && mCondition == ConditionState::kTrue,
- mCurrentBucketStartTimeNs);
-
- VLOG("value metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-ValueMetricProducer::~ValueMetricProducer() {
- VLOG("~ValueMetricProducer() called");
- if (mIsPulled) {
- mPullerManager->UnRegisterReceiver(mPullTagId, mConfigKey, this);
- }
-}
-
-void ValueMetricProducer::onStateChanged(int64_t eventTimeNs, int32_t atomId,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) {
- VLOG("ValueMetric %lld onStateChanged time %lld, State %d, key %s, %d -> %d",
- (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
- oldState.mValue.int_value, newState.mValue.int_value);
-
- // If old and new states are in the same StateGroup, then we do not need to
- // pull for this state change.
- FieldValue oldStateCopy = oldState;
- FieldValue newStateCopy = newState;
- mapStateValue(atomId, &oldStateCopy);
- mapStateValue(atomId, &newStateCopy);
- if (oldStateCopy == newStateCopy) {
- return;
- }
-
- // If condition is not true or metric is not active, we do not need to pull
- // for this state change.
- if (mCondition != ConditionState::kTrue || !mIsActive) {
- return;
- }
-
- bool isEventLate = eventTimeNs < mCurrentBucketStartTimeNs;
- if (isEventLate) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- return;
- }
- mStateChangePrimaryKey.first = atomId;
- mStateChangePrimaryKey.second = primaryKey;
- if (mIsPulled) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- mStateChangePrimaryKey.first = 0;
- mStateChangePrimaryKey.second = DEFAULT_DIMENSION_KEY;
- flushIfNeededLocked(eventTimeNs);
-}
-
-void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const int64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-}
-
-void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
- StatsdStats::getInstance().noteBucketDropped(mMetricId);
-
- // The current partial bucket is not flushed and does not require a pull,
- // so the data is still valid.
- flushIfNeededLocked(dropTimeNs);
- clearPastBucketsLocked(dropTimeNs);
-}
-
-void ValueMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
- mPastBuckets.clear();
- mSkippedBuckets.clear();
-}
-
-void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- VLOG("metric %lld dump report now...", (long long)mMetricId);
- if (include_current_partial_bucket) {
- // For pull metrics, we need to do a pull at bucket boundaries. If we do not do that the
- // current bucket will have incomplete data and the next will have the wrong snapshot to do
- // a diff against. If the condition is false, we are fine since the base data is reset and
- // we are not tracking anything.
- bool pullNeeded = mIsPulled && mCondition == ConditionState::kTrue;
- if (pullNeeded) {
- switch (dumpLatency) {
- case FAST:
- invalidateCurrentBucket(dumpTimeNs, BucketDropReason::DUMP_REPORT_REQUESTED);
- break;
- case NO_TIME_CONSTRAINTS:
- pullAndMatchEventsLocked(dumpTimeNs);
- break;
- }
- }
- flushCurrentBucketLocked(dumpTimeNs, dumpTimeNs);
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
- if (mPastBuckets.empty() && mSkippedBuckets.empty()) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
- // Fills the dimension path if not slicing by ALL.
- if (!mSliceByPositionALL) {
- if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
- writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
- protoOutput->end(dimenPathToken);
- }
- }
-
- uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_VALUE_METRICS);
-
- for (const auto& skippedBucket : mSkippedBuckets) {
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SKIPPED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_START_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketStartTimeNs)));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_END_MILLIS,
- (long long)(NanoToMillis(skippedBucket.bucketEndTimeNs)));
- for (const auto& dropEvent : skippedBucket.dropEvents) {
- uint64_t dropEventToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SKIPPED_DROP_EVENT);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_BUCKET_DROP_REASON, dropEvent.reason);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DROP_TIME,
- (long long)(NanoToMillis(dropEvent.dropTimeNs)));
- ;
- protoOutput->end(dropEventToken);
- }
- protoOutput->end(wrapperToken);
- }
-
- for (const auto& pair : mPastBuckets) {
- const MetricDimensionKey& dimensionKey = pair.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
- uint64_t wrapperToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
- // First fill dimension.
- if (mSliceByPositionALL) {
- uint64_t dimensionToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
- protoOutput->end(dimensionToken);
- } else {
- writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
- FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
- }
-
- // Then fill slice_by_state.
- for (auto state : dimensionKey.getStateValuesKey().getValues()) {
- uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SLICE_BY_STATE);
- writeStateToProto(state, protoOutput);
- protoOutput->end(stateToken);
- }
-
- // Then fill bucket_info (ValueBucketInfo).
- for (const auto& bucket : pair.second) {
- uint64_t bucketInfoToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-
- if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketStartNs));
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
- (long long)NanoToMillis(bucket.mBucketEndNs));
- } else {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
- (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
- }
- // only write the condition timer value if the metric has a condition.
- if (mConditionTrackerIndex >= 0) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_TRUE_NS,
- (long long)bucket.mConditionTrueNs);
- }
- for (int i = 0; i < (int)bucket.valueIndex.size(); i++) {
- int index = bucket.valueIndex[i];
- const Value& value = bucket.values[i];
- uint64_t valueToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_VALUES);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_VALUE_INDEX,
- index);
- if (value.getType() == LONG) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_LONG,
- (long long)value.long_value);
- VLOG("\t bucket [%lld - %lld] value %d: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, index, (long long)value.long_value);
- } else if (value.getType() == DOUBLE) {
- protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE,
- value.double_value);
- VLOG("\t bucket [%lld - %lld] value %d: %.2f", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, index, value.double_value);
- } else {
- VLOG("Wrong value type for ValueMetric output: %d", value.getType());
- }
- protoOutput->end(valueToken);
- }
- protoOutput->end(bucketInfoToken);
- }
- protoOutput->end(wrapperToken);
- }
- protoOutput->end(protoToken);
-
- VLOG("metric %lld dump report now...", (long long)mMetricId);
- if (erase_data) {
- mPastBuckets.clear();
- mSkippedBuckets.clear();
- }
-}
-
-void ValueMetricProducer::invalidateCurrentBucketWithoutResetBase(const int64_t dropTimeNs,
- const BucketDropReason reason) {
- if (!mCurrentBucketIsSkipped) {
- // Only report to StatsdStats once per invalid bucket.
- StatsdStats::getInstance().noteInvalidatedBucket(mMetricId);
- }
-
- skipCurrentBucket(dropTimeNs, reason);
-}
-
-void ValueMetricProducer::invalidateCurrentBucket(const int64_t dropTimeNs,
- const BucketDropReason reason) {
- invalidateCurrentBucketWithoutResetBase(dropTimeNs, reason);
- resetBase();
-}
-
-void ValueMetricProducer::skipCurrentBucket(const int64_t dropTimeNs,
- const BucketDropReason reason) {
- if (!maxDropEventsReached()) {
- mCurrentSkippedBucket.dropEvents.emplace_back(buildDropEvent(dropTimeNs, reason));
- }
- mCurrentBucketIsSkipped = true;
-}
-
-void ValueMetricProducer::resetBase() {
- for (auto& slice : mCurrentBaseInfo) {
- for (auto& baseInfo : slice.second) {
- baseInfo.hasBase = false;
- }
- }
- mHasGlobalBase = false;
-}
-
-// Handle active state change. Active state change is treated like a condition change:
-// - drop bucket if active state change event arrives too late
-// - if condition is true, pull data on active state changes
-// - ConditionTimer tracks changes based on AND of condition and active state.
-void ValueMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
- bool isEventTooLate = eventTimeNs < mCurrentBucketStartTimeNs;
- if (isEventTooLate) {
- // Drop bucket because event arrived too late, ie. we are missing data for this bucket.
- StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- }
-
- // Call parent method once we've verified the validity of current bucket.
- MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-
- if (ConditionState::kTrue != mCondition) {
- return;
- }
-
- // Pull on active state changes.
- if (!isEventTooLate) {
- if (mIsPulled) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- // When active state changes from true to false, clear diff base but don't
- // reset other counters as we may accumulate more value in the bucket.
- if (mUseDiff && !mIsActive) {
- resetBase();
- }
- }
-
- flushIfNeededLocked(eventTimeNs);
-
- // Let condition timer know of new active state.
- mConditionTimer.onConditionChanged(mIsActive, eventTimeNs);
-}
-
-void ValueMetricProducer::onConditionChangedLocked(const bool condition,
- const int64_t eventTimeNs) {
- ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
- bool isEventTooLate = eventTimeNs < mCurrentBucketStartTimeNs;
-
- // If the config is not active, skip the event.
- if (!mIsActive) {
- mCondition = isEventTooLate ? ConditionState::kUnknown : newCondition;
- return;
- }
-
- // If the event arrived late, mark the bucket as invalid and skip the event.
- if (isEventTooLate) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- mCondition = ConditionState::kUnknown;
- mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
- return;
- }
-
- // If the previous condition was unknown, mark the bucket as invalid
- // because the bucket will contain partial data. For example, the condition
- // change might happen close to the end of the bucket and we might miss a
- // lot of data.
- //
- // We still want to pull to set the base.
- if (mCondition == ConditionState::kUnknown) {
- invalidateCurrentBucket(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
- }
-
- // Pull and match for the following condition change cases:
- // unknown/false -> true - condition changed
- // true -> false - condition changed
- // true -> true - old condition was true so we can flush the bucket at the
- // end if needed.
- //
- // We don’t need to pull for unknown -> false or false -> false.
- //
- // onConditionChangedLocked might happen on bucket boundaries if this is
- // called before #onDataPulled.
- if (mIsPulled &&
- (newCondition == ConditionState::kTrue || mCondition == ConditionState::kTrue)) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
-
- // For metrics that use diff, when condition changes from true to false,
- // clear diff base but don't reset other counts because we may accumulate
- // more value in the bucket.
- if (mUseDiff &&
- (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)) {
- resetBase();
- }
-
- // Update condition state after pulling.
- mCondition = newCondition;
-
- flushIfNeededLocked(eventTimeNs);
- mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
-}
-
-void ValueMetricProducer::prepareFirstBucketLocked() {
- // Kicks off the puller immediately if condition is true and diff based.
- if (mIsActive && mIsPulled && mCondition == ConditionState::kTrue && mUseDiff) {
- pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
- }
-}
-
-void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
- vector<std::shared_ptr<LogEvent>> allData;
- if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
- ALOGE("Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
- invalidateCurrentBucket(timestampNs, BucketDropReason::PULL_FAILED);
- return;
- }
-
- accumulateEvents(allData, timestampNs, timestampNs);
-}
-
-int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTimeNs) {
- return mTimeBaseNs + ((currentTimeNs - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
-}
-
-// By design, statsd pulls data at bucket boundaries using AlarmManager. These pulls are likely
-// to be delayed. Other events like condition changes or app upgrade which are not based on
-// AlarmManager might have arrived earlier and close the bucket.
-void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
- bool pullSuccess, int64_t originalPullTimeNs) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mCondition == ConditionState::kTrue) {
- // If the pull failed, we won't be able to compute a diff.
- if (!pullSuccess) {
- invalidateCurrentBucket(originalPullTimeNs, BucketDropReason::PULL_FAILED);
- } else {
- bool isEventLate = originalPullTimeNs < getCurrentBucketEndTimeNs();
- if (isEventLate) {
- // If the event is late, we are in the middle of a bucket. Just
- // process the data without trying to snap the data to the nearest bucket.
- accumulateEvents(allData, originalPullTimeNs, originalPullTimeNs);
- } else {
- // For scheduled pulled data, the effective event time is snap to the nearest
- // bucket end. In the case of waking up from a deep sleep state, we will
- // attribute to the previous bucket end. If the sleep was long but not very
- // long, we will be in the immediate next bucket. Previous bucket may get a
- // larger number as we pull at a later time than real bucket end.
- //
- // If the sleep was very long, we skip more than one bucket before sleep. In
- // this case, if the diff base will be cleared and this new data will serve as
- // new diff base.
- int64_t bucketEndTime = calcPreviousBucketEndTime(originalPullTimeNs) - 1;
- StatsdStats::getInstance().noteBucketBoundaryDelayNs(
- mMetricId, originalPullTimeNs - bucketEndTime);
- accumulateEvents(allData, originalPullTimeNs, bucketEndTime);
- }
- }
- }
-
- // We can probably flush the bucket. Since we used bucketEndTime when calling
- // #onMatchedLogEventInternalLocked, the current bucket will not have been flushed.
- flushIfNeededLocked(originalPullTimeNs);
-}
-
-void ValueMetricProducer::accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
- int64_t originalPullTimeNs, int64_t eventElapsedTimeNs) {
- bool isEventLate = eventElapsedTimeNs < mCurrentBucketStartTimeNs;
- if (isEventLate) {
- VLOG("Skip bucket end pull due to late arrival: %lld vs %lld",
- (long long)eventElapsedTimeNs, (long long)mCurrentBucketStartTimeNs);
- StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
- return;
- }
-
- const int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
- const int64_t pullDelayNs = elapsedRealtimeNs - originalPullTimeNs;
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- if (pullDelayNs > mMaxPullDelayNs) {
- ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId,
- (long long)mMaxPullDelayNs);
- StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- // We are missing one pull from the bucket which means we will not have a complete view of
- // what's going on.
- invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::PULL_DELAYED);
- return;
- }
-
- mMatchedMetricDimensionKeys.clear();
- for (const auto& data : allData) {
- LogEvent localCopy = data->makeCopy();
- if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
- MatchingState::kMatched) {
- localCopy.setElapsedTimestampNs(eventElapsedTimeNs);
- onMatchedLogEventLocked(mWhatMatcherIndex, localCopy);
- }
- }
- // If a key that is:
- // 1. Tracked in mCurrentSlicedBucket and
- // 2. A superset of the current mStateChangePrimaryKey
- // was not found in the new pulled data (i.e. not in mMatchedDimensionInWhatKeys)
- // then we need to reset the base.
- for (auto& slice : mCurrentSlicedBucket) {
- const auto& whatKey = slice.first.getDimensionKeyInWhat();
- bool presentInPulledData =
- mMatchedMetricDimensionKeys.find(whatKey) != mMatchedMetricDimensionKeys.end();
- if (!presentInPulledData && whatKey.contains(mStateChangePrimaryKey.second)) {
- auto it = mCurrentBaseInfo.find(whatKey);
- for (auto& baseInfo : it->second) {
- baseInfo.hasBase = false;
- }
- }
- }
- mMatchedMetricDimensionKeys.clear();
- mHasGlobalBase = true;
-
- // If we reach the guardrail, we might have dropped some data which means the bucket is
- // incomplete.
- //
- // The base also needs to be reset. If we do not have the full data, we might
- // incorrectly compute the diff when mUseZeroDefaultBase is true since an existing key
- // might be missing from mCurrentSlicedBucket.
- if (hasReachedGuardRailLimit()) {
- invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::DIMENSION_GUARDRAIL_REACHED);
- mCurrentSlicedBucket.clear();
- }
-}
-
-void ValueMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
- if (mCurrentSlicedBucket.size() == 0) {
- return;
- }
-
- fprintf(out, "ValueMetric %lld dimension size %lu\n", (long long)mMetricId,
- (unsigned long)mCurrentSlicedBucket.size());
- if (verbose) {
- for (const auto& it : mCurrentSlicedBucket) {
- for (const auto& interval : it.second) {
- fprintf(out, "\t(what)%s\t(states)%s (value)%s\n",
- it.first.getDimensionKeyInWhat().toString().c_str(),
- it.first.getStateValuesKey().toString().c_str(),
- interval.value.toString().c_str());
- }
- }
- }
-}
-
-bool ValueMetricProducer::hasReachedGuardRailLimit() const {
- return mCurrentSlicedBucket.size() >= mDimensionHardLimit;
-}
-
-bool ValueMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentSlicedBucket.find(newKey) != mCurrentSlicedBucket.end()) {
- return false;
- }
- if (mCurrentSlicedBucket.size() > mDimensionSoftLimit - 1) {
- size_t newTupleCount = mCurrentSlicedBucket.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (hasReachedGuardRailLimit()) {
- ALOGE("ValueMetric %lld dropping data for dimension key %s", (long long)mMetricId,
- newKey.toString().c_str());
- StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
- return true;
- }
- }
-
- return false;
-}
-
-bool ValueMetricProducer::hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey) {
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mCurrentFullBucket.find(newKey) != mCurrentFullBucket.end()) {
- return false;
- }
- if (mCurrentFullBucket.size() > mDimensionSoftLimit - 1) {
- size_t newTupleCount = mCurrentFullBucket.size() + 1;
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > mDimensionHardLimit) {
- ALOGE("ValueMetric %lld dropping data for full bucket dimension key %s",
- (long long)mMetricId,
- newKey.toString().c_str());
- return true;
- }
- }
-
- return false;
-}
-
-bool getDoubleOrLong(const LogEvent& event, const Matcher& matcher, Value& ret) {
- for (const FieldValue& value : event.getValues()) {
- if (value.mField.matches(matcher)) {
- switch (value.mValue.type) {
- case INT:
- ret.setLong(value.mValue.int_value);
- break;
- case LONG:
- ret.setLong(value.mValue.long_value);
- break;
- case FLOAT:
- ret.setDouble(value.mValue.float_value);
- break;
- case DOUBLE:
- ret.setDouble(value.mValue.double_value);
- break;
- default:
- return false;
- break;
- }
- return true;
- }
- }
- return false;
-}
-
-bool ValueMetricProducer::multipleBucketsSkipped(const int64_t numBucketsForward) {
- // Skip buckets if this is a pulled metric or a pushed metric that is diffed.
- return numBucketsForward > 1 && (mIsPulled || mUseDiff);
-}
-
-void ValueMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const map<int, HashableDimensionKey>& statePrimaryKeys) {
- auto whatKey = eventKey.getDimensionKeyInWhat();
- auto stateKey = eventKey.getStateValuesKey();
-
- // Skip this event if a state changed occurred for a different primary key.
- auto it = statePrimaryKeys.find(mStateChangePrimaryKey.first);
- // Check that both the atom id and the primary key are equal.
- if (it != statePrimaryKeys.end() && it->second != mStateChangePrimaryKey.second) {
- VLOG("ValueMetric skip event with primary key %s because state change primary key "
- "is %s",
- it->second.toString().c_str(), mStateChangePrimaryKey.second.toString().c_str());
- return;
- }
-
- int64_t eventTimeNs = event.GetElapsedTimestampNs();
- if (eventTimeNs < mCurrentBucketStartTimeNs) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
- (long long)mCurrentBucketStartTimeNs);
- return;
- }
- mMatchedMetricDimensionKeys.insert(whatKey);
-
- if (!mIsPulled) {
- // We cannot flush without doing a pull first.
- flushIfNeededLocked(eventTimeNs);
- }
-
- // We should not accumulate the data for pushed metrics when the condition is false.
- bool shouldSkipForPushMetric = !mIsPulled && !condition;
- // For pulled metrics, there are two cases:
- // - to compute diffs, we need to process all the state changes
- // - for non-diffs metrics, we should ignore the data if the condition wasn't true. If we have a
- // state change from
- // + True -> True: we should process the data, it might be a bucket boundary
- // + True -> False: we als need to process the data.
- bool shouldSkipForPulledMetric = mIsPulled && !mUseDiff
- && mCondition != ConditionState::kTrue;
- if (shouldSkipForPushMetric || shouldSkipForPulledMetric) {
- VLOG("ValueMetric skip event because condition is false and we are not using diff (for "
- "pulled metric)");
- return;
- }
-
- if (hitGuardRailLocked(eventKey)) {
- return;
- }
-
- vector<BaseInfo>& baseInfos = mCurrentBaseInfo[whatKey];
- if (baseInfos.size() < mFieldMatchers.size()) {
- VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
- baseInfos.resize(mFieldMatchers.size());
- }
-
- for (BaseInfo& baseInfo : baseInfos) {
- if (!baseInfo.hasCurrentState) {
- baseInfo.currentState = getUnknownStateKey();
- baseInfo.hasCurrentState = true;
- }
- }
-
- // We need to get the intervals stored with the previous state key so we can
- // close these value intervals.
- const auto oldStateKey = baseInfos[0].currentState;
- vector<Interval>& intervals = mCurrentSlicedBucket[MetricDimensionKey(whatKey, oldStateKey)];
- if (intervals.size() < mFieldMatchers.size()) {
- VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
- intervals.resize(mFieldMatchers.size());
- }
-
- // We only use anomaly detection under certain cases.
- // N.B.: The anomaly detection cases were modified in order to fix an issue with value metrics
- // containing multiple values. We tried to retain all previous behaviour, but we are unsure the
- // previous behaviour was correct. At the time of the fix, anomaly detection had no owner.
- // Whoever next works on it should look into the cases where it is triggered in this function.
- // Discussion here: http://ag/6124370.
- bool useAnomalyDetection = true;
-
- for (int i = 0; i < (int)mFieldMatchers.size(); i++) {
- const Matcher& matcher = mFieldMatchers[i];
- BaseInfo& baseInfo = baseInfos[i];
- Interval& interval = intervals[i];
- interval.valueIndex = i;
- Value value;
- baseInfo.hasCurrentState = true;
- baseInfo.currentState = stateKey;
- if (!getDoubleOrLong(event, matcher, value)) {
- VLOG("Failed to get value %d from event %s", i, event.ToString().c_str());
- StatsdStats::getInstance().noteBadValueType(mMetricId);
- return;
- }
- interval.seenNewData = true;
-
- if (mUseDiff) {
- if (!baseInfo.hasBase) {
- if (mHasGlobalBase && mUseZeroDefaultBase) {
- // The bucket has global base. This key does not.
- // Optionally use zero as base.
- baseInfo.base = (value.type == LONG ? ZERO_LONG : ZERO_DOUBLE);
- baseInfo.hasBase = true;
- } else {
- // no base. just update base and return.
- baseInfo.base = value;
- baseInfo.hasBase = true;
- // If we're missing a base, do not use anomaly detection on incomplete data
- useAnomalyDetection = false;
- // Continue (instead of return) here in order to set baseInfo.base and
- // baseInfo.hasBase for other baseInfos
- continue;
- }
- }
-
- Value diff;
- switch (mValueDirection) {
- case ValueMetric::INCREASING:
- if (value >= baseInfo.base) {
- diff = value - baseInfo.base;
- } else if (mUseAbsoluteValueOnReset) {
- diff = value;
- } else {
- VLOG("Unexpected decreasing value");
- StatsdStats::getInstance().notePullDataError(mPullTagId);
- baseInfo.base = value;
- // If we've got bad data, do not use anomaly detection
- useAnomalyDetection = false;
- continue;
- }
- break;
- case ValueMetric::DECREASING:
- if (baseInfo.base >= value) {
- diff = baseInfo.base - value;
- } else if (mUseAbsoluteValueOnReset) {
- diff = value;
- } else {
- VLOG("Unexpected increasing value");
- StatsdStats::getInstance().notePullDataError(mPullTagId);
- baseInfo.base = value;
- // If we've got bad data, do not use anomaly detection
- useAnomalyDetection = false;
- continue;
- }
- break;
- case ValueMetric::ANY:
- diff = value - baseInfo.base;
- break;
- default:
- break;
- }
- baseInfo.base = value;
- value = diff;
- }
-
- if (interval.hasValue) {
- switch (mAggregationType) {
- case ValueMetric::SUM:
- // for AVG, we add up and take average when flushing the bucket
- case ValueMetric::AVG:
- interval.value += value;
- break;
- case ValueMetric::MIN:
- interval.value = std::min(value, interval.value);
- break;
- case ValueMetric::MAX:
- interval.value = std::max(value, interval.value);
- break;
- default:
- break;
- }
- } else {
- interval.value = value;
- interval.hasValue = true;
- }
- interval.sampleSize += 1;
- }
-
- // Only trigger the tracker if all intervals are correct and we have not skipped the bucket due
- // to MULTIPLE_BUCKETS_SKIPPED.
- if (useAnomalyDetection && !multipleBucketsSkipped(calcBucketsForwardCount(eventTimeNs))) {
- // TODO: propgate proper values down stream when anomaly support doubles
- long wholeBucketVal = intervals[0].value.long_value;
- auto prev = mCurrentFullBucket.find(eventKey);
- if (prev != mCurrentFullBucket.end()) {
- wholeBucketVal += prev->second;
- }
- for (auto& tracker : mAnomalyTrackers) {
- tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId, eventKey,
- wholeBucketVal);
- }
- }
-}
-
-// For pulled metrics, we always need to make sure we do a pull before flushing the bucket
-// if mCondition is true!
-void ValueMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
- if (eventTimeNs < currentBucketEndTimeNs) {
- VLOG("eventTime is %lld, less than current bucket end time %lld", (long long)eventTimeNs,
- (long long)(currentBucketEndTimeNs));
- return;
- }
- int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
- int64_t nextBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
- flushCurrentBucketLocked(eventTimeNs, nextBucketStartTimeNs);
-}
-
-int64_t ValueMetricProducer::calcBucketsForwardCount(const int64_t& eventTimeNs) const {
- int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
- if (eventTimeNs < currentBucketEndTimeNs) {
- return 0;
- }
- return 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-}
-
-void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) {
- if (mCondition == ConditionState::kUnknown) {
- StatsdStats::getInstance().noteBucketUnknownCondition(mMetricId);
- invalidateCurrentBucketWithoutResetBase(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
- }
-
- VLOG("finalizing bucket for %ld, dumping %d slices", (long)mCurrentBucketStartTimeNs,
- (int)mCurrentSlicedBucket.size());
-
- int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- int64_t bucketEndTime = fullBucketEndTimeNs;
- int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
-
- if (multipleBucketsSkipped(numBucketsForward)) {
- VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
- StatsdStats::getInstance().noteSkippedForwardBuckets(mMetricId);
- // Something went wrong. Maybe the device was sleeping for a long time. It is better
- // to mark the current bucket as invalid. The last pull might have been successful through.
- invalidateCurrentBucketWithoutResetBase(eventTimeNs,
- BucketDropReason::MULTIPLE_BUCKETS_SKIPPED);
- // End the bucket at the next bucket start time so the entire interval is skipped.
- bucketEndTime = nextBucketStartTimeNs;
- } else if (eventTimeNs < fullBucketEndTimeNs) {
- bucketEndTime = eventTimeNs;
- }
-
- // Close the current bucket.
- int64_t conditionTrueDuration = mConditionTimer.newBucketStart(bucketEndTime);
- bool isBucketLargeEnough = bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
- if (!isBucketLargeEnough) {
- skipCurrentBucket(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL);
- }
- if (!mCurrentBucketIsSkipped) {
- bool bucketHasData = false;
- // The current bucket is large enough to keep.
- for (const auto& slice : mCurrentSlicedBucket) {
- ValueBucket bucket = buildPartialBucket(bucketEndTime, slice.second);
- bucket.mConditionTrueNs = conditionTrueDuration;
- // it will auto create new vector of ValuebucketInfo if the key is not found.
- if (bucket.valueIndex.size() > 0) {
- auto& bucketList = mPastBuckets[slice.first];
- bucketList.push_back(bucket);
- bucketHasData = true;
- }
- }
- if (!bucketHasData) {
- skipCurrentBucket(eventTimeNs, BucketDropReason::NO_DATA);
- }
- }
-
- if (mCurrentBucketIsSkipped) {
- mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs;
- mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime;
- mSkippedBuckets.emplace_back(mCurrentSkippedBucket);
- }
-
- // This means that the current bucket was not flushed before a forced bucket split.
- // This can happen if an app update or a dump report with include_current_partial_bucket is
- // requested before we get a chance to flush the bucket due to receiving new data, either from
- // the statsd socket or the StatsPullerManager.
- if (bucketEndTime < nextBucketStartTimeNs) {
- SkippedBucket bucketInGap;
- bucketInGap.bucketStartTimeNs = bucketEndTime;
- bucketInGap.bucketEndTimeNs = nextBucketStartTimeNs;
- bucketInGap.dropEvents.emplace_back(
- buildDropEvent(eventTimeNs, BucketDropReason::NO_DATA));
- mSkippedBuckets.emplace_back(bucketInGap);
- }
-
- appendToFullBucket(eventTimeNs > fullBucketEndTimeNs);
- initCurrentSlicedBucket(nextBucketStartTimeNs);
- // Update the condition timer again, in case we skipped buckets.
- mConditionTimer.newBucketStart(nextBucketStartTimeNs);
- mCurrentBucketNum += numBucketsForward;
-}
-
-ValueBucket ValueMetricProducer::buildPartialBucket(int64_t bucketEndTime,
- const std::vector<Interval>& intervals) {
- ValueBucket bucket;
- bucket.mBucketStartNs = mCurrentBucketStartTimeNs;
- bucket.mBucketEndNs = bucketEndTime;
- for (const auto& interval : intervals) {
- if (interval.hasValue) {
- // skip the output if the diff is zero
- if (mSkipZeroDiffOutput && mUseDiff && interval.value.isZero()) {
- continue;
- }
- bucket.valueIndex.push_back(interval.valueIndex);
- if (mAggregationType != ValueMetric::AVG) {
- bucket.values.push_back(interval.value);
- } else {
- double sum = interval.value.type == LONG ? (double)interval.value.long_value
- : interval.value.double_value;
- bucket.values.push_back(Value((double)sum / interval.sampleSize));
- }
- }
- }
- return bucket;
-}
-
-void ValueMetricProducer::initCurrentSlicedBucket(int64_t nextBucketStartTimeNs) {
- StatsdStats::getInstance().noteBucketCount(mMetricId);
- // Cleanup data structure to aggregate values.
- for (auto it = mCurrentSlicedBucket.begin(); it != mCurrentSlicedBucket.end();) {
- bool obsolete = true;
- for (auto& interval : it->second) {
- interval.hasValue = false;
- interval.sampleSize = 0;
- if (interval.seenNewData) {
- obsolete = false;
- }
- interval.seenNewData = false;
- }
-
- if (obsolete) {
- it = mCurrentSlicedBucket.erase(it);
- } else {
- it++;
- }
- // TODO(b/157655103): remove mCurrentBaseInfo entries when obsolete
- }
-
- mCurrentBucketIsSkipped = false;
- mCurrentSkippedBucket.reset();
-
- // If we do not have a global base when the condition is true,
- // we will have incomplete bucket for the next bucket.
- if (mUseDiff && !mHasGlobalBase && mCondition) {
- mCurrentBucketIsSkipped = false;
- }
- mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
- VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
- (long long)mCurrentBucketStartTimeNs);
-}
-
-void ValueMetricProducer::appendToFullBucket(const bool isFullBucketReached) {
- if (mCurrentBucketIsSkipped) {
- if (isFullBucketReached) {
- // If the bucket is invalid, we ignore the full bucket since it contains invalid data.
- mCurrentFullBucket.clear();
- }
- // Current bucket is invalid, we do not add it to the full bucket.
- return;
- }
-
- if (isFullBucketReached) { // If full bucket, send to anomaly tracker.
- // Accumulate partial buckets with current value and then send to anomaly tracker.
- if (mCurrentFullBucket.size() > 0) {
- for (const auto& slice : mCurrentSlicedBucket) {
- if (hitFullBucketGuardRailLocked(slice.first)) {
- continue;
- }
- // TODO: fix this when anomaly can accept double values
- auto& interval = slice.second[0];
- if (interval.hasValue) {
- mCurrentFullBucket[slice.first] += interval.value.long_value;
- }
- }
- for (const auto& slice : mCurrentFullBucket) {
- for (auto& tracker : mAnomalyTrackers) {
- if (tracker != nullptr) {
- tracker->addPastBucket(slice.first, slice.second, mCurrentBucketNum);
- }
- }
- }
- mCurrentFullBucket.clear();
- } else {
- // Skip aggregating the partial buckets since there's no previous partial bucket.
- for (const auto& slice : mCurrentSlicedBucket) {
- for (auto& tracker : mAnomalyTrackers) {
- if (tracker != nullptr) {
- // TODO: fix this when anomaly can accept double values
- auto& interval = slice.second[0];
- if (interval.hasValue) {
- tracker->addPastBucket(slice.first, interval.value.long_value,
- mCurrentBucketNum);
- }
- }
- }
- }
- }
- } else {
- // Accumulate partial bucket.
- for (const auto& slice : mCurrentSlicedBucket) {
- // TODO: fix this when anomaly can accept double values
- auto& interval = slice.second[0];
- if (interval.hasValue) {
- mCurrentFullBucket[slice.first] += interval.value.long_value;
- }
- }
- }
-}
-
-size_t ValueMetricProducer::byteSizeLocked() const {
- size_t totalSize = 0;
- for (const auto& pair : mPastBuckets) {
- totalSize += pair.second.size() * kBucketSize;
- }
- return totalSize;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
deleted file mode 100644
index e72002e88533..000000000000
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTimer.h"
-#include "condition/ConditionTracker.h"
-#include "external/PullDataReceiver.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/EventMatcherWizard.h"
-#include "stats_log_util.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct ValueBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- std::vector<int> valueIndex;
- std::vector<Value> values;
- // If the metric has no condition, then this field is just wasted.
- // When we tune statsd memory usage in the future, this is a candidate to optimize.
- int64_t mConditionTrueNs;
-};
-
-
-// Aggregates values within buckets.
-//
-// There are different events that might complete a bucket
-// - a condition change
-// - an app upgrade
-// - an alarm set to the end of the bucket
-class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
-public:
- ValueMetricProducer(
- const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex,
- const vector<ConditionState>& initialConditionCache,
- const sp<ConditionWizard>& conditionWizard, const int whatMatcherIndex,
- const sp<EventMatcherWizard>& matcherWizard, const int pullTagId,
- const int64_t timeBaseNs, const int64_t startTimeNs,
- const sp<StatsPullerManager>& pullerManager,
- const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
- const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
- eventDeactivationMap = {},
- const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
- virtual ~ValueMetricProducer();
-
- // Process data pulled on bucket boundary.
- void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
- bool pullSuccess, int64_t originalPullTimeNs) override;
-
- // ValueMetric needs special logic if it's a pulled atom.
- void notifyAppUpgrade(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mSplitBucketForAppUpgrade) {
- return;
- }
- if (mIsPulled && mCondition == ConditionState::kTrue) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
- };
-
- // ValueMetric needs special logic if it's a pulled atom.
- void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mIsPulled && mCondition == ConditionState::kTrue) {
- pullAndMatchEventsLocked(eventTimeNs);
- }
- flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
- };
-
- void onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) override;
-
-protected:
- void onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition, const LogEvent& event,
- const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
- void onDumpReportLocked(const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
- const bool erase_data,
- const DumpLatency dumpLatency,
- std::set<string> *str_set,
- android::util::ProtoOutputStream* protoOutput) override;
- void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
- // Internal interface to handle active state change.
- void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
- // Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
- // Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
- // Internal function to calculate the current used bytes.
- size_t byteSizeLocked() const override;
-
- void dumpStatesLocked(FILE* out, bool verbose) const override;
-
- // For pulled metrics, this method should only be called if a pull has be done. Else we will
- // not have complete data for the bucket.
- void flushIfNeededLocked(const int64_t& eventTime) override;
-
- // For pulled metrics, this method should only be called if a pulled have be done. Else we will
- // not have complete data for the bucket.
- void flushCurrentBucketLocked(const int64_t& eventTimeNs,
- const int64_t& nextBucketStartTimeNs) override;
-
- void prepareFirstBucketLocked() override;
-
- void dropDataLocked(const int64_t dropTimeNs) override;
-
- // Calculate previous bucket end time based on current time.
- int64_t calcPreviousBucketEndTime(const int64_t currentTimeNs);
-
- // Calculate how many buckets are present between the current bucket and eventTimeNs.
- int64_t calcBucketsForwardCount(const int64_t& eventTimeNs) const;
-
- // Mark the data as invalid.
- void invalidateCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason);
-
- void invalidateCurrentBucketWithoutResetBase(const int64_t dropTimeNs,
- const BucketDropReason reason);
-
- // Skips the current bucket without notifying StatsdStats of the skipped bucket.
- // This should only be called from #flushCurrentBucketLocked. Otherwise, a future event that
- // causes the bucket to be invalidated will not notify StatsdStats.
- void skipCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason);
-
- const int mWhatMatcherIndex;
-
- sp<EventMatcherWizard> mEventMatcherWizard;
-
- sp<StatsPullerManager> mPullerManager;
-
- // Value fields for matching.
- std::vector<Matcher> mFieldMatchers;
-
- // Value fields for matching.
- std::set<HashableDimensionKey> mMatchedMetricDimensionKeys;
-
- // Holds the atom id, primary key pair from a state change.
- pair<int32_t, HashableDimensionKey> mStateChangePrimaryKey;
-
- // tagId for pulled data. -1 if this is not pulled
- const int mPullTagId;
-
- // if this is pulled metric
- const bool mIsPulled;
-
- // internal state of an ongoing aggregation bucket.
- typedef struct {
- // Index in multi value aggregation.
- int valueIndex;
- // Current value, depending on the aggregation type.
- Value value;
- // Number of samples collected.
- int sampleSize;
- // If this dimension has any non-tainted value. If not, don't report the
- // dimension.
- bool hasValue = false;
- // Whether new data is seen in the bucket.
- bool seenNewData = false;
- } Interval;
-
- typedef struct {
- // Holds current base value of the dimension. Take diff and update if necessary.
- Value base;
- // Whether there is a base to diff to.
- bool hasBase;
- // Last seen state value(s).
- HashableDimensionKey currentState;
- // Whether this dimensions in what key has a current state key.
- bool hasCurrentState;
- } BaseInfo;
-
- std::unordered_map<MetricDimensionKey, std::vector<Interval>> mCurrentSlicedBucket;
-
- std::unordered_map<HashableDimensionKey, std::vector<BaseInfo>> mCurrentBaseInfo;
-
- std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
-
- // Save the past buckets and we can clear when the StatsLogReport is dumped.
- std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets;
-
- const int64_t mMinBucketSizeNs;
-
- // Util function to check whether the specified dimension hits the guardrail.
- bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
- bool hasReachedGuardRailLimit() const;
-
- bool hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey);
-
- void pullAndMatchEventsLocked(const int64_t timestampNs);
-
- bool multipleBucketsSkipped(const int64_t numBucketsForward);
-
- void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
- int64_t originalPullTimeNs, int64_t eventElapsedTimeNs);
-
- ValueBucket buildPartialBucket(int64_t bucketEndTime,
- const std::vector<Interval>& intervals);
-
- void initCurrentSlicedBucket(int64_t nextBucketStartTimeNs);
-
- void appendToFullBucket(const bool isFullBucketReached);
-
- // Reset diff base and mHasGlobalBase
- void resetBase();
-
- static const size_t kBucketSize = sizeof(ValueBucket{});
-
- const size_t mDimensionSoftLimit;
-
- const size_t mDimensionHardLimit;
-
- const bool mUseAbsoluteValueOnReset;
-
- const ValueMetric::AggregationType mAggregationType;
-
- const bool mUseDiff;
-
- const ValueMetric::ValueDirection mValueDirection;
-
- const bool mSkipZeroDiffOutput;
-
- // If true, use a zero value as base to compute the diff.
- // This is used for new keys which are present in the new data but was not
- // present in the base data.
- // The default base will only be used if we have a global base.
- const bool mUseZeroDefaultBase;
-
- // For pulled metrics, this is always set to true whenever a pull succeeds.
- // It is set to false when a pull fails, or upon condition change to false.
- // This is used to decide if we have the right base data to compute the
- // diff against.
- bool mHasGlobalBase;
-
- // This is to track whether or not the bucket is skipped for any of the reasons listed in
- // BucketDropReason, many of which make the bucket potentially invalid.
- bool mCurrentBucketIsSkipped;
-
- const int64_t mMaxPullDelayNs;
-
- const bool mSplitBucketForAppUpgrade;
-
- ConditionTimer mConditionTimer;
-
- FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
- FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet);
- FRIEND_TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime);
- FRIEND_TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged);
- FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary);
- FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged);
- FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled);
- FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestFirstBucket);
- FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff);
- FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff);
- FRIEND_TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering);
- FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateAvg);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMax);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMin);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSum);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate);
- FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput);
- FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedState);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithMap);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions);
- FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithCondition);
- FRIEND_TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey);
- FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBase);
- FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures);
-
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit);
- FRIEND_TEST(ValueMetricProducerTest_BucketDrop,
- TestInvalidBucketWhenAccumulateEventWrongBucket);
-
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPushedEvents);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue);
- FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse);
-
- friend class ValueMetricProducerTestHelper;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
deleted file mode 100644
index 8d59d1362919..000000000000
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DURATION_TRACKER_H
-#define DURATION_TRACKER_H
-
-#include "anomaly/DurationAnomalyTracker.h"
-#include "condition/ConditionWizard.h"
-#include "config/ConfigKey.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum DurationState {
- kStopped = 0, // The event is stopped.
- kStarted = 1, // The event is on going.
- kPaused = 2, // The event is started, but condition is false, clock is paused. When condition
- // turns to true, kPaused will become kStarted.
-};
-
-// Hold duration information for one atom level duration in current on-going bucket.
-struct DurationInfo {
- DurationState state;
-
- // the number of starts seen.
- int32_t startCount;
-
- // most recent start time.
- int64_t lastStartTime;
- // existing duration in current bucket.
- int64_t lastDuration;
- // cache the HashableDimensionKeys we need to query the condition for this duration event.
- ConditionKey conditionKeys;
-
- DurationInfo() : state(kStopped), startCount(0), lastStartTime(0), lastDuration(0){};
-};
-
-struct DurationBucket {
- int64_t mBucketStartNs;
- int64_t mBucketEndNs;
- int64_t mDuration;
-};
-
-struct DurationValues {
- // Recorded duration for current partial bucket.
- int64_t mDuration;
-
- // Sum of past partial bucket durations in current full bucket.
- // Used for anomaly detection.
- int64_t mDurationFullBucket;
-};
-
-class DurationTracker {
-public:
- DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
- int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
- int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
- const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : mConfigKey(key),
- mTrackerId(id),
- mEventKey(eventKey),
- mWizard(wizard),
- mConditionTrackerIndex(conditionIndex),
- mBucketSizeNs(bucketSizeNs),
- mNested(nesting),
- mCurrentBucketStartTimeNs(currentBucketStartNs),
- mDuration(0),
- mCurrentBucketNum(currentBucketNum),
- mStartTimeNs(startTimeNs),
- mConditionSliced(conditionSliced),
- mHasLinksToAllConditionDimensionsInTracker(fullLink),
- mAnomalyTrackers(anomalyTrackers){};
-
- virtual ~DurationTracker(){};
-
- virtual void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
- const ConditionKey& conditionKey) = 0;
- virtual void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- const bool stopAll) = 0;
- virtual void noteStopAll(const int64_t eventTime) = 0;
-
- virtual void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) = 0;
- virtual void onConditionChanged(bool condition, const int64_t timestamp) = 0;
-
- virtual void onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) = 0;
-
- // Flush stale buckets if needed, and return true if the tracker has no on-going duration
- // events, so that the owner can safely remove the tracker.
- virtual bool flushIfNeeded(
- int64_t timestampNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
-
- // Should only be called during an app upgrade or from this tracker's flushIfNeeded. If from
- // an app upgrade, we assume that we're trying to form a partial bucket.
- virtual bool flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
-
- // Predict the anomaly timestamp given the current status.
- virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const = 0;
- // Dump internal states for debugging
- virtual void dumpStates(FILE* out, bool verbose) const = 0;
-
- virtual int64_t getCurrentStateKeyDuration() const = 0;
-
- virtual int64_t getCurrentStateKeyFullBucketDuration() const = 0;
-
- // Replace old value with new value for the given state atom.
- virtual void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) = 0;
-
-protected:
- int64_t getCurrentBucketEndTimeNs() const {
- return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
- }
-
- // Starts the anomaly alarm.
- void startAnomalyAlarm(const int64_t eventTime) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- const int64_t alarmTimestampNs =
- predictAnomalyTimestampNs(*anomalyTracker, eventTime);
- if (alarmTimestampNs > 0) {
- anomalyTracker->startAlarm(mEventKey, alarmTimestampNs);
- }
- }
- }
- }
-
- // Stops the anomaly alarm. If it should have already fired, declare the anomaly now.
- void stopAnomalyAlarm(const int64_t timestamp) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- anomalyTracker->stopAlarm(mEventKey, timestamp);
- }
- }
- }
-
- void addPastBucketToAnomalyTrackers(const MetricDimensionKey eventKey,
- const int64_t& bucketValue, const int64_t& bucketNum) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- anomalyTracker->addPastBucket(eventKey, bucketValue, bucketNum);
- }
- }
- }
-
- void detectAndDeclareAnomaly(const int64_t& timestamp, const int64_t& currBucketNum,
- const int64_t& currentBucketValue) {
- for (auto& anomalyTracker : mAnomalyTrackers) {
- if (anomalyTracker != nullptr) {
- anomalyTracker->detectAndDeclareAnomaly(timestamp, currBucketNum, mTrackerId,
- mEventKey, currentBucketValue);
- }
- }
- }
-
- // Convenience to compute the current bucket's end time, which is always aligned with the
- // start time of the metric.
- int64_t getCurrentBucketEndTimeNs() {
- return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
- }
-
- void setEventKey(const MetricDimensionKey& eventKey) {
- mEventKey = eventKey;
- }
-
- // A reference to the DurationMetricProducer's config key.
- const ConfigKey& mConfigKey;
-
- const int64_t mTrackerId;
-
- MetricDimensionKey mEventKey;
-
- sp<ConditionWizard> mWizard;
-
- const int mConditionTrackerIndex;
-
- const int64_t mBucketSizeNs;
-
- const bool mNested;
-
- int64_t mCurrentBucketStartTimeNs;
-
- int64_t mDuration; // current recorded duration result (for partial bucket)
-
- // Recorded duration results for each state key in the current partial bucket.
- std::unordered_map<HashableDimensionKey, DurationValues> mStateKeyDurationMap;
-
- int64_t mCurrentBucketNum;
-
- const int64_t mStartTimeNs;
-
- const bool mConditionSliced;
-
- bool mHasLinksToAllConditionDimensionsInTracker;
-
- std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
-
- FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
deleted file mode 100644
index ee4e1672411f..000000000000
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false
-
-#include "Log.h"
-#include "MaxDurationTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const int64_t& id,
- const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
- int64_t currentBucketStartNs, int64_t currentBucketNum,
- int64_t startTimeNs, int64_t bucketSizeNs,
- bool conditionSliced, bool fullLink,
- const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
- currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
- anomalyTrackers) {
-}
-
-bool MaxDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
- // ===========GuardRail==============
- if (mInfos.find(newKey) != mInfos.end()) {
- // if the key existed, we are good!
- return false;
- }
- // 1. Report the tuple count if the tuple count > soft limit
- if (mInfos.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mInfos.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("MaxDurTracker %lld dropping data for dimension key %s",
- (long long)mTrackerId, newKey.toString().c_str());
- return true;
- }
- }
- return false;
-}
-
-void MaxDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
- const int64_t eventTime, const ConditionKey& conditionKey) {
- // this will construct a new DurationInfo if this key didn't exist.
- if (hitGuardRail(key)) {
- return;
- }
-
- DurationInfo& duration = mInfos[key];
- if (mConditionSliced) {
- duration.conditionKeys = conditionKey;
- }
- VLOG("MaxDuration: key %s start condition %d", key.toString().c_str(), condition);
-
- switch (duration.state) {
- case kStarted:
- duration.startCount++;
- break;
- case kPaused:
- duration.startCount++;
- break;
- case kStopped:
- if (!condition) {
- // event started, but we need to wait for the condition to become true.
- duration.state = DurationState::kPaused;
- } else {
- duration.state = DurationState::kStarted;
- duration.lastStartTime = eventTime;
- startAnomalyAlarm(eventTime);
- }
- duration.startCount = 1;
- break;
- }
-}
-
-void MaxDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- bool forceStop) {
- VLOG("MaxDuration: key %s stop", key.toString().c_str());
- if (mInfos.find(key) == mInfos.end()) {
- // we didn't see a start event before. do nothing.
- return;
- }
- DurationInfo& duration = mInfos[key];
-
- switch (duration.state) {
- case DurationState::kStopped:
- // already stopped, do nothing.
- break;
- case DurationState::kStarted: {
- duration.startCount--;
- if (forceStop || !mNested || duration.startCount <= 0) {
- stopAnomalyAlarm(eventTime);
- duration.state = DurationState::kStopped;
- int64_t durationTime = eventTime - duration.lastStartTime;
- VLOG("Max, key %s, Stop %lld %lld %lld", key.toString().c_str(),
- (long long)duration.lastStartTime, (long long)eventTime,
- (long long)durationTime);
- duration.lastDuration += durationTime;
- if (anyStarted()) {
- // In case any other dimensions are still started, we need to keep the alarm
- // set.
- startAnomalyAlarm(eventTime);
- }
- VLOG(" record duration: %lld ", (long long)duration.lastDuration);
- }
- break;
- }
- case DurationState::kPaused: {
- duration.startCount--;
- if (forceStop || !mNested || duration.startCount <= 0) {
- duration.state = DurationState::kStopped;
- }
- break;
- }
- }
-
- if (duration.lastDuration > mDuration) {
- mDuration = duration.lastDuration;
- VLOG("Max: new max duration: %lld", (long long)mDuration);
- }
- // Once an atom duration ends, we erase it. Next time, if we see another atom event with the
- // same name, they are still considered as different atom durations.
- if (duration.state == DurationState::kStopped) {
- mInfos.erase(key);
- }
-}
-
-bool MaxDurationTracker::anyStarted() {
- for (auto& pair : mInfos) {
- if (pair.second.state == kStarted) {
- return true;
- }
- }
- return false;
-}
-
-void MaxDurationTracker::noteStopAll(const int64_t eventTime) {
- std::set<HashableDimensionKey> keys;
- for (const auto& pair : mInfos) {
- keys.insert(pair.first);
- }
- for (auto& key : keys) {
- noteStop(key, eventTime, true);
- }
-}
-
-bool MaxDurationTracker::flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
- VLOG("MaxDurationTracker flushing.....");
-
- // adjust the bucket start time
- int numBucketsForward = 0;
- int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
- int64_t currentBucketEndTimeNs;
- if (eventTimeNs >= fullBucketEnd) {
- numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
- currentBucketEndTimeNs = fullBucketEnd;
- } else {
- // This must be a partial bucket.
- currentBucketEndTimeNs = eventTimeNs;
- }
-
- bool hasPendingEvent =
- false; // has either a kStarted or kPaused event across bucket boundaries
- // meaning we need to carry them over to the new bucket.
- for (auto it = mInfos.begin(); it != mInfos.end();) {
- if (it->second.state == DurationState::kStopped) {
- // No need to keep buckets for events that were stopped before.
- it = mInfos.erase(it);
- } else {
- ++it;
- hasPendingEvent = true;
- }
- }
-
- // mDuration is updated in noteStop to the maximum duration that ended in the current bucket.
- if (mDuration != 0) {
- DurationBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- info.mBucketEndNs = currentBucketEndTimeNs;
- info.mDuration = mDuration;
- (*output)[mEventKey].push_back(info);
- VLOG(" final duration for last bucket: %lld", (long long)mDuration);
- }
-
- if (numBucketsForward > 0) {
- mCurrentBucketStartTimeNs = fullBucketEnd + (numBucketsForward - 1) * mBucketSizeNs;
- mCurrentBucketNum += numBucketsForward;
- } else { // We must be forming a partial bucket.
- mCurrentBucketStartTimeNs = eventTimeNs;
- }
-
- mDuration = 0;
- // If this tracker has no pending events, tell owner to remove.
- return !hasPendingEvent;
-}
-
-bool MaxDurationTracker::flushIfNeeded(
- int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
- if (eventTimeNs < getCurrentBucketEndTimeNs()) {
- return false;
- }
- return flushCurrentBucket(eventTimeNs, output);
-}
-
-void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
- const int64_t timestamp) {
- // Now for each of the on-going event, check if the condition has changed for them.
- for (auto& pair : mInfos) {
- if (pair.second.state == kStopped) {
- continue;
- }
- ConditionState conditionState = mWizard->query(
- mConditionTrackerIndex, pair.second.conditionKeys,
- !mHasLinksToAllConditionDimensionsInTracker);
- bool conditionMet = (conditionState == ConditionState::kTrue);
-
- VLOG("key: %s, condition: %d", pair.first.toString().c_str(), conditionMet);
- noteConditionChanged(pair.first, conditionMet, timestamp);
- }
-}
-
-void MaxDurationTracker::onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
-}
-
-void MaxDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
- for (auto& pair : mInfos) {
- noteConditionChanged(pair.first, condition, timestamp);
- }
-}
-
-void MaxDurationTracker::noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
- const int64_t timestamp) {
- auto it = mInfos.find(key);
- if (it == mInfos.end()) {
- return;
- }
-
- switch (it->second.state) {
- case kStarted:
- // If condition becomes false, kStarted -> kPaused. Record the current duration and
- // stop anomaly alarm.
- if (!conditionMet) {
- stopAnomalyAlarm(timestamp);
- it->second.state = DurationState::kPaused;
- it->second.lastDuration += (timestamp - it->second.lastStartTime);
- if (anyStarted()) {
- // In case any other dimensions are still started, we need to set the alarm.
- startAnomalyAlarm(timestamp);
- }
- VLOG("MaxDurationTracker Key: %s Started->Paused ", key.toString().c_str());
- }
- break;
- case kStopped:
- // Nothing to do if it's stopped.
- break;
- case kPaused:
- // If condition becomes true, kPaused -> kStarted. and the start time is the condition
- // change time.
- if (conditionMet) {
- it->second.state = DurationState::kStarted;
- it->second.lastStartTime = timestamp;
- startAnomalyAlarm(timestamp);
- VLOG("MaxDurationTracker Key: %s Paused->Started", key.toString().c_str());
- }
- break;
- }
- // Note that we don't update mDuration here since it's only updated during noteStop.
-}
-
-int64_t MaxDurationTracker::predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const {
- // The allowed time we can continue in the current state is the
- // (anomaly threshold) - max(elapsed time of the started mInfos).
- int64_t maxElapsed = 0;
- for (auto it = mInfos.begin(); it != mInfos.end(); ++it) {
- if (it->second.state == DurationState::kStarted) {
- int64_t duration =
- it->second.lastDuration + (currentTimestamp - it->second.lastStartTime);
- if (duration > maxElapsed) {
- maxElapsed = duration;
- }
- }
- }
- int64_t anomalyTimeNs = currentTimestamp + anomalyTracker.getAnomalyThreshold() - maxElapsed;
- int64_t refractoryEndNs = anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
- return std::max(anomalyTimeNs, refractoryEndNs);
-}
-
-void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
- fprintf(out, "\t\t sub-durations %lu\n", (unsigned long)mInfos.size());
- fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
-}
-
-int64_t MaxDurationTracker::getCurrentStateKeyDuration() const {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
- return -1;
-}
-
-int64_t MaxDurationTracker::getCurrentStateKeyFullBucketDuration() const {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
- return -1;
-}
-
-void MaxDurationTracker::updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) {
- ALOGE("MaxDurationTracker does not handle sliced state changes.");
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
deleted file mode 100644
index 2891c6e1138a..000000000000
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MAX_DURATION_TRACKER_H
-#define MAX_DURATION_TRACKER_H
-
-#include "DurationTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Tracks a pool of atom durations, and output the max duration for each bucket.
-// To get max duration, we need to keep track of each individual durations, and compare them when
-// they stop or bucket expires.
-class MaxDurationTracker : public DurationTracker {
-public:
- MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex,
- bool nesting,
- int64_t currentBucketStartNs, int64_t currentBucketNum,
- int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
- bool fullLink,
- const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
-
- MaxDurationTracker(const MaxDurationTracker& tracker) = default;
-
- void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
- const ConditionKey& conditionKey) override;
- void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- const bool stopAll) override;
- void noteStopAll(const int64_t eventTime) override;
-
- bool flushIfNeeded(
- int64_t timestampNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
- bool flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
-
- void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
- void onConditionChanged(bool condition, const int64_t timestamp) override;
-
- void onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) override;
-
- int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const override;
- void dumpStates(FILE* out, bool verbose) const override;
-
- int64_t getCurrentStateKeyDuration() const override;
-
- int64_t getCurrentStateKeyFullBucketDuration() const override;
-
- void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
-
-private:
- // Returns true if at least one of the mInfos is started.
- bool anyStarted();
-
- std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
-
- void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
- const int64_t timestamp);
-
- // return true if we should not allow newKey to be tracked because we are above the threshold
- bool hitGuardRail(const HashableDimensionKey& newKey);
-
- FRIEND_TEST(MaxDurationTrackerTest, TestSimpleMaxDuration);
- FRIEND_TEST(MaxDurationTrackerTest, TestCrossBucketBoundary);
- FRIEND_TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition);
- FRIEND_TEST(MaxDurationTrackerTest, TestStopAll);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
- FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // MAX_DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
deleted file mode 100644
index 0d49bbc269a3..000000000000
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false
-#include "Log.h"
-#include "OringDurationTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::pair;
-
-OringDurationTracker::OringDurationTracker(
- const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
- sp<ConditionWizard> wizard, int conditionIndex, bool nesting, int64_t currentBucketStartNs,
- int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
- bool fullLink, const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
- : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
- currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
- anomalyTrackers),
- mStarted(),
- mPaused() {
- mLastStartTime = 0;
-}
-
-bool OringDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
- // ===========GuardRail==============
- // 1. Report the tuple count if the tuple count > soft limit
- if (mConditionKeyMap.find(newKey) != mConditionKeyMap.end()) {
- return false;
- }
- if (mConditionKeyMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
- size_t newTupleCount = mConditionKeyMap.size() + 1;
- StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
- // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
- if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
- ALOGE("OringDurTracker %lld dropping data for dimension key %s",
- (long long)mTrackerId, newKey.toString().c_str());
- return true;
- }
- }
- return false;
-}
-
-void OringDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
- const int64_t eventTime, const ConditionKey& conditionKey) {
- if (hitGuardRail(key)) {
- return;
- }
- if (condition) {
- if (mStarted.size() == 0) {
- mLastStartTime = eventTime;
- VLOG("record first start....");
- startAnomalyAlarm(eventTime);
- }
- mStarted[key]++;
- } else {
- mPaused[key]++;
- }
-
- if (mConditionSliced && mConditionKeyMap.find(key) == mConditionKeyMap.end()) {
- mConditionKeyMap[key] = conditionKey;
- }
- VLOG("Oring: %s start, condition %d", key.toString().c_str(), condition);
-}
-
-void OringDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t timestamp,
- const bool stopAll) {
- VLOG("Oring: %s stop", key.toString().c_str());
- auto it = mStarted.find(key);
- if (it != mStarted.end()) {
- (it->second)--;
- if (stopAll || !mNested || it->second <= 0) {
- mStarted.erase(it);
- mConditionKeyMap.erase(key);
- }
- if (mStarted.empty()) {
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- VLOG("record duration %lld, total duration %lld for state key %s",
- (long long)timestamp - mLastStartTime, (long long)getCurrentStateKeyDuration(),
- mEventKey.getStateValuesKey().toString().c_str());
- }
- }
-
- auto pausedIt = mPaused.find(key);
- if (pausedIt != mPaused.end()) {
- (pausedIt->second)--;
- if (stopAll || !mNested || pausedIt->second <= 0) {
- mPaused.erase(pausedIt);
- mConditionKeyMap.erase(key);
- }
- }
- if (mStarted.empty()) {
- stopAnomalyAlarm(timestamp);
- }
-}
-
-void OringDurationTracker::noteStopAll(const int64_t timestamp) {
- if (!mStarted.empty()) {
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- VLOG("Oring Stop all: record duration %lld, total duration %lld for state key %s",
- (long long)timestamp - mLastStartTime, (long long)getCurrentStateKeyDuration(),
- mEventKey.getStateValuesKey().toString().c_str());
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- }
-
- stopAnomalyAlarm(timestamp);
- mStarted.clear();
- mPaused.clear();
- mConditionKeyMap.clear();
-}
-
-bool OringDurationTracker::flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
- VLOG("OringDurationTracker Flushing.............");
-
- // Note that we have to mimic the bucket time changes we do in the
- // MetricProducer#notifyAppUpgrade.
-
- int numBucketsForward = 0;
- int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
- int64_t currentBucketEndTimeNs;
-
- if (eventTimeNs >= fullBucketEnd) {
- numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
- currentBucketEndTimeNs = fullBucketEnd;
- } else {
- // This must be a partial bucket.
- currentBucketEndTimeNs = eventTimeNs;
- }
-
- // Process the current bucket.
- if (mStarted.size() > 0) {
- // Calculate the duration for the current state key.
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (currentBucketEndTimeNs - mLastStartTime);
- }
- // Store DurationBucket info for each whatKey, stateKey pair.
- // Note: The whatKey stored in mEventKey is constant for each DurationTracker, while the
- // stateKey stored in mEventKey is only the current stateKey. mStateKeyDurationMap is used to
- // store durations for each stateKey, so we need to flush the bucket by creating a
- // DurationBucket for each stateKey.
- for (auto& durationIt : mStateKeyDurationMap) {
- if (durationIt.second.mDuration > 0) {
- DurationBucket current_info;
- current_info.mBucketStartNs = mCurrentBucketStartTimeNs;
- current_info.mBucketEndNs = currentBucketEndTimeNs;
- current_info.mDuration = durationIt.second.mDuration;
- (*output)[MetricDimensionKey(mEventKey.getDimensionKeyInWhat(), durationIt.first)]
- .push_back(current_info);
-
- durationIt.second.mDurationFullBucket += durationIt.second.mDuration;
- VLOG(" duration: %lld", (long long)current_info.mDuration);
- }
-
- if (eventTimeNs > fullBucketEnd) {
- // End of full bucket, can send to anomaly tracker now.
- addPastBucketToAnomalyTrackers(
- MetricDimensionKey(mEventKey.getDimensionKeyInWhat(), durationIt.first),
- getCurrentStateKeyFullBucketDuration(), mCurrentBucketNum);
- durationIt.second.mDurationFullBucket = 0;
- }
- durationIt.second.mDuration = 0;
- }
-
- if (mStarted.size() > 0) {
- for (int i = 1; i < numBucketsForward; i++) {
- DurationBucket info;
- info.mBucketStartNs = fullBucketEnd + mBucketSizeNs * (i - 1);
- info.mBucketEndNs = info.mBucketStartNs + mBucketSizeNs;
- info.mDuration = mBucketSizeNs;
- // Full duration buckets are attributed to the current stateKey.
- (*output)[mEventKey].push_back(info);
- // Safe to send these buckets to anomaly tracker since they must be full buckets.
- // If it's a partial bucket, numBucketsForward would be 0.
- addPastBucketToAnomalyTrackers(mEventKey, info.mDuration, mCurrentBucketNum + i);
- VLOG(" add filling bucket with duration %lld", (long long)info.mDuration);
- }
- } else {
- if (numBucketsForward >= 2) {
- addPastBucketToAnomalyTrackers(mEventKey, 0, mCurrentBucketNum + numBucketsForward - 1);
- }
- }
-
- if (numBucketsForward > 0) {
- mCurrentBucketStartTimeNs = fullBucketEnd + (numBucketsForward - 1) * mBucketSizeNs;
- mCurrentBucketNum += numBucketsForward;
- } else { // We must be forming a partial bucket.
- mCurrentBucketStartTimeNs = eventTimeNs;
- }
- mLastStartTime = mCurrentBucketStartTimeNs;
-
- // if all stopped, then tell owner it's safe to remove this tracker.
- return mStarted.empty() && mPaused.empty();
-}
-
-bool OringDurationTracker::flushIfNeeded(
- int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
- if (eventTimeNs < getCurrentBucketEndTimeNs()) {
- return false;
- }
- return flushCurrentBucket(eventTimeNs, output);
-}
-
-void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
- const int64_t timestamp) {
- vector<pair<HashableDimensionKey, int>> startedToPaused;
- vector<pair<HashableDimensionKey, int>> pausedToStarted;
- if (!mStarted.empty()) {
- for (auto it = mStarted.begin(); it != mStarted.end();) {
- const auto& key = it->first;
- const auto& condIt = mConditionKeyMap.find(key);
- if (condIt == mConditionKeyMap.end()) {
- VLOG("Key %s dont have condition key", key.toString().c_str());
- ++it;
- continue;
- }
- ConditionState conditionState =
- mWizard->query(mConditionTrackerIndex, condIt->second,
- !mHasLinksToAllConditionDimensionsInTracker);
- if (conditionState != ConditionState::kTrue) {
- startedToPaused.push_back(*it);
- it = mStarted.erase(it);
- VLOG("Key %s started -> paused", key.toString().c_str());
- } else {
- ++it;
- }
- }
-
- if (mStarted.empty()) {
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- VLOG("record duration %lld, total duration %lld for state key %s",
- (long long)(timestamp - mLastStartTime), (long long)getCurrentStateKeyDuration(),
- mEventKey.getStateValuesKey().toString().c_str());
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- }
- }
-
- if (!mPaused.empty()) {
- for (auto it = mPaused.begin(); it != mPaused.end();) {
- const auto& key = it->first;
- if (mConditionKeyMap.find(key) == mConditionKeyMap.end()) {
- VLOG("Key %s dont have condition key", key.toString().c_str());
- ++it;
- continue;
- }
- ConditionState conditionState =
- mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key],
- !mHasLinksToAllConditionDimensionsInTracker);
- if (conditionState == ConditionState::kTrue) {
- pausedToStarted.push_back(*it);
- it = mPaused.erase(it);
- VLOG("Key %s paused -> started", key.toString().c_str());
- } else {
- ++it;
- }
- }
-
- if (mStarted.empty() && pausedToStarted.size() > 0) {
- mLastStartTime = timestamp;
- }
- }
-
- if (mStarted.empty() && !pausedToStarted.empty()) {
- startAnomalyAlarm(timestamp);
- }
- mStarted.insert(pausedToStarted.begin(), pausedToStarted.end());
- mPaused.insert(startedToPaused.begin(), startedToPaused.end());
-
- if (mStarted.empty()) {
- stopAnomalyAlarm(timestamp);
- }
-}
-
-void OringDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
- if (condition) {
- if (!mPaused.empty()) {
- VLOG("Condition true, all started");
- if (mStarted.empty()) {
- mLastStartTime = timestamp;
- }
- if (mStarted.empty() && !mPaused.empty()) {
- startAnomalyAlarm(timestamp);
- }
- mStarted.insert(mPaused.begin(), mPaused.end());
- mPaused.clear();
- }
- } else {
- if (!mStarted.empty()) {
- VLOG("Condition false, all paused");
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
- (timestamp - mLastStartTime);
- mPaused.insert(mStarted.begin(), mStarted.end());
- mStarted.clear();
- detectAndDeclareAnomaly(
- timestamp, mCurrentBucketNum,
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
- }
- }
- if (mStarted.empty()) {
- stopAnomalyAlarm(timestamp);
- }
-}
-
-void OringDurationTracker::onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) {
- // Nothing needs to be done on a state change if we have not seen a start
- // event, the metric is currently not active, or condition is false.
- // For these cases, no keys are being tracked in mStarted, so update
- // the current state key and return.
- if (mStarted.empty()) {
- updateCurrentStateKey(atomId, newState);
- return;
- }
- // Add the current duration length to the previous state key and then update
- // the last start time and current state key.
- mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration += (timestamp - mLastStartTime);
- mLastStartTime = timestamp;
- updateCurrentStateKey(atomId, newState);
-}
-
-int64_t OringDurationTracker::predictAnomalyTimestampNs(
- const DurationAnomalyTracker& anomalyTracker, const int64_t eventTimestampNs) const {
-
- // The anomaly threshold.
- const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold();
-
- // The timestamp of the current bucket end.
- const int64_t currentBucketEndNs = getCurrentBucketEndTimeNs();
-
- // The past duration ns for the current bucket of the current stateKey.
- int64_t currentStateBucketPastNs =
- getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration();
-
- // As we move into the future, old buckets get overwritten (so their old data is erased).
- // Sum of past durations. Will change as we overwrite old buckets.
- int64_t pastNs = currentStateBucketPastNs + anomalyTracker.getSumOverPastBuckets(mEventKey);
-
- // The refractory period end timestamp for dimension mEventKey.
- const int64_t refractoryPeriodEndNs =
- anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
-
- // The anomaly should happen when accumulated wakelock duration is above the threshold and
- // not within the refractory period.
- int64_t anomalyTimestampNs =
- std::max(eventTimestampNs + thresholdNs - pastNs, refractoryPeriodEndNs);
- // If the predicted the anomaly timestamp is within the current bucket, return it directly.
- if (anomalyTimestampNs <= currentBucketEndNs) {
- return std::max(eventTimestampNs, anomalyTimestampNs);
- }
-
- // Remove the old bucket.
- if (anomalyTracker.getNumOfPastBuckets() > 0) {
- pastNs -= anomalyTracker.getPastBucketValue(
- mEventKey,
- mCurrentBucketNum - anomalyTracker.getNumOfPastBuckets());
- // Add the remaining of the current bucket to the accumulated wakelock duration.
- pastNs += (currentBucketEndNs - eventTimestampNs);
- } else {
- // The anomaly depends on only one bucket.
- pastNs = 0;
- }
-
- // The anomaly will not happen in the current bucket. We need to iterate over the future buckets
- // to predict the accumulated wakelock duration and determine the anomaly timestamp accordingly.
- for (int futureBucketIdx = 1; futureBucketIdx <= anomalyTracker.getNumOfPastBuckets() + 1;
- futureBucketIdx++) {
- // The alarm candidate timestamp should meet two requirements:
- // 1. the accumulated wakelock duration is above the threshold.
- // 2. it is not within the refractory period.
- // 3. the alarm timestamp falls in this bucket. Otherwise we need to flush the past buckets,
- // find the new alarm candidate timestamp and check these requirements again.
- const int64_t bucketEndNs = currentBucketEndNs + futureBucketIdx * mBucketSizeNs;
- int64_t anomalyTimestampNs =
- std::max(bucketEndNs - mBucketSizeNs + thresholdNs - pastNs, refractoryPeriodEndNs);
- if (anomalyTimestampNs <= bucketEndNs) {
- return anomalyTimestampNs;
- }
- if (anomalyTracker.getNumOfPastBuckets() <= 0) {
- continue;
- }
-
- // No valid alarm timestamp is found in this bucket. The clock moves to the end of the
- // bucket. Update the pastNs.
- pastNs += mBucketSizeNs;
- // 1. If the oldest past bucket is still in the past bucket window, we could fetch the past
- // bucket and erase it from pastNs.
- // 2. If the oldest past bucket is the current bucket, we should compute the
- // wakelock duration in the current bucket and erase it from pastNs.
- // 3. Otherwise all othe past buckets are ancient.
- if (futureBucketIdx < anomalyTracker.getNumOfPastBuckets()) {
- pastNs -= anomalyTracker.getPastBucketValue(
- mEventKey,
- mCurrentBucketNum - anomalyTracker.getNumOfPastBuckets() + futureBucketIdx);
- } else if (futureBucketIdx == anomalyTracker.getNumOfPastBuckets()) {
- pastNs -= (currentStateBucketPastNs + (currentBucketEndNs - eventTimestampNs));
- }
- }
-
- return std::max(eventTimestampNs + thresholdNs, refractoryPeriodEndNs);
-}
-
-void OringDurationTracker::dumpStates(FILE* out, bool verbose) const {
- fprintf(out, "\t\t started count %lu\n", (unsigned long)mStarted.size());
- fprintf(out, "\t\t paused count %lu\n", (unsigned long)mPaused.size());
- fprintf(out, "\t\t current duration %lld\n", (long long)getCurrentStateKeyDuration());
-}
-
-int64_t OringDurationTracker::getCurrentStateKeyDuration() const {
- auto it = mStateKeyDurationMap.find(mEventKey.getStateValuesKey());
- if (it == mStateKeyDurationMap.end()) {
- return 0;
- } else {
- return it->second.mDuration;
- }
-}
-
-int64_t OringDurationTracker::getCurrentStateKeyFullBucketDuration() const {
- auto it = mStateKeyDurationMap.find(mEventKey.getStateValuesKey());
- if (it == mStateKeyDurationMap.end()) {
- return 0;
- } else {
- return it->second.mDurationFullBucket;
- }
-}
-
-void OringDurationTracker::updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) {
- HashableDimensionKey* stateValuesKey = mEventKey.getMutableStateValuesKey();
- for (size_t i = 0; i < stateValuesKey->getValues().size(); i++) {
- if (stateValuesKey->getValues()[i].mField.getTag() == atomId) {
- stateValuesKey->mutableValue(i)->mValue = newState.mValue;
- }
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
deleted file mode 100644
index bd8017a7decd..000000000000
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ORING_DURATION_TRACKER_H
-#define ORING_DURATION_TRACKER_H
-
-#include "DurationTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Tracks the "Or'd" duration -- if 2 durations are overlapping, they won't be double counted.
-class OringDurationTracker : public DurationTracker {
-public:
- OringDurationTracker(const ConfigKey& key, const int64_t& id,
- const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard,
- int conditionIndex, bool nesting, int64_t currentBucketStartNs,
- int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs,
- bool conditionSliced, bool fullLink,
- const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
-
- OringDurationTracker(const OringDurationTracker& tracker) = default;
-
- void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
- const ConditionKey& conditionKey) override;
- void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
- const bool stopAll) override;
- void noteStopAll(const int64_t eventTime) override;
-
- void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
- void onConditionChanged(bool condition, const int64_t timestamp) override;
-
- void onStateChanged(const int64_t timestamp, const int32_t atomId,
- const FieldValue& newState) override;
-
- bool flushCurrentBucket(
- const int64_t& eventTimeNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
- bool flushIfNeeded(
- int64_t timestampNs,
- std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
-
- int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
- const int64_t currentTimestamp) const override;
- void dumpStates(FILE* out, bool verbose) const override;
-
- int64_t getCurrentStateKeyDuration() const override;
-
- int64_t getCurrentStateKeyFullBucketDuration() const override;
-
- void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
-
-private:
- // We don't need to keep track of individual durations. The information that's needed is:
- // 1) which keys are started. We record the first start time.
- // 2) which keys are paused (started but condition was false)
- // 3) whenever a key stops, we remove it from the started set. And if the set becomes empty,
- // it means everything has stopped, we then record the end time.
- std::unordered_map<HashableDimensionKey, int> mStarted;
- std::unordered_map<HashableDimensionKey, int> mPaused;
- int64_t mLastStartTime;
- std::unordered_map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
-
- // return true if we should not allow newKey to be tracked because we are above the threshold
- bool hitGuardRail(const HashableDimensionKey& newKey);
-
- FRIEND_TEST(OringDurationTrackerTest, TestDurationOverlap);
- FRIEND_TEST(OringDurationTrackerTest, TestCrossBucketBoundary);
- FRIEND_TEST(OringDurationTrackerTest, TestDurationConditionChange);
- FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
- FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // ORING_DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
deleted file mode 100644
index 8917c36bb608..000000000000
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "metrics_manager_util.h"
-
-#include <inttypes.h>
-
-#include "FieldValue.h"
-#include "MetricProducer.h"
-#include "condition/CombinationConditionTracker.h"
-#include "condition/SimpleConditionTracker.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/CombinationLogMatchingTracker.h"
-#include "matchers/EventMatcherWizard.h"
-#include "matchers/SimpleLogMatchingTracker.h"
-#include "metrics/CountMetricProducer.h"
-#include "metrics/DurationMetricProducer.h"
-#include "metrics/EventMetricProducer.h"
-#include "metrics/GaugeMetricProducer.h"
-#include "metrics/ValueMetricProducer.h"
-#include "state/StateManager.h"
-#include "stats_util.h"
-
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-bool hasLeafNode(const FieldMatcher& matcher) {
- if (!matcher.has_field()) {
- return false;
- }
- for (int i = 0; i < matcher.child_size(); ++i) {
- if (hasLeafNode(matcher.child(i))) {
- return true;
- }
- }
- return true;
-}
-
-} // namespace
-
-bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex,
- const bool usedForDimension,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int, std::vector<int>>& trackerToMetricMap,
- int& logTrackerIndex) {
- auto logTrackerIt = logTrackerMap.find(what);
- if (logTrackerIt == logTrackerMap.end()) {
- ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)what);
- return false;
- }
- if (usedForDimension && allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
- ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
- "the \"what\" can only about one atom type.",
- (long long)what);
- return false;
- }
- logTrackerIndex = logTrackerIt->second;
- auto& metric_list = trackerToMetricMap[logTrackerIndex];
- metric_list.push_back(metricIndex);
- return true;
-}
-
-bool handlePullMetricTriggerWithLogTrackers(
- const int64_t trigger, const int metricIndex,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int, std::vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
- auto logTrackerIt = logTrackerMap.find(trigger);
- if (logTrackerIt == logTrackerMap.end()) {
- ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)trigger);
- return false;
- }
- if (allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
- ALOGE("AtomMatcher \"%lld\" has more than one tag ids."
- "Trigger can only be one atom type.",
- (long long)trigger);
- return false;
- }
- logTrackerIndex = logTrackerIt->second;
- auto& metric_list = trackerToMetricMap[logTrackerIndex];
- metric_list.push_back(metricIndex);
- return true;
-}
-
-bool handleMetricWithConditions(
- const int64_t condition, const int metricIndex,
- const unordered_map<int64_t, int>& conditionTrackerMap,
- const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
- links,
- vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
- unordered_map<int, std::vector<int>>& conditionToMetricMap) {
- auto condition_it = conditionTrackerMap.find(condition);
- if (condition_it == conditionTrackerMap.end()) {
- ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
- return false;
- }
-
- for (const auto& link : links) {
- auto it = conditionTrackerMap.find(link.condition());
- if (it == conditionTrackerMap.end()) {
- ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
- return false;
- }
- allConditionTrackers[condition_it->second]->setSliced(true);
- allConditionTrackers[it->second]->setSliced(true);
- }
- conditionIndex = condition_it->second;
-
- // will create new vector if not exist before.
- auto& metricList = conditionToMetricMap[condition_it->second];
- metricList.push_back(metricIndex);
- return true;
-}
-
-// Initializes state data structures for a metric.
-// input:
-// [config]: the input config
-// [stateIds]: the slice_by_state ids for this metric
-// [stateAtomIdMap]: this map contains the mapping from all state ids to atom ids
-// [allStateGroupMaps]: this map contains the mapping from state ids and state
-// values to state group ids for all states
-// output:
-// [slicedStateAtoms]: a vector of atom ids of all the slice_by_states
-// [stateGroupMap]: this map should contain the mapping from states ids and state
-// values to state group ids for all states that this metric
-// is interested in
-bool handleMetricWithStates(
- const StatsdConfig& config, const ::google::protobuf::RepeatedField<int64_t>& stateIds,
- const unordered_map<int64_t, int>& stateAtomIdMap,
- const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
- vector<int>& slicedStateAtoms,
- unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap) {
- for (const auto& stateId : stateIds) {
- auto it = stateAtomIdMap.find(stateId);
- if (it == stateAtomIdMap.end()) {
- ALOGW("cannot find State %" PRId64 " in the config", stateId);
- return false;
- }
- int atomId = it->second;
- slicedStateAtoms.push_back(atomId);
-
- auto stateIt = allStateGroupMaps.find(stateId);
- if (stateIt != allStateGroupMaps.end()) {
- stateGroupMap[atomId] = stateIt->second;
- }
- }
- return true;
-}
-
-bool handleMetricWithStateLink(const FieldMatcher& stateMatcher,
- const vector<Matcher>& dimensionsInWhat) {
- vector<Matcher> stateMatchers;
- translateFieldMatcher(stateMatcher, &stateMatchers);
-
- return subsetDimensions(stateMatchers, dimensionsInWhat);
-}
-
-// Validates a metricActivation and populates state.
-// EventActivationMap and EventDeactivationMap are supplied to a MetricProducer
-// to provide the producer with state about its activators and deactivators.
-// Returns false if there are errors.
-bool handleMetricActivation(
- const StatsdConfig& config,
- const int64_t metricId,
- const int metricIndex,
- const unordered_map<int64_t, int>& metricToActivationMap,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
- vector<int>& metricsWithActivation,
- unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
- unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap) {
- // Check if metric has an associated activation
- auto itr = metricToActivationMap.find(metricId);
- if (itr == metricToActivationMap.end()) return true;
-
- int activationIndex = itr->second;
- const MetricActivation& metricActivation = config.metric_activation(activationIndex);
-
- for (int i = 0; i < metricActivation.event_activation_size(); i++) {
- const EventActivation& activation = metricActivation.event_activation(i);
-
- auto itr = logTrackerMap.find(activation.atom_matcher_id());
- if (itr == logTrackerMap.end()) {
- ALOGE("Atom matcher not found for event activation.");
- return false;
- }
-
- ActivationType activationType = (activation.has_activation_type()) ?
- activation.activation_type() : metricActivation.activation_type();
- std::shared_ptr<Activation> activationWrapper = std::make_shared<Activation>(
- activationType, activation.ttl_seconds() * NS_PER_SEC);
-
- int atomMatcherIndex = itr->second;
- activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
- eventActivationMap.emplace(atomMatcherIndex, activationWrapper);
-
- if (activation.has_deactivation_atom_matcher_id()) {
- itr = logTrackerMap.find(activation.deactivation_atom_matcher_id());
- if (itr == logTrackerMap.end()) {
- ALOGE("Atom matcher not found for event deactivation.");
- return false;
- }
- int deactivationAtomMatcherIndex = itr->second;
- deactivationAtomTrackerToMetricMap[deactivationAtomMatcherIndex].push_back(metricIndex);
- eventDeactivationMap[deactivationAtomMatcherIndex].push_back(activationWrapper);
- }
- }
-
- metricsWithActivation.push_back(metricIndex);
- return true;
-}
-
-bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
- unordered_map<int64_t, int>& logTrackerMap,
- vector<sp<LogMatchingTracker>>& allAtomMatchers, set<int>& allTagIds) {
- vector<AtomMatcher> matcherConfigs;
- const int atomMatcherCount = config.atom_matcher_size();
- matcherConfigs.reserve(atomMatcherCount);
- allAtomMatchers.reserve(atomMatcherCount);
-
- for (int i = 0; i < atomMatcherCount; i++) {
- const AtomMatcher& logMatcher = config.atom_matcher(i);
-
- int index = allAtomMatchers.size();
- switch (logMatcher.contents_case()) {
- case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
- allAtomMatchers.push_back(new SimpleLogMatchingTracker(
- logMatcher.id(), index, logMatcher.simple_atom_matcher(), uidMap));
- break;
- case AtomMatcher::ContentsCase::kCombination:
- allAtomMatchers.push_back(
- new CombinationLogMatchingTracker(logMatcher.id(), index));
- break;
- default:
- ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
- return false;
- // continue;
- }
- if (logTrackerMap.find(logMatcher.id()) != logTrackerMap.end()) {
- ALOGE("Duplicate AtomMatcher found!");
- return false;
- }
- logTrackerMap[logMatcher.id()] = index;
- matcherConfigs.push_back(logMatcher);
- }
-
- vector<bool> stackTracker2(allAtomMatchers.size(), false);
- for (auto& matcher : allAtomMatchers) {
- if (!matcher->init(matcherConfigs, allAtomMatchers, logTrackerMap, stackTracker2)) {
- return false;
- }
- // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
- const set<int>& tagIds = matcher->getAtomIds();
- allTagIds.insert(tagIds.begin(), tagIds.end());
- }
- return true;
-}
-
-bool initConditions(const ConfigKey& key, const StatsdConfig& config,
- const unordered_map<int64_t, int>& logTrackerMap,
- unordered_map<int64_t, int>& conditionTrackerMap,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- unordered_map<int, std::vector<int>>& trackerToConditionMap,
- vector<ConditionState>& initialConditionCache) {
- vector<Predicate> conditionConfigs;
- const int conditionTrackerCount = config.predicate_size();
- conditionConfigs.reserve(conditionTrackerCount);
- allConditionTrackers.reserve(conditionTrackerCount);
- initialConditionCache.reserve(conditionTrackerCount);
- std::fill(initialConditionCache.begin(), initialConditionCache.end(), ConditionState::kUnknown);
-
- for (int i = 0; i < conditionTrackerCount; i++) {
- const Predicate& condition = config.predicate(i);
- int index = allConditionTrackers.size();
- switch (condition.contents_case()) {
- case Predicate::ContentsCase::kSimplePredicate: {
- allConditionTrackers.push_back(new SimpleConditionTracker(
- key, condition.id(), index, condition.simple_predicate(), logTrackerMap));
- break;
- }
- case Predicate::ContentsCase::kCombination: {
- allConditionTrackers.push_back(
- new CombinationConditionTracker(condition.id(), index));
- break;
- }
- default:
- ALOGE("Predicate \"%lld\" malformed", (long long)condition.id());
- return false;
- }
- if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
- ALOGE("Duplicate Predicate found!");
- return false;
- }
- conditionTrackerMap[condition.id()] = index;
- conditionConfigs.push_back(condition);
- }
-
- vector<bool> stackTracker(allConditionTrackers.size(), false);
- for (size_t i = 0; i < allConditionTrackers.size(); i++) {
- auto& conditionTracker = allConditionTrackers[i];
- if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
- stackTracker, initialConditionCache)) {
- return false;
- }
- for (const int trackerIndex : conditionTracker->getLogTrackerIndex()) {
- auto& conditionList = trackerToConditionMap[trackerIndex];
- conditionList.push_back(i);
- }
- }
- return true;
-}
-
-bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
- unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps) {
- for (int i = 0; i < config.state_size(); i++) {
- const State& state = config.state(i);
- const int64_t stateId = state.id();
- stateAtomIdMap[stateId] = state.atom_id();
-
- const StateMap& stateMap = state.map();
- for (auto group : stateMap.group()) {
- for (auto value : group.value()) {
- allStateGroupMaps[stateId][value] = group.group_id();
- }
- }
- }
-
- return true;
-}
-
-bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
- const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
- const unordered_map<int64_t, int>& logTrackerMap,
- const unordered_map<int64_t, int>& conditionTrackerMap,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& stateAtomIdMap,
- const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- const vector<ConditionState>& initialConditionCache,
- vector<sp<MetricProducer>>& allMetricProducers,
- unordered_map<int, vector<int>>& conditionToMetricMap,
- unordered_map<int, vector<int>>& trackerToMetricMap,
- unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds,
- unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
- vector<int>& metricsWithActivation) {
- sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
- sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchers);
- const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
- config.event_metric_size() + config.gauge_metric_size() +
- config.value_metric_size();
- allMetricProducers.reserve(allMetricsCount);
-
- // Construct map from metric id to metric activation index. The map will be used to determine
- // the metric activation corresponding to a metric.
- unordered_map<int64_t, int> metricToActivationMap;
- for (int i = 0; i < config.metric_activation_size(); i++) {
- const MetricActivation& metricActivation = config.metric_activation(i);
- int64_t metricId = metricActivation.metric_id();
- if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
- ALOGE("Metric %lld has multiple MetricActivations", (long long) metricId);
- return false;
- }
- metricToActivationMap.insert({metricId, i});
- }
-
- // Build MetricProducers for each metric defined in config.
- // build CountMetricProducer
- for (int i = 0; i < config.count_metric_size(); i++) {
- const CountMetric& metric = config.count_metric(i);
- if (!metric.has_what()) {
- ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id());
- return false;
- }
-
- int metricIndex = allMetricProducers.size();
- metricMap.insert({metric.id(), metricIndex});
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
- return false;
- }
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
- metric.links(), allConditionTrackers, conditionIndex,
- conditionToMetricMap)) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- std::vector<int> slicedStateAtoms;
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- if (metric.slice_by_state_size() > 0) {
- if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
- allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
- return false;
- }
- } else {
- if (metric.state_link_size() > 0) {
- ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> countProducer =
- new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
- timeBaseTimeNs, currentTimeNs, eventActivationMap,
- eventDeactivationMap, slicedStateAtoms, stateGroupMap);
- allMetricProducers.push_back(countProducer);
- }
-
- // build DurationMetricProducer
- for (int i = 0; i < config.duration_metric_size(); i++) {
- int metricIndex = allMetricProducers.size();
- const DurationMetric& metric = config.duration_metric(i);
- metricMap.insert({metric.id(), metricIndex});
-
- auto what_it = conditionTrackerMap.find(metric.what());
- if (what_it == conditionTrackerMap.end()) {
- ALOGE("DurationMetric's \"what\" is invalid");
- return false;
- }
-
- const Predicate& durationWhat = config.predicate(what_it->second);
-
- if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
- ALOGE("DurationMetric's \"what\" must be a simple condition");
- return false;
- }
-
- const auto& simplePredicate = durationWhat.simple_predicate();
-
- bool nesting = simplePredicate.count_nesting();
-
- int trackerIndices[3] = {-1, -1, -1};
- if (!simplePredicate.has_start() ||
- !handleMetricWithLogTrackers(simplePredicate.start(), metricIndex,
- metric.has_dimensions_in_what(), allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndices[0])) {
- ALOGE("Duration metrics must specify a valid the start event matcher");
- return false;
- }
-
- if (simplePredicate.has_stop() &&
- !handleMetricWithLogTrackers(simplePredicate.stop(), metricIndex,
- metric.has_dimensions_in_what(), allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndices[1])) {
- return false;
- }
-
- if (simplePredicate.has_stop_all() &&
- !handleMetricWithLogTrackers(simplePredicate.stop_all(), metricIndex,
- metric.has_dimensions_in_what(), allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndices[2])) {
- return false;
- }
-
- FieldMatcher internalDimensions = simplePredicate.dimensions();
-
- int conditionIndex = -1;
-
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- std::vector<int> slicedStateAtoms;
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- if (metric.slice_by_state_size() > 0) {
- if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
- ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
- return false;
- }
- if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
- allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
- return false;
- }
- } else {
- if (metric.state_link_size() > 0) {
- ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
- return false;
- }
- }
-
- // Check that all metric state links are a subset of dimensions_in_what fields.
- std::vector<Matcher> dimensionsInWhat;
- translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
- for (const auto& stateLink : metric.state_link()) {
- if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> durationMetric = new DurationMetricProducer(
- key, metric, conditionIndex, initialConditionCache, trackerIndices[0],
- trackerIndices[1], trackerIndices[2], nesting, wizard, internalDimensions,
- timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap,
- slicedStateAtoms, stateGroupMap);
-
- allMetricProducers.push_back(durationMetric);
- }
-
- // build EventMetricProducer
- for (int i = 0; i < config.event_metric_size(); i++) {
- int metricIndex = allMetricProducers.size();
- const EventMetric& metric = config.event_metric(i);
- metricMap.insert({metric.id(), metricIndex});
- if (!metric.has_id() || !metric.has_what()) {
- ALOGW("cannot find the metric name or what in config");
- return false;
- }
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex, false, allAtomMatchers,
- logTrackerMap, trackerToMetricMap, trackerIndex)) {
- return false;
- }
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> eventMetric =
- new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
- timeBaseTimeNs, eventActivationMap, eventDeactivationMap);
-
- allMetricProducers.push_back(eventMetric);
- }
-
- // build ValueMetricProducer
- for (int i = 0; i < config.value_metric_size(); i++) {
- const ValueMetric& metric = config.value_metric(i);
- if (!metric.has_what()) {
- ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
- return false;
- }
- if (!metric.has_value_field()) {
- ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
- return false;
- }
- std::vector<Matcher> fieldMatchers;
- translateFieldMatcher(metric.value_field(), &fieldMatchers);
- if (fieldMatchers.size() < 1) {
- ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
- return false;
- }
-
- int metricIndex = allMetricProducers.size();
- metricMap.insert({metric.id(), metricIndex});
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
- return false;
- }
-
- sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
- // If it is pulled atom, it should be simple matcher with one tagId.
- if (atomMatcher->getAtomIds().size() != 1) {
- return false;
- }
- int atomTagId = *(atomMatcher->getAtomIds().begin());
- int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- std::vector<int> slicedStateAtoms;
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- if (metric.slice_by_state_size() > 0) {
- if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
- allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
- return false;
- }
- } else {
- if (metric.state_link_size() > 0) {
- ALOGW("ValueMetric has a MetricStateLink but doesn't have a sliced state");
- return false;
- }
- }
-
- // Check that all metric state links are a subset of dimensions_in_what fields.
- std::vector<Matcher> dimensionsInWhat;
- translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
- for (const auto& stateLink : metric.state_link()) {
- if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(
- config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- metricsWithActivation, eventActivationMap, eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> valueProducer = new ValueMetricProducer(
- key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
- matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, pullerManager,
- eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap);
- allMetricProducers.push_back(valueProducer);
- }
-
- // Gauge metrics.
- for (int i = 0; i < config.gauge_metric_size(); i++) {
- const GaugeMetric& metric = config.gauge_metric(i);
- if (!metric.has_what()) {
- ALOGW("cannot find \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
- return false;
- }
-
- if ((!metric.gauge_fields_filter().has_include_all() ||
- (metric.gauge_fields_filter().include_all() == false)) &&
- !hasLeafNode(metric.gauge_fields_filter().fields())) {
- ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
- return false;
- }
- if ((metric.gauge_fields_filter().has_include_all() &&
- metric.gauge_fields_filter().include_all() == true) &&
- hasLeafNode(metric.gauge_fields_filter().fields())) {
- ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
- return false;
- }
-
- int metricIndex = allMetricProducers.size();
- metricMap.insert({metric.id(), metricIndex});
- int trackerIndex;
- if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
- metric.has_dimensions_in_what(),
- allAtomMatchers, logTrackerMap, trackerToMetricMap,
- trackerIndex)) {
- return false;
- }
-
- sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
- // For GaugeMetric atom, it should be simple matcher with one tagId.
- if (atomMatcher->getAtomIds().size() != 1) {
- return false;
- }
- int atomTagId = *(atomMatcher->getAtomIds().begin());
- int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
-
- int triggerTrackerIndex;
- int triggerAtomId = -1;
- if (metric.has_trigger_event()) {
- if (pullTagId == -1) {
- ALOGW("Pull atom not specified for trigger");
- return false;
- }
- // event_trigger should be used with FIRST_N_SAMPLES
- if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
- return false;
- }
- if (!handlePullMetricTriggerWithLogTrackers(metric.trigger_event(), metricIndex,
- allAtomMatchers, logTrackerMap,
- trackerToMetricMap, triggerTrackerIndex)) {
- return false;
- }
- sp<LogMatchingTracker> triggerAtomMatcher = allAtomMatchers.at(triggerTrackerIndex);
- triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
- }
-
- if (!metric.has_trigger_event() && pullTagId != -1 &&
- metric.sampling_type() == GaugeMetric::FIRST_N_SAMPLES) {
- ALOGW("FIRST_N_SAMPLES is only for pushed event or pull_on_trigger");
- return false;
- }
-
- int conditionIndex = -1;
- if (metric.has_condition()) {
- bool good = handleMetricWithConditions(
- metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
- allConditionTrackers, conditionIndex, conditionToMetricMap);
- if (!good) {
- return false;
- }
- } else {
- if (metric.links_size() > 0) {
- ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
- return false;
- }
- }
-
- unordered_map<int, shared_ptr<Activation>> eventActivationMap;
- unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
- bool success = handleMetricActivation(config, metric.id(), metricIndex,
- metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
- eventDeactivationMap);
- if (!success) return false;
-
- sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
- key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
- matcherWizard, pullTagId, triggerAtomId, atomTagId, timeBaseTimeNs, currentTimeNs,
- pullerManager, eventActivationMap, eventDeactivationMap);
- allMetricProducers.push_back(gaugeProducer);
- }
- for (int i = 0; i < config.no_report_metric_size(); ++i) {
- const auto no_report_metric = config.no_report_metric(i);
- if (metricMap.find(no_report_metric) == metricMap.end()) {
- ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
- return false;
- }
- noReportMetricIds.insert(no_report_metric);
- }
-
- const set<int> whitelistedAtomIds(config.whitelisted_atom_ids().begin(),
- config.whitelisted_atom_ids().end());
- for (const auto& it : allMetricProducers) {
- // Register metrics to StateTrackers
- for (int atomId : it->getSlicedStateAtoms()) {
- // Register listener for non-whitelisted atoms only. Using whitelisted atom as a sliced
- // state atom is not allowed.
- if (whitelistedAtomIds.find(atomId) == whitelistedAtomIds.end()) {
- StateManager::getInstance().registerListener(atomId, it);
- } else {
- return false;
- }
- }
- }
- return true;
-}
-
-bool initAlerts(const StatsdConfig& config,
- const unordered_map<int64_t, int>& metricProducerMap,
- unordered_map<int64_t, int>& alertTrackerMap,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- vector<sp<MetricProducer>>& allMetricProducers,
- vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
- for (int i = 0; i < config.alert_size(); i++) {
- const Alert& alert = config.alert(i);
- const auto& itr = metricProducerMap.find(alert.metric_id());
- if (itr == metricProducerMap.end()) {
- ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
- (long long)alert.metric_id());
- return false;
- }
- if (!alert.has_trigger_if_sum_gt()) {
- ALOGW("invalid alert: missing threshold");
- return false;
- }
- if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
- ALOGW("invalid alert: threshold=%f num_buckets= %d",
- alert.trigger_if_sum_gt(), alert.num_buckets());
- return false;
- }
- const int metricIndex = itr->second;
- sp<MetricProducer> metric = allMetricProducers[metricIndex];
- sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
- if (anomalyTracker == nullptr) {
- // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
- return false;
- }
- alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
- allAnomalyTrackers.push_back(anomalyTracker);
- }
- for (int i = 0; i < config.subscription_size(); ++i) {
- const Subscription& subscription = config.subscription(i);
- if (subscription.rule_type() != Subscription::ALERT) {
- continue;
- }
- if (subscription.subscriber_information_case() ==
- Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
- ALOGW("subscription \"%lld\" has no subscriber info.\"",
- (long long)subscription.id());
- return false;
- }
- const auto& itr = alertTrackerMap.find(subscription.rule_id());
- if (itr == alertTrackerMap.end()) {
- ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
- (long long)subscription.id(), (long long)subscription.rule_id());
- return false;
- }
- const int anomalyTrackerIndex = itr->second;
- allAnomalyTrackers[anomalyTrackerIndex]->addSubscription(subscription);
- }
- return true;
-}
-
-bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
- const sp<AlarmMonitor>& periodicAlarmMonitor,
- const int64_t timeBaseNs, const int64_t currentTimeNs,
- vector<sp<AlarmTracker>>& allAlarmTrackers) {
- unordered_map<int64_t, int> alarmTrackerMap;
- int64_t startMillis = timeBaseNs / 1000 / 1000;
- int64_t currentTimeMillis = currentTimeNs / 1000 /1000;
- for (int i = 0; i < config.alarm_size(); i++) {
- const Alarm& alarm = config.alarm(i);
- if (alarm.offset_millis() <= 0) {
- ALOGW("Alarm offset_millis should be larger than 0.");
- return false;
- }
- if (alarm.period_millis() <= 0) {
- ALOGW("Alarm period_millis should be larger than 0.");
- return false;
- }
- alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
- allAlarmTrackers.push_back(
- new AlarmTracker(startMillis, currentTimeMillis,
- alarm, key, periodicAlarmMonitor));
- }
- for (int i = 0; i < config.subscription_size(); ++i) {
- const Subscription& subscription = config.subscription(i);
- if (subscription.rule_type() != Subscription::ALARM) {
- continue;
- }
- if (subscription.subscriber_information_case() ==
- Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
- ALOGW("subscription \"%lld\" has no subscriber info.\"",
- (long long)subscription.id());
- return false;
- }
- const auto& itr = alarmTrackerMap.find(subscription.rule_id());
- if (itr == alarmTrackerMap.end()) {
- ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
- (long long)subscription.id(), (long long)subscription.rule_id());
- return false;
- }
- const int trackerIndex = itr->second;
- allAlarmTrackers[trackerIndex]->addSubscription(subscription);
- }
- return true;
-}
-
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
- const int64_t currentTimeNs, set<int>& allTagIds,
- vector<sp<LogMatchingTracker>>& allAtomMatchers,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- vector<sp<MetricProducer>>& allMetricProducers,
- vector<sp<AnomalyTracker>>& allAnomalyTrackers,
- vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
- unordered_map<int, std::vector<int>>& conditionToMetricMap,
- unordered_map<int, std::vector<int>>& trackerToMetricMap,
- unordered_map<int, std::vector<int>>& trackerToConditionMap,
- unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
- unordered_map<int64_t, int>& alertTrackerMap,
- vector<int>& metricsWithActivation,
- std::set<int64_t>& noReportMetricIds) {
- unordered_map<int64_t, int> logTrackerMap;
- unordered_map<int64_t, int> conditionTrackerMap;
- vector<ConditionState> initialConditionCache;
- unordered_map<int64_t, int> metricProducerMap;
- unordered_map<int64_t, int> stateAtomIdMap;
- unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-
- if (!initLogTrackers(config, uidMap, logTrackerMap, allAtomMatchers, allTagIds)) {
- ALOGE("initLogMatchingTrackers failed");
- return false;
- }
- VLOG("initLogMatchingTrackers succeed...");
-
- if (!initConditions(key, config, logTrackerMap, conditionTrackerMap, allConditionTrackers,
- trackerToConditionMap, initialConditionCache)) {
- ALOGE("initConditionTrackers failed");
- return false;
- }
-
- if (!initStates(config, stateAtomIdMap, allStateGroupMaps)) {
- ALOGE("initStates failed");
- return false;
- }
- if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, logTrackerMap,
- conditionTrackerMap, allAtomMatchers, stateAtomIdMap, allStateGroupMaps,
- allConditionTrackers, initialConditionCache, allMetricProducers,
- conditionToMetricMap, trackerToMetricMap, metricProducerMap, noReportMetricIds,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- metricsWithActivation)) {
- ALOGE("initMetricProducers failed");
- return false;
- }
- if (!initAlerts(config, metricProducerMap, alertTrackerMap, anomalyAlarmMonitor,
- allMetricProducers, allAnomalyTrackers)) {
- ALOGE("initAlerts failed");
- return false;
- }
- if (!initAlarms(config, key, periodicAlarmMonitor,
- timeBaseNs, currentTimeNs, allPeriodicAlarmTrackers)) {
- ALOGE("initAlarms failed");
- return false;
- }
-
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
deleted file mode 100644
index 96b5c26ff789..000000000000
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "../anomaly/AlarmTracker.h"
-#include "../condition/ConditionTracker.h"
-#include "../external/StatsPullerManager.h"
-#include "../matchers/LogMatchingTracker.h"
-#include "../metrics/MetricProducer.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Helper functions for MetricsManager to initialize from StatsdConfig.
-// *Note*: only initStatsdConfig() should be called from outside.
-// All other functions are intermediate
-// steps, created to make unit tests easier. And most of the parameters in these
-// functions are temporary objects in the initialization phase.
-
-// Initialize the LogMatchingTrackers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input StatsdConfig
-// output:
-// [logTrackerMap]: this map should contain matcher name to index mapping
-// [allAtomMatchers]: should store the sp to all the LogMatchingTracker
-// [allTagIds]: contains the set of all interesting tag ids to this config.
-bool initLogTrackers(const StatsdConfig& config,
- const UidMap& uidMap,
- std::unordered_map<int64_t, int>& logTrackerMap,
- std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
- std::set<int>& allTagIds);
-
-// Initialize ConditionTrackers
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [logTrackerMap]: LogMatchingTracker name to index mapping from previous step.
-// output:
-// [conditionTrackerMap]: this map should contain condition name to index mapping
-// [allConditionTrackers]: stores the sp to all the ConditionTrackers
-// [trackerToConditionMap]: contain the mapping from index of
-// log tracker to condition trackers that use the log tracker
-// [initialConditionCache]: stores the initial conditions for each ConditionTracker
-bool initConditions(const ConfigKey& key, const StatsdConfig& config,
- const std::unordered_map<int64_t, int>& logTrackerMap,
- std::unordered_map<int64_t, int>& conditionTrackerMap,
- std::vector<sp<ConditionTracker>>& allConditionTrackers,
- std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
- std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks,
- std::vector<ConditionState>& initialConditionCache);
-
-// Initialize State maps using State protos in the config. These maps will
-// eventually be passed to MetricProducers to initialize their state info.
-// input:
-// [config]: the input config
-// output:
-// [stateAtomIdMap]: this map should contain the mapping from state ids to atom ids
-// [allStateGroupMaps]: this map should contain the mapping from states ids and state
-// values to state group ids for all states
-bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
- unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps);
-
-// Initialize MetricProducers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [timeBaseSec]: start time base for all metrics
-// [logTrackerMap]: LogMatchingTracker name to index mapping from previous step.
-// [conditionTrackerMap]: condition name to index mapping
-// [stateAtomIdMap]: contains the mapping from state ids to atom ids
-// [allStateGroupMaps]: contains the mapping from atom ids and state values to
-// state group ids for all states
-// output:
-// [allMetricProducers]: contains the list of sp to the MetricProducers created.
-// [conditionToMetricMap]: contains the mapping from condition tracker index to
-// the list of MetricProducer index
-// [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index.
-bool initMetrics(
- const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
- const int64_t currentTimeNs, UidMap& uidMap, const sp<StatsPullerManager>& pullerManager,
- const std::unordered_map<int64_t, int>& logTrackerMap,
- const std::unordered_map<int64_t, int>& conditionTrackerMap,
- const std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks,
- const vector<sp<LogMatchingTracker>>& allAtomMatchers,
- const unordered_map<int64_t, int>& stateAtomIdMap,
- const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
- vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::vector<ConditionState>& initialConditionCache,
- std::vector<sp<MetricProducer>>& allMetricProducers,
- std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
- std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
- std::set<int64_t>& noReportMetricIds,
- std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
- std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
- std::vector<int>& metricsWithActivation);
-
-// Initialize MetricsManager from StatsdConfig.
-// Parameters are the members of MetricsManager. See MetricsManager for declaration.
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
- const sp<StatsPullerManager>& pullerManager,
- const sp<AlarmMonitor>& anomalyAlarmMonitor,
- const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
- const int64_t currentTimeNs, std::set<int>& allTagIds,
- std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
- std::vector<sp<ConditionTracker>>& allConditionTrackers,
- std::vector<sp<MetricProducer>>& allMetricProducers,
- vector<sp<AnomalyTracker>>& allAnomalyTrackers,
- vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
- std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
- std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
- std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
- unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
- unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
- std::unordered_map<int64_t, int>& alertTrackerMap,
- vector<int>& metricsWithActivation,
- std::set<int64_t>& noReportMetricIds);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
deleted file mode 100644
index 6c50a8c41770..000000000000
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STATSD_PACKAGE_INFO_LISTENER_H
-#define STATSD_PACKAGE_INFO_LISTENER_H
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PackageInfoListener : public virtual android::RefBase {
-public:
- // Uid map will notify this listener that the app with apk name and uid has been upgraded to
- // the specified version.
- virtual void notifyAppUpgrade(const int64_t& eventTimeNs, const std::string& apk,
- const int uid, const int64_t version) = 0;
-
- // Notify interested listeners that the given apk and uid combination no longer exits.
- virtual void notifyAppRemoved(const int64_t& eventTimeNs, const std::string& apk,
- const int uid) = 0;
-
- // Notify the listener that the UidMap snapshot is available.
- virtual void onUidMapReceived(const int64_t& eventTimeNs) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // STATSD_PACKAGE_INFO_LISTENER_H
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
deleted file mode 100644
index acf40c88a00d..000000000000
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, versionCode 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "hash.h"
-#include "stats_log_util.h"
-#include "guardrail/StatsdStats.h"
-#include "packages/UidMap.h"
-
-#include <inttypes.h>
-
-using namespace android;
-
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
-const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
-const int FIELD_ID_SNAPSHOT_PACKAGE_DELETED = 4;
-const int FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH = 5;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING = 6;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH = 7;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER = 8;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH = 9;
-const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
-const int FIELD_ID_SNAPSHOTS = 1;
-const int FIELD_ID_CHANGES = 2;
-const int FIELD_ID_CHANGE_DELETION = 1;
-const int FIELD_ID_CHANGE_TIMESTAMP = 2;
-const int FIELD_ID_CHANGE_PACKAGE = 3;
-const int FIELD_ID_CHANGE_UID = 4;
-const int FIELD_ID_CHANGE_NEW_VERSION = 5;
-const int FIELD_ID_CHANGE_PREV_VERSION = 6;
-const int FIELD_ID_CHANGE_PACKAGE_HASH = 7;
-const int FIELD_ID_CHANGE_NEW_VERSION_STRING = 8;
-const int FIELD_ID_CHANGE_PREV_VERSION_STRING = 9;
-const int FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH = 10;
-const int FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH = 11;
-
-UidMap::UidMap() : mBytesUsed(0) {}
-
-UidMap::~UidMap() {}
-
-sp<UidMap> UidMap::getInstance() {
- static sp<UidMap> sInstance = new UidMap();
- return sInstance;
-}
-
-bool UidMap::hasApp(int uid, const string& packageName) const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mMap.find(std::make_pair(uid, packageName));
- return it != mMap.end() && !it->second.deleted;
-}
-
-string UidMap::normalizeAppName(const string& appName) const {
- string normalizedName = appName;
- std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
- return normalizedName;
-}
-
-std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const {
- lock_guard<mutex> lock(mMutex);
- return getAppNamesFromUidLocked(uid,returnNormalized);
-}
-
-std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const {
- std::set<string> names;
- for (const auto& kv : mMap) {
- if (kv.first.first == uid && !kv.second.deleted) {
- names.insert(returnNormalized ? normalizeAppName(kv.first.second) : kv.first.second);
- }
- }
- return names;
-}
-
-int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
- lock_guard<mutex> lock(mMutex);
-
- auto it = mMap.find(std::make_pair(uid, packageName));
- if (it == mMap.end() || it->second.deleted) {
- return 0;
- }
- return it->second.versionCode;
-}
-
-void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
- const vector<int64_t>& versionCode, const vector<String16>& versionString,
- const vector<String16>& packageName, const vector<String16>& installer) {
- wp<PackageInfoListener> broadcast = NULL;
- {
- lock_guard<mutex> lock(mMutex); // Exclusively lock for updates.
-
- std::unordered_map<std::pair<int, string>, AppData, PairHash> deletedApps;
-
- // Copy all the deleted apps.
- for (const auto& kv : mMap) {
- if (kv.second.deleted) {
- deletedApps[kv.first] = kv.second;
- }
- }
-
- mMap.clear();
- for (size_t j = 0; j < uid.size(); j++) {
- string package = string(String8(packageName[j]).string());
- mMap[std::make_pair(uid[j], package)] =
- AppData(versionCode[j], string(String8(versionString[j]).string()),
- string(String8(installer[j]).string()));
- }
-
- for (const auto& kv : deletedApps) {
- auto mMapIt = mMap.find(kv.first);
- if (mMapIt != mMap.end()) {
- // Insert this deleted app back into the current map.
- mMap[kv.first] = kv.second;
- }
- }
-
- ensureBytesUsedBelowLimit();
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- broadcast = mSubscriber;
- }
- // To avoid invoking callback while holding the internal lock. we get a copy of the listener
- // and invoke the callback. It's still possible that after we copy the listener, it removes
- // itself before we call it. It's then the listener's job to handle it (expect the callback to
- // be called after listener is removed, and the listener should properly ignore it).
- auto strongPtr = broadcast.promote();
- if (strongPtr != NULL) {
- strongPtr->onUidMapReceived(timestamp);
- }
-}
-
-void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid,
- const int64_t& versionCode, const String16& versionString,
- const String16& installer) {
- wp<PackageInfoListener> broadcast = NULL;
- string appName = string(String8(app_16).string());
- {
- lock_guard<mutex> lock(mMutex);
- int32_t prevVersion = 0;
- string prevVersionString = "";
- string newVersionString = string(String8(versionString).string());
- bool found = false;
- auto it = mMap.find(std::make_pair(uid, appName));
- if (it != mMap.end()) {
- found = true;
- prevVersion = it->second.versionCode;
- prevVersionString = it->second.versionString;
- it->second.versionCode = versionCode;
- it->second.versionString = newVersionString;
- it->second.installer = string(String8(installer).string());
- it->second.deleted = false;
- }
- if (!found) {
- // Otherwise, we need to add an app at this uid.
- mMap[std::make_pair(uid, appName)] =
- AppData(versionCode, newVersionString, string(String8(installer).string()));
- } else {
- // Only notify the listeners if this is an app upgrade. If this app is being installed
- // for the first time, then we don't notify the listeners.
- // It's also OK to split again if we're forming a partial bucket after re-installing an
- // app after deletion.
- broadcast = mSubscriber;
- }
- mChanges.emplace_back(false, timestamp, appName, uid, versionCode, newVersionString,
- prevVersion, prevVersionString);
- mBytesUsed += kBytesChangeRecord;
- ensureBytesUsedBelowLimit();
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- StatsdStats::getInstance().setUidMapChanges(mChanges.size());
- }
-
- auto strongPtr = broadcast.promote();
- if (strongPtr != NULL) {
- strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
- }
-}
-
-void UidMap::ensureBytesUsedBelowLimit() {
- size_t limit;
- if (maxBytesOverride <= 0) {
- limit = StatsdStats::kMaxBytesUsedUidMap;
- } else {
- limit = maxBytesOverride;
- }
- while (mBytesUsed > limit) {
- ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
- if (mChanges.size() > 0) {
- mBytesUsed -= kBytesChangeRecord;
- mChanges.pop_front();
- StatsdStats::getInstance().noteUidMapDropped(1);
- }
- }
-}
-
-void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) {
- wp<PackageInfoListener> broadcast = NULL;
- string app = string(String8(app_16).string());
- {
- lock_guard<mutex> lock(mMutex);
-
- int64_t prevVersion = 0;
- string prevVersionString = "";
- auto key = std::make_pair(uid, app);
- auto it = mMap.find(key);
- if (it != mMap.end() && !it->second.deleted) {
- prevVersion = it->second.versionCode;
- prevVersionString = it->second.versionString;
- it->second.deleted = true;
- mDeletedApps.push_back(key);
- }
- if (mDeletedApps.size() > StatsdStats::kMaxDeletedAppsInUidMap) {
- // Delete the oldest one.
- auto oldest = mDeletedApps.front();
- mDeletedApps.pop_front();
- mMap.erase(oldest);
- StatsdStats::getInstance().noteUidMapAppDeletionDropped();
- }
- mChanges.emplace_back(true, timestamp, app, uid, 0, "", prevVersion, prevVersionString);
- mBytesUsed += kBytesChangeRecord;
- ensureBytesUsedBelowLimit();
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- StatsdStats::getInstance().setUidMapChanges(mChanges.size());
- broadcast = mSubscriber;
- }
-
- auto strongPtr = broadcast.promote();
- if (strongPtr != NULL) {
- strongPtr->notifyAppRemoved(timestamp, app, uid);
- }
-}
-
-void UidMap::setListener(wp<PackageInfoListener> listener) {
- lock_guard<mutex> lock(mMutex); // Lock for updates
- mSubscriber = listener;
-}
-
-void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
- lock_guard<mutex> lock(mIsolatedMutex);
-
- mIsolatedUidMap[isolatedUid] = parentUid;
-}
-
-void UidMap::removeIsolatedUid(int isolatedUid) {
- lock_guard<mutex> lock(mIsolatedMutex);
-
- auto it = mIsolatedUidMap.find(isolatedUid);
- if (it != mIsolatedUidMap.end()) {
- mIsolatedUidMap.erase(it);
- }
-}
-
-int UidMap::getHostUidOrSelf(int uid) const {
- lock_guard<mutex> lock(mIsolatedMutex);
-
- auto it = mIsolatedUidMap.find(uid);
- if (it != mIsolatedUidMap.end()) {
- return it->second;
- }
- return uid;
-}
-
-void UidMap::clearOutput() {
- mChanges.clear();
- // Also update the guardrail trackers.
- StatsdStats::getInstance().setUidMapChanges(0);
- mBytesUsed = 0;
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-}
-
-int64_t UidMap::getMinimumTimestampNs() {
- int64_t m = 0;
- for (const auto& kv : mLastUpdatePerConfigKey) {
- if (m == 0) {
- m = kv.second;
- } else if (kv.second < m) {
- m = kv.second;
- }
- }
- return m;
-}
-
-size_t UidMap::getBytesUsed() const {
- return mBytesUsed;
-}
-
-void UidMap::writeUidMapSnapshot(int64_t timestamp, bool includeVersionStrings,
- bool includeInstaller, const std::set<int32_t>& interestingUids,
- std::set<string>* str_set, ProtoOutputStream* proto) {
- lock_guard<mutex> lock(mMutex);
-
- writeUidMapSnapshotLocked(timestamp, includeVersionStrings, includeInstaller, interestingUids,
- str_set, proto);
-}
-
-void UidMap::writeUidMapSnapshotLocked(int64_t timestamp, bool includeVersionStrings,
- bool includeInstaller,
- const std::set<int32_t>& interestingUids,
- std::set<string>* str_set, ProtoOutputStream* proto) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP, (long long)timestamp);
- for (const auto& kv : mMap) {
- if (!interestingUids.empty() &&
- interestingUids.find(kv.first.first) == interestingUids.end()) {
- continue;
- }
- uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_SNAPSHOT_PACKAGE_INFO);
- if (str_set != nullptr) {
- str_set->insert(kv.first.second);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH,
- (long long)Hash64(kv.first.second));
- if (includeVersionStrings) {
- str_set->insert(kv.second.versionString);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH,
- (long long)Hash64(kv.second.versionString));
- }
- if (includeInstaller) {
- str_set->insert(kv.second.installer);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH,
- (long long)Hash64(kv.second.installer));
- }
- } else {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, kv.first.second);
- if (includeVersionStrings) {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING,
- kv.second.versionString);
- }
- if (includeInstaller) {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER,
- kv.second.installer);
- }
- }
-
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION,
- (long long)kv.second.versionCode);
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, kv.first.first);
- proto->write(FIELD_TYPE_BOOL | FIELD_ID_SNAPSHOT_PACKAGE_DELETED, kv.second.deleted);
- proto->end(token);
- }
-}
-
-void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set,
- bool includeVersionStrings, bool includeInstaller,
- ProtoOutputStream* proto) {
- lock_guard<mutex> lock(mMutex); // Lock for updates
-
- for (const ChangeRecord& record : mChanges) {
- if (record.timestampNs > mLastUpdatePerConfigKey[key]) {
- uint64_t changesToken =
- proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
- proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP,
- (long long)record.timestampNs);
- if (str_set != nullptr) {
- str_set->insert(record.package);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PACKAGE_HASH,
- (long long)Hash64(record.package));
- if (includeVersionStrings) {
- str_set->insert(record.versionString);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH,
- (long long)Hash64(record.versionString));
- str_set->insert(record.prevVersionString);
- proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH,
- (long long)Hash64(record.prevVersionString));
- }
- } else {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
- if (includeVersionStrings) {
- proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_NEW_VERSION_STRING,
- record.versionString);
- proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PREV_VERSION_STRING,
- record.prevVersionString);
- }
- }
-
- proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_NEW_VERSION, (long long)record.version);
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_PREV_VERSION,
- (long long)record.prevVersion);
- proto->end(changesToken);
- }
- }
-
- // Write snapshot from current uid map state.
- uint64_t snapshotsToken =
- proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
- writeUidMapSnapshotLocked(timestamp, includeVersionStrings, includeInstaller,
- std::set<int32_t>() /*empty uid set means including every uid*/,
- str_set, proto);
- proto->end(snapshotsToken);
-
- int64_t prevMin = getMinimumTimestampNs();
- mLastUpdatePerConfigKey[key] = timestamp;
- int64_t newMin = getMinimumTimestampNs();
-
- if (newMin > prevMin) { // Delete anything possible now that the minimum has
- // moved forward.
- int64_t cutoff_nanos = newMin;
- for (auto it_changes = mChanges.begin(); it_changes != mChanges.end();) {
- if (it_changes->timestampNs < cutoff_nanos) {
- mBytesUsed -= kBytesChangeRecord;
- it_changes = mChanges.erase(it_changes);
- } else {
- ++it_changes;
- }
- }
- }
- StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
- StatsdStats::getInstance().setUidMapChanges(mChanges.size());
-}
-
-void UidMap::printUidMap(int out) const {
- lock_guard<mutex> lock(mMutex);
-
- for (const auto& kv : mMap) {
- if (!kv.second.deleted) {
- dprintf(out, "%s, v%" PRId64 ", %s, %s (%i)\n", kv.first.second.c_str(),
- kv.second.versionCode, kv.second.versionString.c_str(),
- kv.second.installer.c_str(), kv.first.first);
- }
- }
-}
-
-void UidMap::OnConfigUpdated(const ConfigKey& key) {
- mLastUpdatePerConfigKey[key] = -1;
-}
-
-void UidMap::OnConfigRemoved(const ConfigKey& key) {
- mLastUpdatePerConfigKey.erase(key);
-}
-
-set<int32_t> UidMap::getAppUid(const string& package) const {
- lock_guard<mutex> lock(mMutex);
-
- set<int32_t> results;
- for (const auto& kv : mMap) {
- if (kv.first.second == package && !kv.second.deleted) {
- results.insert(kv.first.first);
- }
- }
- return results;
-}
-
-// Note not all the following AIDs are used as uids. Some are used only for gids.
-// It's ok to leave them in the map, but we won't ever see them in the log's uid field.
-// App's uid starts from 10000, and will not overlap with the following AIDs.
-const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
- {"AID_SYSTEM", 1000},
- {"AID_RADIO", 1001},
- {"AID_BLUETOOTH", 1002},
- {"AID_GRAPHICS", 1003},
- {"AID_INPUT", 1004},
- {"AID_AUDIO", 1005},
- {"AID_CAMERA", 1006},
- {"AID_LOG", 1007},
- {"AID_COMPASS", 1008},
- {"AID_MOUNT", 1009},
- {"AID_WIFI", 1010},
- {"AID_ADB", 1011},
- {"AID_INSTALL", 1012},
- {"AID_MEDIA", 1013},
- {"AID_DHCP", 1014},
- {"AID_SDCARD_RW", 1015},
- {"AID_VPN", 1016},
- {"AID_KEYSTORE", 1017},
- {"AID_USB", 1018},
- {"AID_DRM", 1019},
- {"AID_MDNSR", 1020},
- {"AID_GPS", 1021},
- // {"AID_UNUSED1", 1022},
- {"AID_MEDIA_RW", 1023},
- {"AID_MTP", 1024},
- // {"AID_UNUSED2", 1025},
- {"AID_DRMRPC", 1026},
- {"AID_NFC", 1027},
- {"AID_SDCARD_R", 1028},
- {"AID_CLAT", 1029},
- {"AID_LOOP_RADIO", 1030},
- {"AID_MEDIA_DRM", 1031},
- {"AID_PACKAGE_INFO", 1032},
- {"AID_SDCARD_PICS", 1033},
- {"AID_SDCARD_AV", 1034},
- {"AID_SDCARD_ALL", 1035},
- {"AID_LOGD", 1036},
- {"AID_SHARED_RELRO", 1037},
- {"AID_DBUS", 1038},
- {"AID_TLSDATE", 1039},
- {"AID_MEDIA_EX", 1040},
- {"AID_AUDIOSERVER", 1041},
- {"AID_METRICS_COLL", 1042},
- {"AID_METRICSD", 1043},
- {"AID_WEBSERV", 1044},
- {"AID_DEBUGGERD", 1045},
- {"AID_MEDIA_CODEC", 1046},
- {"AID_CAMERASERVER", 1047},
- {"AID_FIREWALL", 1048},
- {"AID_TRUNKS", 1049},
- {"AID_NVRAM", 1050},
- {"AID_DNS", 1051},
- {"AID_DNS_TETHER", 1052},
- {"AID_WEBVIEW_ZYGOTE", 1053},
- {"AID_VEHICLE_NETWORK", 1054},
- {"AID_MEDIA_AUDIO", 1055},
- {"AID_MEDIA_VIDEO", 1056},
- {"AID_MEDIA_IMAGE", 1057},
- {"AID_TOMBSTONED", 1058},
- {"AID_MEDIA_OBB", 1059},
- {"AID_ESE", 1060},
- {"AID_OTA_UPDATE", 1061},
- {"AID_AUTOMOTIVE_EVS", 1062},
- {"AID_LOWPAN", 1063},
- {"AID_HSM", 1064},
- {"AID_RESERVED_DISK", 1065},
- {"AID_STATSD", 1066},
- {"AID_INCIDENTD", 1067},
- {"AID_SECURE_ELEMENT", 1068},
- {"AID_LMKD", 1069},
- {"AID_LLKD", 1070},
- {"AID_IORAPD", 1071},
- {"AID_GPU_SERVICE", 1072},
- {"AID_NETWORK_STACK", 1073},
- {"AID_GSID", 1074},
- {"AID_FSVERITY_CERT", 1075},
- {"AID_CREDSTORE", 1076},
- {"AID_EXTERNAL_STORAGE", 1077},
- {"AID_EXT_DATA_RW", 1078},
- {"AID_EXT_OBB_RW", 1079},
- {"AID_CONTEXT_HUB", 1080},
- {"AID_SHELL", 2000},
- {"AID_CACHE", 2001},
- {"AID_DIAG", 2002}};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
deleted file mode 100644
index 22250aee402e..000000000000
--- a/cmds/statsd/src/packages/UidMap.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
-#include "packages/PackageInfoListener.h"
-#include "stats_util.h"
-
-#include <gtest/gtest_prod.h>
-#include <stdio.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-
-#include <list>
-#include <mutex>
-#include <set>
-#include <string>
-#include <unordered_map>
-
-using namespace android;
-using namespace std;
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct AppData {
- int64_t versionCode;
- string versionString;
- string installer;
- bool deleted;
-
- // Empty constructor needed for unordered map.
- AppData() {
- }
-
- AppData(const int64_t v, const string& versionString, const string& installer)
- : versionCode(v), versionString(versionString), installer(installer), deleted(false){};
-};
-
-// When calling appendUidMap, we retrieve all the ChangeRecords since the last
-// timestamp we called appendUidMap for this configuration key.
-struct ChangeRecord {
- const bool deletion;
- const int64_t timestampNs;
- const string package;
- const int32_t uid;
- const int64_t version;
- const int64_t prevVersion;
- const string versionString;
- const string prevVersionString;
-
- ChangeRecord(const bool isDeletion, const int64_t timestampNs, const string& package,
- const int32_t uid, const int64_t version, const string versionString,
- const int64_t prevVersion, const string prevVersionString)
- : deletion(isDeletion),
- timestampNs(timestampNs),
- package(package),
- uid(uid),
- version(version),
- prevVersion(prevVersion),
- versionString(versionString),
- prevVersionString(prevVersionString) {
- }
-};
-
-const unsigned int kBytesChangeRecord = sizeof(struct ChangeRecord);
-
-// UidMap keeps track of what the corresponding app name (APK name) and version code for every uid
-// at any given moment. This map must be updated by StatsCompanionService.
-class UidMap : public virtual android::RefBase {
-public:
- UidMap();
- ~UidMap();
- static const std::map<std::string, uint32_t> sAidToUidMapping;
-
- static sp<UidMap> getInstance();
- /*
- * All three inputs must be the same size, and the jth element in each array refers to the same
- * tuple, ie. uid[j] corresponds to packageName[j] with versionCode[j].
- */
- void updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
- const vector<int64_t>& versionCode, const vector<String16>& versionString,
- const vector<String16>& packageName, const vector<String16>& installer);
-
- void updateApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid,
- const int64_t& versionCode, const String16& versionString,
- const String16& installer);
- void removeApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid);
-
- // Returns true if the given uid contains the specified app (eg. com.google.android.gms).
- bool hasApp(int uid, const string& packageName) const;
-
- // Returns the app names from uid.
- std::set<string> getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const;
-
- int64_t getAppVersion(int uid, const string& packageName) const;
-
- // Helper for debugging contents of this uid map. Can be triggered with:
- // adb shell cmd stats print-uid-map
- void printUidMap(int outFd) const;
-
- // Command for indicating to the map that StatsLogProcessor should be notified if an app is
- // updated. This allows metric producers and managers to distinguish when the same uid or app
- // represents a different version of an app.
- void setListener(wp<PackageInfoListener> listener);
-
- // Informs uid map that a config is added/updated. Used for keeping mConfigKeys up to date.
- void OnConfigUpdated(const ConfigKey& key);
-
- // Informs uid map that a config is removed. Used for keeping mConfigKeys up to date.
- void OnConfigRemoved(const ConfigKey& key);
-
- void assignIsolatedUid(int isolatedUid, int parentUid);
- void removeIsolatedUid(int isolatedUid);
-
- // Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in.
- virtual int getHostUidOrSelf(int uid) const;
-
- // Gets all snapshots and changes that have occurred since the last output.
- // If every config key has received a change or snapshot record, then this
- // record is deleted.
- void appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set,
- bool includeVersionStrings, bool includeInstaller,
- ProtoOutputStream* proto);
-
- // Forces the output to be cleared. We still generate a snapshot based on the current state.
- // This results in extra data uploaded but helps us reconstruct the uid mapping on the server
- // in case we lose a previous upload.
- void clearOutput();
-
- // Get currently cached value of memory used by UID map.
- size_t getBytesUsed() const;
-
- virtual std::set<int32_t> getAppUid(const string& package) const;
-
- // Write current PackageInfoSnapshot to ProtoOutputStream.
- // interestingUids: If not empty, only write the package info for these uids. If empty, write
- // package info for all uids.
- // str_set: if not null, add new string to the set and write str_hash to proto
- // if null, write string to proto.
- void writeUidMapSnapshot(int64_t timestamp, bool includeVersionStrings, bool includeInstaller,
- const std::set<int32_t>& interestingUids, std::set<string>* str_set,
- ProtoOutputStream* proto);
-
-private:
- std::set<string> getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const;
- string normalizeAppName(const string& appName) const;
-
- void writeUidMapSnapshotLocked(int64_t timestamp, bool includeVersionStrings,
- bool includeInstaller, const std::set<int32_t>& interestingUids,
- std::set<string>* str_set, ProtoOutputStream* proto);
-
- mutable mutex mMutex;
- mutable mutex mIsolatedMutex;
-
- struct PairHash {
- size_t operator()(std::pair<int, string> p) const noexcept {
- std::hash<std::string> hash_fn;
- return hash_fn(std::to_string(p.first) + p.second);
- }
- };
- // Maps uid and package name to application data.
- std::unordered_map<std::pair<int, string>, AppData, PairHash> mMap;
-
- // Maps isolated uid to the parent uid. Any metrics for an isolated uid will instead contribute
- // to the parent uid.
- std::unordered_map<int, int> mIsolatedUidMap;
-
- // Record the changes that can be provided with the uploads.
- std::list<ChangeRecord> mChanges;
-
- // Store which uid and apps represent deleted ones.
- std::list<std::pair<int, string>> mDeletedApps;
-
- // Notify StatsLogProcessor if there's an upgrade/removal in any app.
- wp<PackageInfoListener> mSubscriber;
-
- // Mapping of config keys we're aware of to the epoch time they last received an update. This
- // lets us know it's safe to delete events older than the oldest update. The value is nanosec.
- // Value of -1 denotes this config key has never received an upload.
- std::unordered_map<ConfigKey, int64_t> mLastUpdatePerConfigKey;
-
- // Returns the minimum value from mConfigKeys.
- int64_t getMinimumTimestampNs();
-
- // If our current used bytes is above the limit, then we clear out the earliest snapshot. If
- // there are no more snapshots, then we clear out the earliest delta. We repeat the deletions
- // until the memory consumed by mOutput is below the specified limit.
- void ensureBytesUsedBelowLimit();
-
- // Override used for testing the max memory allowed by uid map. 0 means we use the value
- // specified in StatsdStats.h with the rest of the guardrails.
- size_t maxBytesOverride = 0;
-
- // Cache the size of mOutput;
- size_t mBytesUsed;
-
- // Allows unit-test to access private methods.
- FRIEND_TEST(UidMapTest, TestClearingOutput);
- FRIEND_TEST(UidMapTest, TestRemovedAppRetained);
- FRIEND_TEST(UidMapTest, TestRemovedAppOverGuardrail);
- FRIEND_TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot);
- FRIEND_TEST(UidMapTest, TestMemoryComputed);
- FRIEND_TEST(UidMapTest, TestMemoryGuardrail);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
deleted file mode 100644
index fd883c29dba0..000000000000
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "ShellSubscriber.h"
-
-#include <android-base/file.h>
-
-#include "matchers/matcher_util.h"
-#include "stats_log_util.h"
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const static int FIELD_ID_ATOM = 1;
-
-void ShellSubscriber::startNewSubscription(int in, int out, int timeoutSec) {
- int myToken = claimToken();
- VLOG("ShellSubscriber: new subscription %d has come in", myToken);
- mSubscriptionShouldEnd.notify_one();
-
- shared_ptr<SubscriptionInfo> mySubscriptionInfo = make_shared<SubscriptionInfo>(in, out);
- if (!readConfig(mySubscriptionInfo)) return;
-
- {
- std::unique_lock<std::mutex> lock(mMutex);
- mSubscriptionInfo = mySubscriptionInfo;
- spawnHelperThread(myToken);
- waitForSubscriptionToEndLocked(mySubscriptionInfo, myToken, lock, timeoutSec);
-
- if (mSubscriptionInfo == mySubscriptionInfo) {
- mSubscriptionInfo = nullptr;
- }
-
- }
-}
-
-void ShellSubscriber::spawnHelperThread(int myToken) {
- std::thread t([this, myToken] { pullAndSendHeartbeats(myToken); });
- t.detach();
-}
-
-void ShellSubscriber::waitForSubscriptionToEndLocked(shared_ptr<SubscriptionInfo> myInfo,
- int myToken,
- std::unique_lock<std::mutex>& lock,
- int timeoutSec) {
- if (timeoutSec > 0) {
- mSubscriptionShouldEnd.wait_for(lock, timeoutSec * 1s, [this, myToken, &myInfo] {
- return mToken != myToken || !myInfo->mClientAlive;
- });
- } else {
- mSubscriptionShouldEnd.wait(lock, [this, myToken, &myInfo] {
- return mToken != myToken || !myInfo->mClientAlive;
- });
- }
-}
-
-// Atomically claim the next token. Token numbers denote subscriber ordering.
-int ShellSubscriber::claimToken() {
- std::unique_lock<std::mutex> lock(mMutex);
- int myToken = ++mToken;
- return myToken;
-}
-
-// Read and parse single config. There should only one config per input.
-bool ShellSubscriber::readConfig(shared_ptr<SubscriptionInfo> subscriptionInfo) {
- // Read the size of the config.
- size_t bufferSize;
- if (!android::base::ReadFully(subscriptionInfo->mInputFd, &bufferSize, sizeof(bufferSize))) {
- return false;
- }
-
- // Read the config.
- vector<uint8_t> buffer(bufferSize);
- if (!android::base::ReadFully(subscriptionInfo->mInputFd, buffer.data(), bufferSize)) {
- return false;
- }
-
- // Parse the config.
- ShellSubscription config;
- if (!config.ParseFromArray(buffer.data(), bufferSize)) {
- return false;
- }
-
- // Update SubscriptionInfo with state from config
- for (const auto& pushed : config.pushed()) {
- subscriptionInfo->mPushedMatchers.push_back(pushed);
- }
-
- for (const auto& pulled : config.pulled()) {
- vector<string> packages;
- vector<int32_t> uids;
- for (const string& pkg : pulled.packages()) {
- auto it = UidMap::sAidToUidMapping.find(pkg);
- if (it != UidMap::sAidToUidMapping.end()) {
- uids.push_back(it->second);
- } else {
- packages.push_back(pkg);
- }
- }
-
- subscriptionInfo->mPulledInfo.emplace_back(pulled.matcher(), pulled.freq_millis(), packages,
- uids);
- VLOG("adding matcher for pulled atom %d", pulled.matcher().atom_id());
- }
-
- return true;
-}
-
-void ShellSubscriber::pullAndSendHeartbeats(int myToken) {
- VLOG("ShellSubscriber: helper thread %d starting", myToken);
- while (true) {
- int64_t sleepTimeMs = INT_MAX;
- {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mSubscriptionInfo || mToken != myToken) {
- VLOG("ShellSubscriber: helper thread %d done!", myToken);
- return;
- }
-
- int64_t nowMillis = getElapsedRealtimeMillis();
- int64_t nowNanos = getElapsedRealtimeNs();
- for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
- if (pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval >= nowMillis) {
- continue;
- }
-
- vector<int32_t> uids;
- getUidsForPullAtom(&uids, pullInfo);
-
- vector<std::shared_ptr<LogEvent>> data;
- mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), uids, nowNanos, &data);
- VLOG("Pulled %zu atoms with id %d", data.size(), pullInfo.mPullerMatcher.atom_id());
- writePulledAtomsLocked(data, pullInfo.mPullerMatcher);
-
- pullInfo.mPrevPullElapsedRealtimeMs = nowMillis;
- }
-
- // Send a heartbeat, consisting of a data size of 0, if perfd hasn't recently received
- // data from statsd. When it receives the data size of 0, perfd will not expect any
- // atoms and recheck whether the subscription should end.
- if (nowMillis - mLastWriteMs > kMsBetweenHeartbeats) {
- attemptWriteToPipeLocked(/*dataSize=*/0);
- }
-
- // Determine how long to sleep before doing more work.
- for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
- int64_t nextPullTime = pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval;
- int64_t timeBeforePull = nextPullTime - nowMillis; // guaranteed to be non-negative
- if (timeBeforePull < sleepTimeMs) sleepTimeMs = timeBeforePull;
- }
- int64_t timeBeforeHeartbeat = (mLastWriteMs + kMsBetweenHeartbeats) - nowMillis;
- if (timeBeforeHeartbeat < sleepTimeMs) sleepTimeMs = timeBeforeHeartbeat;
- }
-
- VLOG("ShellSubscriber: helper thread %d sleeping for %lld ms", myToken,
- (long long)sleepTimeMs);
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
- }
-}
-
-void ShellSubscriber::getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo) {
- uids->insert(uids->end(), pullInfo.mPullUids.begin(), pullInfo.mPullUids.end());
- // This is slow. Consider storing the uids per app and listening to uidmap updates.
- for (const string& pkg : pullInfo.mPullPackages) {
- set<int32_t> uidsForPkg = mUidMap->getAppUid(pkg);
- uids->insert(uids->end(), uidsForPkg.begin(), uidsForPkg.end());
- }
- uids->push_back(DEFAULT_PULL_UID);
-}
-
-void ShellSubscriber::writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
- const SimpleAtomMatcher& matcher) {
- mProto.clear();
- int count = 0;
- for (const auto& event : data) {
- if (matchesSimple(*mUidMap, matcher, *event)) {
- count++;
- uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
- util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
- event->ToProto(mProto);
- mProto.end(atomToken);
- }
- }
-
- if (count > 0) attemptWriteToPipeLocked(mProto.size());
-}
-
-void ShellSubscriber::onLogEvent(const LogEvent& event) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mSubscriptionInfo) return;
-
- mProto.clear();
- for (const auto& matcher : mSubscriptionInfo->mPushedMatchers) {
- if (matchesSimple(*mUidMap, matcher, event)) {
- uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
- util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
- event.ToProto(mProto);
- mProto.end(atomToken);
- attemptWriteToPipeLocked(mProto.size());
- }
- }
-}
-
-// Tries to write the atom encoded in mProto to the pipe. If the write fails
-// because the read end of the pipe has closed, signals to other threads that
-// the subscription should end.
-void ShellSubscriber::attemptWriteToPipeLocked(size_t dataSize) {
- // First, write the payload size.
- if (!android::base::WriteFully(mSubscriptionInfo->mOutputFd, &dataSize, sizeof(dataSize))) {
- mSubscriptionInfo->mClientAlive = false;
- mSubscriptionShouldEnd.notify_one();
- return;
- }
-
- // Then, write the payload if this is not just a heartbeat.
- if (dataSize > 0 && !mProto.flush(mSubscriptionInfo->mOutputFd)) {
- mSubscriptionInfo->mClientAlive = false;
- mSubscriptionShouldEnd.notify_one();
- return;
- }
-
- mLastWriteMs = getElapsedRealtimeMillis();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h
deleted file mode 100644
index 4c05fa7f71c2..000000000000
--- a/cmds/statsd/src/shell/ShellSubscriber.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/util/ProtoOutputStream.h>
-#include <private/android_filesystem_config.h>
-
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include "external/StatsPullerManager.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Handles atoms subscription via shell cmd.
- *
- * A shell subscription lasts *until shell exits*. Unlike config based clients, a shell client
- * communicates with statsd via file descriptors. They can subscribe pushed and pulled atoms.
- * The atoms are sent back to the client in real time, as opposed to keeping the data in memory.
- * Shell clients do not subscribe aggregated metrics, as they are responsible for doing the
- * aggregation after receiving the atom events.
- *
- * Shell clients pass ShellSubscription in the proto binary format. Clients can update the
- * subscription by sending a new subscription. The new subscription would replace the old one.
- * Input data stream format is:
- *
- * |size_t|subscription proto|size_t|subscription proto|....
- *
- * statsd sends the events back in Atom proto binary format. Each Atom message is preceded
- * with sizeof(size_t) bytes indicating the size of the proto message payload.
- *
- * The stream would be in the following format:
- * |size_t|shellData proto|size_t|shellData proto|....
- *
- * Only one shell subscriber is allowed at a time because each shell subscriber blocks one thread
- * until it exits.
- */
-class ShellSubscriber : public virtual RefBase {
-public:
- ShellSubscriber(sp<UidMap> uidMap, sp<StatsPullerManager> pullerMgr)
- : mUidMap(uidMap), mPullerMgr(pullerMgr){};
-
- void startNewSubscription(int inFd, int outFd, int timeoutSec);
-
- void onLogEvent(const LogEvent& event);
-
-private:
- struct PullInfo {
- PullInfo(const SimpleAtomMatcher& matcher, int64_t interval,
- const std::vector<std::string>& packages, const std::vector<int32_t>& uids)
- : mPullerMatcher(matcher),
- mInterval(interval),
- mPrevPullElapsedRealtimeMs(0),
- mPullPackages(packages),
- mPullUids(uids) {
- }
- SimpleAtomMatcher mPullerMatcher;
- int64_t mInterval;
- int64_t mPrevPullElapsedRealtimeMs;
- std::vector<std::string> mPullPackages;
- std::vector<int32_t> mPullUids;
- };
-
- struct SubscriptionInfo {
- SubscriptionInfo(const int& inputFd, const int& outputFd)
- : mInputFd(inputFd), mOutputFd(outputFd), mClientAlive(true) {
- }
-
- int mInputFd;
- int mOutputFd;
- std::vector<SimpleAtomMatcher> mPushedMatchers;
- std::vector<PullInfo> mPulledInfo;
- bool mClientAlive;
- };
-
- int claimToken();
-
- bool readConfig(std::shared_ptr<SubscriptionInfo> subscriptionInfo);
-
- void spawnHelperThread(int myToken);
-
- void waitForSubscriptionToEndLocked(std::shared_ptr<SubscriptionInfo> myInfo,
- int myToken,
- std::unique_lock<std::mutex>& lock,
- int timeoutSec);
-
- // Helper thread that pulls atoms at a regular frequency and sends
- // heartbeats to perfd if statsd hasn't recently sent any data. Statsd must
- // send heartbeats for perfd to escape a blocking read call and recheck if
- // the user has terminated the subscription.
- void pullAndSendHeartbeats(int myToken);
-
- void writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
- const SimpleAtomMatcher& matcher);
-
- void getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo);
-
- void attemptWriteToPipeLocked(size_t dataSize);
-
- sp<UidMap> mUidMap;
-
- sp<StatsPullerManager> mPullerMgr;
-
- android::util::ProtoOutputStream mProto;
-
- mutable std::mutex mMutex;
-
- std::condition_variable mSubscriptionShouldEnd;
-
- std::shared_ptr<SubscriptionInfo> mSubscriptionInfo = nullptr;
-
- int mToken = 0;
-
- const int32_t DEFAULT_PULL_UID = AID_SYSTEM;
-
- // Tracks when we last send data to perfd. We need that time to determine
- // when next to send a heartbeat.
- int64_t mLastWriteMs = 0;
- const int64_t kMsBetweenHeartbeats = 1000;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/shell/shell_config.proto b/cmds/statsd/src/shell/shell_config.proto
deleted file mode 100644
index 07d0310ef2dd..000000000000
--- a/cmds/statsd/src/shell/shell_config.proto
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "ShellConfig";
-
-import "frameworks/base/cmds/statsd/src/statsd_config.proto";
-
-message PulledAtomSubscription {
- optional SimpleAtomMatcher matcher = 1;
-
- /* gap between two pulls in milliseconds */
- optional int32 freq_millis = 2;
-
- /* Packages that the pull is requested from */
- repeated string packages = 3;
-}
-
-message ShellSubscription {
- repeated SimpleAtomMatcher pushed = 1;
- repeated PulledAtomSubscription pulled = 2;
-} \ No newline at end of file
diff --git a/cmds/statsd/src/shell/shell_data.proto b/cmds/statsd/src/shell/shell_data.proto
deleted file mode 100644
index 236bdbdd31f6..000000000000
--- a/cmds/statsd/src/shell/shell_data.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os.statsd";
-option java_outer_classname = "ShellDataProto";
-
-import "frameworks/base/cmds/statsd/src/atoms.proto";
-
-// The output of shell subscription, including both pulled and pushed subscriptions.
-message ShellData {
- repeated Atom atom = 1;
-}
diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp
deleted file mode 100755
index b877cc9c352f..000000000000
--- a/cmds/statsd/src/socket/StatsSocketListener.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <sys/cdefs.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <cutils/sockets.h>
-
-#include "StatsSocketListener.h"
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsSocketListener::StatsSocketListener(std::shared_ptr<LogEventQueue> queue)
- : SocketListener(getLogSocket(), false /*start listen*/), mQueue(queue) {
-}
-
-StatsSocketListener::~StatsSocketListener() {
-}
-
-bool StatsSocketListener::onDataAvailable(SocketClient* cli) {
- static bool name_set;
- if (!name_set) {
- prctl(PR_SET_NAME, "statsd.writer");
- name_set = true;
- }
-
- // + 1 to ensure null terminator if MAX_PAYLOAD buffer is received
- char buffer[sizeof(android_log_header_t) + LOGGER_ENTRY_MAX_PAYLOAD + 1];
- struct iovec iov = {buffer, sizeof(buffer) - 1};
-
- alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
- struct msghdr hdr = {
- NULL, 0, &iov, 1, control, sizeof(control), 0,
- };
-
- int socket = cli->getSocket();
-
- // To clear the entire buffer is secure/safe, but this contributes to 1.68%
- // overhead under logging load. We are safe because we check counts, but
- // still need to clear null terminator
- // memset(buffer, 0, sizeof(buffer));
- ssize_t n = recvmsg(socket, &hdr, 0);
- if (n <= (ssize_t)(sizeof(android_log_header_t))) {
- return false;
- }
-
- buffer[n] = 0;
-
- struct ucred* cred = NULL;
-
- struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
- while (cmsg != NULL) {
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
- cred = (struct ucred*)CMSG_DATA(cmsg);
- break;
- }
- cmsg = CMSG_NXTHDR(&hdr, cmsg);
- }
-
- struct ucred fake_cred;
- if (cred == NULL) {
- cred = &fake_cred;
- cred->pid = 0;
- cred->uid = DEFAULT_OVERFLOWUID;
- }
-
- uint8_t* ptr = ((uint8_t*)buffer) + sizeof(android_log_header_t);
- n -= sizeof(android_log_header_t);
-
- // When a log failed to write to statsd socket (e.g., due ot EBUSY), a special message would
- // be sent to statsd when the socket communication becomes available again.
- // The format is android_log_event_int_t with a single integer in the payload indicating the
- // number of logs that failed. (*FORMAT MUST BE IN SYNC WITH system/core/libstats*)
- // Note that all normal stats logs are in the format of event_list, so there won't be confusion.
- //
- // TODO(b/80538532): In addition to log it in StatsdStats, we should properly reset the config.
- if (n == sizeof(android_log_event_long_t)) {
- android_log_event_long_t* long_event = reinterpret_cast<android_log_event_long_t*>(ptr);
- if (long_event->payload.type == EVENT_TYPE_LONG) {
- int64_t composed_long = long_event->payload.data;
-
- // format:
- // |last_tag|dropped_count|
- int32_t dropped_count = (int32_t)(0xffffffff & composed_long);
- int32_t last_atom_tag = (int32_t)((0xffffffff00000000 & (uint64_t)composed_long) >> 32);
-
- ALOGE("Found dropped events: %d error %d last atom tag %d from uid %d", dropped_count,
- long_event->header.tag, last_atom_tag, cred->uid);
- StatsdStats::getInstance().noteLogLost((int32_t)getWallClockSec(), dropped_count,
- long_event->header.tag, last_atom_tag, cred->uid,
- cred->pid);
- return true;
- }
- }
-
- // move past the 4-byte StatsEventTag
- uint8_t* msg = ptr + sizeof(uint32_t);
- uint32_t len = n - sizeof(uint32_t);
- uint32_t uid = cred->uid;
- uint32_t pid = cred->pid;
-
- int64_t oldestTimestamp;
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid, pid);
- logEvent->parseBuffer(msg, len);
-
- if (!mQueue->push(std::move(logEvent), &oldestTimestamp)) {
- StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp);
- }
-
- return true;
-}
-
-int StatsSocketListener::getLogSocket() {
- static const char socketName[] = "statsdw";
- int sock = android_get_control_socket(socketName);
-
- if (sock < 0) { // statsd started up in init.sh
- sock = socket_local_server(socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
-
- int on = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
- return -1;
- }
- }
- return sock;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h
deleted file mode 100644
index 2167a56445b9..000000000000
--- a/cmds/statsd/src/socket/StatsSocketListener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <sysutils/SocketListener.h>
-#include <utils/RefBase.h>
-#include "logd/LogEventQueue.h"
-
-// DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of
-// the uapi headers for userspace to use. This value is filled in on the
-// out-of-band socket credentials if the OS fails to find one available.
-// One of the causes of this is if SO_PASSCRED is set, all the packets before
-// that point will have this value. We also use it in a fake credential if
-// no socket credentials are supplied.
-#ifndef DEFAULT_OVERFLOWUID
-#define DEFAULT_OVERFLOWUID 65534
-#endif
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsSocketListener : public SocketListener, public virtual android::RefBase {
-public:
- explicit StatsSocketListener(std::shared_ptr<LogEventQueue> queue);
-
- virtual ~StatsSocketListener();
-
-protected:
- virtual bool onDataAvailable(SocketClient* cli);
-
-private:
- static int getLogSocket();
- /**
- * Who is going to get the events when they're read.
- */
- std::shared_ptr<LogEventQueue> mQueue;
-};
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateListener.h b/cmds/statsd/src/state/StateListener.h
deleted file mode 100644
index 63880017ca18..000000000000
--- a/cmds/statsd/src/state/StateListener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-
-#include "HashableDimensionKey.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StateListener : public virtual RefBase {
-public:
- StateListener(){};
-
- virtual ~StateListener(){};
-
- /**
- * Interface for handling a state change.
- *
- * The old and new state values map to the original state values.
- * StateTrackers only track the original state values and are unaware
- * of higher-level state groups. MetricProducers hold information on
- * state groups and are responsible for mapping original state values to
- * the correct state group.
- *
- * [eventTimeNs]: Time of the state change log event.
- * [atomId]: The id of the state atom
- * [primaryKey]: The primary field values of the state atom
- * [oldState]: Previous state value before state change
- * [newState]: Current state value after state change
- */
- virtual void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) = 0;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp
deleted file mode 100644
index c29afeb794fa..000000000000
--- a/cmds/statsd/src/state/StateManager.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StateManager.h"
-
-#include <private/android_filesystem_config.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StateManager::StateManager()
- : mAllowedPkg({
- "com.android.systemui",
- }) {
-}
-
-StateManager& StateManager::getInstance() {
- static StateManager sStateManager;
- return sStateManager;
-}
-
-void StateManager::clear() {
- mStateTrackers.clear();
-}
-
-void StateManager::onLogEvent(const LogEvent& event) {
- // Only process state events from uids in AID_* and packages that are whitelisted in
- // mAllowedPkg.
- // Whitelisted AIDs are AID_ROOT and all AIDs in [1000, 2000)
- if (event.GetUid() == AID_ROOT || (event.GetUid() >= 1000 && event.GetUid() < 2000) ||
- mAllowedLogSources.find(event.GetUid()) != mAllowedLogSources.end()) {
- if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) {
- mStateTrackers[event.GetTagId()]->onLogEvent(event);
- }
- }
-}
-
-void StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) {
- // Check if state tracker already exists.
- if (mStateTrackers.find(atomId) == mStateTrackers.end()) {
- mStateTrackers[atomId] = new StateTracker(atomId);
- }
- mStateTrackers[atomId]->registerListener(listener);
-}
-
-void StateManager::unregisterListener(const int32_t atomId, wp<StateListener> listener) {
- std::unique_lock<std::mutex> lock(mMutex);
-
- // Hold the sp<> until the lock is released so that ~StateTracker() is
- // not called while the lock is held.
- sp<StateTracker> toRemove;
-
- // Unregister listener from correct StateTracker
- auto it = mStateTrackers.find(atomId);
- if (it != mStateTrackers.end()) {
- it->second->unregisterListener(listener);
-
- // Remove the StateTracker if it has no listeners
- if (it->second->getListenersCount() == 0) {
- toRemove = it->second;
- mStateTrackers.erase(it);
- }
- } else {
- ALOGE("StateManager cannot unregister listener, StateTracker for atom %d does not exist",
- atomId);
- }
- lock.unlock();
-}
-
-bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKey& key,
- FieldValue* output) const {
- auto it = mStateTrackers.find(atomId);
- if (it != mStateTrackers.end()) {
- return it->second->getStateValue(key, output);
- }
- return false;
-}
-
-void StateManager::updateLogSources(const sp<UidMap>& uidMap) {
- mAllowedLogSources.clear();
- for (const auto& pkg : mAllowedPkg) {
- auto uids = uidMap->getAppUid(pkg);
- mAllowedLogSources.insert(uids.begin(), uids.end());
- }
-}
-
-void StateManager::notifyAppChanged(const string& apk, const sp<UidMap>& uidMap) {
- if (mAllowedPkg.find(apk) != mAllowedPkg.end()) {
- updateLogSources(uidMap);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h
deleted file mode 100644
index 18c404c29c4e..000000000000
--- a/cmds/statsd/src/state/StateManager.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <inttypes.h>
-#include <utils/RefBase.h>
-
-#include <set>
-#include <string>
-#include <unordered_map>
-
-#include "HashableDimensionKey.h"
-#include "packages/UidMap.h"
-#include "state/StateListener.h"
-#include "state/StateTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * This class is NOT thread safe.
- * It should only be used while StatsLogProcessor's lock is held.
- */
-class StateManager : public virtual RefBase {
-public:
- StateManager();
-
- ~StateManager(){};
-
- // Returns a pointer to the single, shared StateManager object.
- static StateManager& getInstance();
-
- // Unregisters all listeners and removes all trackers from StateManager.
- void clear();
-
- // Notifies the correct StateTracker of an event.
- void onLogEvent(const LogEvent& event);
-
- // Notifies the StateTracker for the given atomId to register listener.
- // If the correct StateTracker does not exist, a new StateTracker is created.
- // Note: StateTrackers can be created for non-state atoms. They are essentially empty and
- // do not perform any actions.
- void registerListener(const int32_t atomId, wp<StateListener> listener);
-
- // Notifies the correct StateTracker to unregister a listener
- // and removes the tracker if it no longer has any listeners.
- void unregisterListener(const int32_t atomId, wp<StateListener> listener);
-
- // Returns true if the StateTracker exists and queries for the
- // original state value mapped to the given query key. The state value is
- // stored and output in a FieldValue class.
- // Returns false if the StateTracker doesn't exist.
- bool getStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
- FieldValue* output) const;
-
- // Updates mAllowedLogSources with the latest uids for the packages that are allowed to log.
- void updateLogSources(const sp<UidMap>& uidMap);
-
- void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap);
-
- inline int getStateTrackersCount() const {
- return mStateTrackers.size();
- }
-
- inline int getListenersCount(const int32_t atomId) const {
- auto it = mStateTrackers.find(atomId);
- if (it != mStateTrackers.end()) {
- return it->second->getListenersCount();
- }
- return -1;
- }
-
-private:
- mutable std::mutex mMutex;
-
- // Maps state atom ids to StateTrackers
- std::unordered_map<int32_t, sp<StateTracker>> mStateTrackers;
-
- // The package names that can log state events.
- const std::set<std::string> mAllowedPkg;
-
- // The combined uid sources (after translating pkg name to uid).
- // State events from uids that are not in the list will be ignored to avoid state pollution.
- std::set<int32_t> mAllowedLogSources;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp
deleted file mode 100644
index 41e525c343ba..000000000000
--- a/cmds/statsd/src/state/StateTracker.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG true // STOPSHIP if true
-#include "Log.h"
-
-#include "stats_util.h"
-
-#include "StateTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StateTracker::StateTracker(const int32_t atomId) : mField(atomId, 0) {
-}
-
-void StateTracker::onLogEvent(const LogEvent& event) {
- const int64_t eventTimeNs = event.GetElapsedTimestampNs();
-
- // Parse event for primary field values i.e. primary key.
- HashableDimensionKey primaryKey;
- filterPrimaryKey(event.getValues(), &primaryKey);
-
- FieldValue newState;
- if (!getStateFieldValueFromLogEvent(event, &newState)) {
- ALOGE("StateTracker error extracting state from log event. Missing exclusive state field.");
- clearStateForPrimaryKey(eventTimeNs, primaryKey);
- return;
- }
-
- mField.setField(newState.mField.getField());
-
- if (newState.mValue.getType() != INT) {
- ALOGE("StateTracker error extracting state from log event. Type: %d",
- newState.mValue.getType());
- clearStateForPrimaryKey(eventTimeNs, primaryKey);
- return;
- }
-
- if (int resetState = event.getResetState(); resetState != -1) {
- VLOG("StateTracker new reset state: %d", resetState);
- const FieldValue resetStateFieldValue(mField, Value(resetState));
- handleReset(eventTimeNs, resetStateFieldValue);
- return;
- }
-
- const bool nested = newState.mAnnotations.isNested();
- StateValueInfo* stateValueInfo = &mStateMap[primaryKey];
- updateStateForPrimaryKey(eventTimeNs, primaryKey, newState, nested, stateValueInfo);
-}
-
-void StateTracker::registerListener(wp<StateListener> listener) {
- mListeners.insert(listener);
-}
-
-void StateTracker::unregisterListener(wp<StateListener> listener) {
- mListeners.erase(listener);
-}
-
-bool StateTracker::getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const {
- output->mField = mField;
-
- if (const auto it = mStateMap.find(queryKey); it != mStateMap.end()) {
- output->mValue = it->second.state;
- return true;
- }
-
- // Set the state value to kStateUnknown if query key is not found in state map.
- output->mValue = kStateUnknown;
- return false;
-}
-
-void StateTracker::handleReset(const int64_t eventTimeNs, const FieldValue& newState) {
- VLOG("StateTracker handle reset");
- for (auto& [primaryKey, stateValueInfo] : mStateMap) {
- updateStateForPrimaryKey(eventTimeNs, primaryKey, newState,
- false /* nested; treat this state change as not nested */,
- &stateValueInfo);
- }
-}
-
-void StateTracker::clearStateForPrimaryKey(const int64_t eventTimeNs,
- const HashableDimensionKey& primaryKey) {
- VLOG("StateTracker clear state for primary key");
- const std::unordered_map<HashableDimensionKey, StateValueInfo>::iterator it =
- mStateMap.find(primaryKey);
-
- // If there is no entry for the primaryKey in mStateMap, then the state is already
- // kStateUnknown.
- const FieldValue state(mField, Value(kStateUnknown));
- if (it != mStateMap.end()) {
- updateStateForPrimaryKey(eventTimeNs, primaryKey, state,
- false /* nested; treat this state change as not nested */,
- &it->second);
- }
-}
-
-void StateTracker::updateStateForPrimaryKey(const int64_t eventTimeNs,
- const HashableDimensionKey& primaryKey,
- const FieldValue& newState, const bool nested,
- StateValueInfo* stateValueInfo) {
- FieldValue oldState;
- oldState.mField = mField;
- oldState.mValue.setInt(stateValueInfo->state);
- const int32_t oldStateValue = stateValueInfo->state;
- const int32_t newStateValue = newState.mValue.int_value;
-
- if (kStateUnknown == newStateValue) {
- mStateMap.erase(primaryKey);
- }
-
- // Update state map for non-nested counting case.
- // Every state event triggers a state overwrite.
- if (!nested) {
- stateValueInfo->state = newStateValue;
- stateValueInfo->count = 1;
-
- // Notify listeners if state has changed.
- if (oldStateValue != newStateValue) {
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- }
- return;
- }
-
- // Update state map for nested counting case.
- //
- // Nested counting is only allowed for binary state events such as ON/OFF or
- // ACQUIRE/RELEASE. For example, WakelockStateChanged might have the state
- // events: ON, ON, OFF. The state will still be ON until we see the same
- // number of OFF events as ON events.
- //
- // In atoms.proto, a state atom with nested counting enabled
- // must only have 2 states. There is no enforcemnt here of this requirement.
- // The atom must be logged correctly.
- if (kStateUnknown == newStateValue) {
- if (kStateUnknown != oldStateValue) {
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- }
- } else if (oldStateValue == kStateUnknown) {
- stateValueInfo->state = newStateValue;
- stateValueInfo->count = 1;
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- } else if (oldStateValue == newStateValue) {
- stateValueInfo->count++;
- } else if (--stateValueInfo->count == 0) {
- stateValueInfo->state = newStateValue;
- stateValueInfo->count = 1;
- notifyListeners(eventTimeNs, primaryKey, oldState, newState);
- }
-}
-
-void StateTracker::notifyListeners(const int64_t eventTimeNs,
- const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState) {
- for (auto l : mListeners) {
- auto sl = l.promote();
- if (sl != nullptr) {
- sl->onStateChanged(eventTimeNs, mField.getTag(), primaryKey, oldState, newState);
- }
- }
-}
-
-bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output) {
- const int exclusiveStateFieldIndex = event.getExclusiveStateFieldIndex();
- if (-1 == exclusiveStateFieldIndex) {
- ALOGE("error extracting state from log event. Missing exclusive state field.");
- return false;
- }
-
- *output = event.getValues()[exclusiveStateFieldIndex];
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h
deleted file mode 100644
index abd579e7e302..000000000000
--- a/cmds/statsd/src/state/StateTracker.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-#include "HashableDimensionKey.h"
-#include "logd/LogEvent.h"
-
-#include "state/StateListener.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StateTracker : public virtual RefBase {
-public:
- StateTracker(const int32_t atomId);
-
- virtual ~StateTracker(){};
-
- // Updates state map and notifies all listeners if a state change occurs.
- // Checks if a state change has occurred by getting the state value from
- // the log event and comparing the old and new states.
- void onLogEvent(const LogEvent& event);
-
- // Adds new listeners to set of StateListeners. If a listener is already
- // registered, it is ignored.
- void registerListener(wp<StateListener> listener);
-
- void unregisterListener(wp<StateListener> listener);
-
- // The output is a FieldValue object that has mStateField as the field and
- // the original state value (found using the given query key) as the value.
- //
- // If the key isn't mapped to a state or the key size doesn't match the
- // number of primary fields, the output value is set to kStateUnknown.
- bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const;
-
- inline int getListenersCount() const {
- return mListeners.size();
- }
-
- const static int kStateUnknown = -1;
-
-private:
- struct StateValueInfo {
- int32_t state = kStateUnknown; // state value
- int count = 0; // nested count (only used for binary states)
- };
-
- Field mField;
-
- // Maps primary key to state value info
- std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap;
-
- // Set of all StateListeners (objects listening for state changes)
- std::set<wp<StateListener>> mListeners;
-
- // Reset all state values in map to the given state.
- void handleReset(const int64_t eventTimeNs, const FieldValue& newState);
-
- // Clears the state value mapped to the given primary key by setting it to kStateUnknown.
- void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey);
-
- // Update the StateMap based on the received state value.
- void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
- const FieldValue& newState, const bool nested,
- StateValueInfo* stateValueInfo);
-
- // Notify registered state listeners of state change.
- void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
- const FieldValue& oldState, const FieldValue& newState);
-};
-
-bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
deleted file mode 100644
index ddd2725c9cb9..000000000000
--- a/cmds/statsd/src/stats_log.proto
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "StatsLog";
-
-import "frameworks/base/cmds/statsd/src/atoms.proto";
-
-message DimensionsValue {
- optional int32 field = 1;
-
- oneof value {
- string value_str = 2;
- int32 value_int = 3;
- int64 value_long = 4;
- bool value_bool = 5;
- float value_float = 6;
- DimensionsValueTuple value_tuple = 7;
- uint64 value_str_hash = 8;
- }
-}
-
-message DimensionsValueTuple {
- repeated DimensionsValue dimensions_value = 1;
-}
-
-message StateValue {
- optional int32 atom_id = 1;
-
- oneof contents {
- int64 group_id = 2;
- int32 value = 3;
- }
-}
-
-message EventMetricData {
- optional int64 elapsed_timestamp_nanos = 1;
-
- optional Atom atom = 2;
-
- optional int64 wall_clock_timestamp_nanos = 3 [deprecated = true];
-}
-
-message CountBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 count = 3;
-
- optional int64 bucket_num = 4;
-
- optional int64 start_bucket_elapsed_millis = 5;
-
- optional int64 end_bucket_elapsed_millis = 6;
-}
-
-message CountMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- repeated StateValue slice_by_state = 6;
-
- repeated CountBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message DurationBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 duration_nanos = 3;
-
- optional int64 bucket_num = 4;
-
- optional int64 start_bucket_elapsed_millis = 5;
-
- optional int64 end_bucket_elapsed_millis = 6;
-}
-
-message DurationMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- repeated StateValue slice_by_state = 6;
-
- repeated DurationBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message ValueBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 value = 3 [deprecated = true];
-
- oneof single_value {
- int64 value_long = 7 [deprecated = true];
-
- double value_double = 8 [deprecated = true];
- }
-
- message Value {
- optional int32 index = 1;
- oneof value {
- int64 value_long = 2;
- double value_double = 3;
- }
- }
-
- repeated Value values = 9;
-
- optional int64 bucket_num = 4;
-
- optional int64 start_bucket_elapsed_millis = 5;
-
- optional int64 end_bucket_elapsed_millis = 6;
-
- optional int64 condition_true_nanos = 10;
-}
-
-message ValueMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- repeated StateValue slice_by_state = 6;
-
- repeated ValueBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message GaugeBucketInfo {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- repeated Atom atom = 3;
-
- repeated int64 elapsed_timestamp_nanos = 4;
-
- repeated int64 wall_clock_timestamp_nanos = 5 [deprecated = true];
-
- optional int64 bucket_num = 6;
-
- optional int64 start_bucket_elapsed_millis = 7;
-
- optional int64 end_bucket_elapsed_millis = 8;
-}
-
-message GaugeMetricData {
- optional DimensionsValue dimensions_in_what = 1;
-
- // Currently unsupported
- repeated StateValue slice_by_state = 6;
-
- repeated GaugeBucketInfo bucket_info = 3;
-
- repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
- optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
- repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message StatsLogReport {
- optional int64 metric_id = 1;
-
- // Fields 2 and 3 are reserved.
-
- // Keep this in sync with BucketDropReason enum in MetricProducer.h.
- enum BucketDropReason {
- // For ValueMetric, a bucket is dropped during a dump report request iff
- // current bucket should be included, a pull is needed (pulled metric and
- // condition is true), and we are under fast time constraints.
- DUMP_REPORT_REQUESTED = 1;
- EVENT_IN_WRONG_BUCKET = 2;
- CONDITION_UNKNOWN = 3;
- PULL_FAILED = 4;
- PULL_DELAYED = 5;
- DIMENSION_GUARDRAIL_REACHED = 6;
- MULTIPLE_BUCKETS_SKIPPED = 7;
- // Not an invalid bucket case, but the bucket is dropped.
- BUCKET_TOO_SMALL = 8;
- // Not an invalid bucket case, but the bucket is skipped.
- NO_DATA = 9;
- };
-
- message DropEvent {
- optional BucketDropReason drop_reason = 1;
-
- optional int64 drop_time_millis = 2;
- }
-
- message SkippedBuckets {
- optional int64 start_bucket_elapsed_nanos = 1;
-
- optional int64 end_bucket_elapsed_nanos = 2;
-
- optional int64 start_bucket_elapsed_millis = 3;
-
- optional int64 end_bucket_elapsed_millis = 4;
-
- // The number of drop events is capped by StatsdStats::kMaxLoggedBucketDropEvents.
- // The current maximum is 10 drop events.
- repeated DropEvent drop_event = 5;
- }
-
- message EventMetricDataWrapper {
- repeated EventMetricData data = 1;
- }
- message CountMetricDataWrapper {
- repeated CountMetricData data = 1;
- }
- message DurationMetricDataWrapper {
- repeated DurationMetricData data = 1;
- }
- message ValueMetricDataWrapper {
- repeated ValueMetricData data = 1;
- repeated SkippedBuckets skipped = 2;
- }
-
- message GaugeMetricDataWrapper {
- repeated GaugeMetricData data = 1;
- repeated SkippedBuckets skipped = 2;
- }
-
- oneof data {
- EventMetricDataWrapper event_metrics = 4;
- CountMetricDataWrapper count_metrics = 5;
- DurationMetricDataWrapper duration_metrics = 6;
- ValueMetricDataWrapper value_metrics = 7;
- GaugeMetricDataWrapper gauge_metrics = 8;
- }
-
- optional int64 time_base_elapsed_nano_seconds = 9;
-
- optional int64 bucket_size_nano_seconds = 10;
-
- optional DimensionsValue dimensions_path_in_what = 11;
-
- optional DimensionsValue dimensions_path_in_condition = 12 [deprecated = true];
-
- // DO NOT USE field 13.
-
- optional bool is_active = 14;
-}
-
-message UidMapping {
- message PackageInfoSnapshot {
- message PackageInfo {
- optional string name = 1;
-
- optional int64 version = 2;
-
- optional int32 uid = 3;
-
- optional bool deleted = 4;
-
- optional uint64 name_hash = 5;
-
- optional string version_string = 6;
-
- optional uint64 version_string_hash = 7;
-
- optional string installer = 8;
-
- optional uint64 installer_hash = 9;
- }
- optional int64 elapsed_timestamp_nanos = 1;
-
- repeated PackageInfo package_info = 2;
- }
- repeated PackageInfoSnapshot snapshots = 1;
-
- message Change {
- optional bool deletion = 1;
-
- optional int64 elapsed_timestamp_nanos = 2;
- optional string app = 3;
- optional int32 uid = 4;
-
- optional int64 new_version = 5;
- optional int64 prev_version = 6;
- optional uint64 app_hash = 7;
- optional string new_version_string = 8;
- optional string prev_version_string = 9;
- optional uint64 new_version_string_hash = 10;
- optional uint64 prev_version_string_hash = 11;
- }
- repeated Change changes = 2;
-}
-
-message ConfigMetricsReport {
- repeated StatsLogReport metrics = 1;
-
- optional UidMapping uid_map = 2;
-
- optional int64 last_report_elapsed_nanos = 3;
-
- optional int64 current_report_elapsed_nanos = 4;
-
- optional int64 last_report_wall_clock_nanos = 5;
-
- optional int64 current_report_wall_clock_nanos = 6;
-
- message Annotation {
- optional int64 field_int64 = 1;
- optional int32 field_int32 = 2;
- }
- repeated Annotation annotation = 7;
-
- enum DumpReportReason {
- DEVICE_SHUTDOWN = 1;
- CONFIG_UPDATED = 2;
- CONFIG_REMOVED = 3;
- GET_DATA_CALLED = 4;
- ADB_DUMP = 5;
- CONFIG_RESET = 6;
- STATSCOMPANION_DIED = 7;
- TERMINATION_SIGNAL_RECEIVED = 8;
- }
- optional DumpReportReason dump_report_reason = 8;
-
- repeated string strings = 9;
-}
-
-message ConfigMetricsReportList {
- message ConfigKey {
- optional int32 uid = 1;
- optional int64 id = 2;
- }
- optional ConfigKey config_key = 1;
-
- repeated ConfigMetricsReport reports = 2;
-
- reserved 10;
-}
-
-message StatsdStatsReport {
- optional int32 stats_begin_time_sec = 1;
-
- optional int32 stats_end_time_sec = 2;
-
- message MatcherStats {
- optional int64 id = 1;
- optional int32 matched_times = 2;
- }
-
- message ConditionStats {
- optional int64 id = 1;
- optional int32 max_tuple_counts = 2;
- }
-
- message MetricStats {
- optional int64 id = 1;
- optional int32 max_tuple_counts = 2;
- }
-
- message AlertStats {
- optional int64 id = 1;
- optional int32 alerted_times = 2;
- }
-
- message ConfigStats {
- optional int32 uid = 1;
- optional int64 id = 2;
- optional int32 creation_time_sec = 3;
- optional int32 deletion_time_sec = 4;
- optional int32 reset_time_sec = 19;
- optional int32 metric_count = 5;
- optional int32 condition_count = 6;
- optional int32 matcher_count = 7;
- optional int32 alert_count = 8;
- optional bool is_valid = 9;
- repeated int32 broadcast_sent_time_sec = 10;
- repeated int32 data_drop_time_sec = 11;
- repeated int64 data_drop_bytes = 21;
- repeated int32 dump_report_time_sec = 12;
- repeated int32 dump_report_data_size = 20;
- repeated MatcherStats matcher_stats = 13;
- repeated ConditionStats condition_stats = 14;
- repeated MetricStats metric_stats = 15;
- repeated AlertStats alert_stats = 16;
- repeated MetricStats metric_dimension_in_condition_stats = 17 [deprecated = true];
- message Annotation {
- optional int64 field_int64 = 1;
- optional int32 field_int32 = 2;
- }
- repeated Annotation annotation = 18;
- repeated int32 activation_time_sec = 22;
- repeated int32 deactivation_time_sec = 23;
- }
-
- repeated ConfigStats config_stats = 3;
-
- message AtomStats {
- optional int32 tag = 1;
- optional int32 count = 2;
- optional int32 error_count = 3;
- }
-
- repeated AtomStats atom_stats = 7;
-
- message UidMapStats {
- optional int32 changes = 1;
- optional int32 bytes_used = 2;
- optional int32 dropped_changes = 3;
- optional int32 deleted_apps = 4;
- }
- optional UidMapStats uidmap_stats = 8;
-
- message AnomalyAlarmStats {
- optional int32 alarms_registered = 1;
- }
- optional AnomalyAlarmStats anomaly_alarm_stats = 9;
-
- message PulledAtomStats {
- optional int32 atom_id = 1;
- optional int64 total_pull = 2;
- optional int64 total_pull_from_cache = 3;
- optional int64 min_pull_interval_sec = 4;
- optional int64 average_pull_time_nanos = 5;
- optional int64 max_pull_time_nanos = 6;
- optional int64 average_pull_delay_nanos = 7;
- optional int64 max_pull_delay_nanos = 8;
- optional int64 data_error = 9;
- optional int64 pull_timeout = 10;
- optional int64 pull_exceed_max_delay = 11;
- optional int64 pull_failed = 12;
- optional int64 stats_companion_pull_failed = 13 [deprecated = true];
- optional int64 stats_companion_pull_binder_transaction_failed = 14 [deprecated = true];
- optional int64 empty_data = 15;
- optional int64 registered_count = 16;
- optional int64 unregistered_count = 17;
- optional int32 atom_error_count = 18;
- optional int64 binder_call_failed = 19;
- optional int64 failed_uid_provider_not_found = 20;
- optional int64 puller_not_found = 21;
- message PullTimeoutMetadata {
- optional int64 pull_timeout_uptime_millis = 1;
- optional int64 pull_timeout_elapsed_millis = 2;
- }
- repeated PullTimeoutMetadata pull_atom_metadata = 22;
- }
- repeated PulledAtomStats pulled_atom_stats = 10;
-
- message AtomMetricStats {
- optional int64 metric_id = 1;
- optional int64 hard_dimension_limit_reached = 2;
- optional int64 late_log_event_skipped = 3;
- optional int64 skipped_forward_buckets = 4;
- optional int64 bad_value_type = 5;
- optional int64 condition_change_in_next_bucket = 6;
- optional int64 invalidated_bucket = 7;
- optional int64 bucket_dropped = 8;
- optional int64 min_bucket_boundary_delay_ns = 9;
- optional int64 max_bucket_boundary_delay_ns = 10;
- optional int64 bucket_unknown_condition = 11;
- optional int64 bucket_count = 12;
- }
- repeated AtomMetricStats atom_metric_stats = 17;
-
- message LoggerErrorStats {
- optional int32 logger_disconnection_sec = 1;
- optional int32 error_code = 2;
- }
- repeated LoggerErrorStats logger_error_stats = 11;
-
- message PeriodicAlarmStats {
- optional int32 alarms_registered = 1;
- }
- optional PeriodicAlarmStats periodic_alarm_stats = 12;
-
- message SkippedLogEventStats {
- optional int32 tag = 1;
- optional int64 elapsed_timestamp_nanos = 2;
- }
- repeated SkippedLogEventStats skipped_log_event_stats = 13;
-
- repeated int64 log_loss_stats = 14;
-
- repeated int32 system_restart_sec = 15;
-
- message LogLossStats {
- optional int32 detected_time_sec = 1;
- optional int32 count = 2;
- optional int32 last_error = 3;
- optional int32 last_tag = 4;
- optional int32 uid = 5;
- optional int32 pid = 6;
- }
- repeated LogLossStats detected_log_loss = 16;
-
- message EventQueueOverflow {
- optional int32 count = 1;
- optional int64 max_queue_history_ns = 2;
- optional int64 min_queue_history_ns = 3;
- }
-
- optional EventQueueOverflow queue_overflow = 18;
-
- message ActivationBroadcastGuardrail {
- optional int32 uid = 1;
- repeated int32 guardrail_met_sec = 2;
- }
-
- repeated ActivationBroadcastGuardrail activation_guardrail_stats = 19;
-}
-
-message AlertTriggerDetails {
- message MetricValue {
- optional int64 metric_id = 1;
- optional DimensionsValue dimension_in_what = 2;
- optional DimensionsValue dimension_in_condition = 3 [deprecated = true];
- optional int64 value = 4;
- }
- oneof value {
- MetricValue trigger_metric = 1;
- EventMetricData trigger_event = 2;
- }
- optional UidMapping.PackageInfoSnapshot package_info = 3;
-}
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
deleted file mode 100644
index 423bae8bc0a4..000000000000
--- a/cmds/statsd/src/stats_log_util.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "hash.h"
-#include "stats_log_util.h"
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <private/android_filesystem_config.h>
-#include <set>
-#include <utils/SystemClock.h>
-
-#include "statscompanion_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FIXED64;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::ProtoOutputStream;
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-using std::string;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for DimensionsValue Proto
-const int DIMENSIONS_VALUE_FIELD = 1;
-const int DIMENSIONS_VALUE_VALUE_STR = 2;
-const int DIMENSIONS_VALUE_VALUE_INT = 3;
-const int DIMENSIONS_VALUE_VALUE_LONG = 4;
-// const int DIMENSIONS_VALUE_VALUE_BOOL = 5; // logd doesn't have bool data type.
-const int DIMENSIONS_VALUE_VALUE_FLOAT = 6;
-const int DIMENSIONS_VALUE_VALUE_TUPLE = 7;
-const int DIMENSIONS_VALUE_VALUE_STR_HASH = 8;
-
-const int DIMENSIONS_VALUE_TUPLE_VALUE = 1;
-
-// for StateValue Proto
-const int STATE_VALUE_ATOM_ID = 1;
-const int STATE_VALUE_CONTENTS_GROUP_ID = 2;
-const int STATE_VALUE_CONTENTS_VALUE = 3;
-
-// for PulledAtomStats proto
-const int FIELD_ID_PULLED_ATOM_STATS = 10;
-const int FIELD_ID_PULL_ATOM_ID = 1;
-const int FIELD_ID_TOTAL_PULL = 2;
-const int FIELD_ID_TOTAL_PULL_FROM_CACHE = 3;
-const int FIELD_ID_MIN_PULL_INTERVAL_SEC = 4;
-const int FIELD_ID_AVERAGE_PULL_TIME_NANOS = 5;
-const int FIELD_ID_MAX_PULL_TIME_NANOS = 6;
-const int FIELD_ID_AVERAGE_PULL_DELAY_NANOS = 7;
-const int FIELD_ID_MAX_PULL_DELAY_NANOS = 8;
-const int FIELD_ID_DATA_ERROR = 9;
-const int FIELD_ID_PULL_TIMEOUT = 10;
-const int FIELD_ID_PULL_EXCEED_MAX_DELAY = 11;
-const int FIELD_ID_PULL_FAILED = 12;
-const int FIELD_ID_EMPTY_DATA = 15;
-const int FIELD_ID_PULL_REGISTERED_COUNT = 16;
-const int FIELD_ID_PULL_UNREGISTERED_COUNT = 17;
-const int FIELD_ID_ATOM_ERROR_COUNT = 18;
-const int FIELD_ID_BINDER_CALL_FAIL_COUNT = 19;
-const int FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND = 20;
-const int FIELD_ID_PULLER_NOT_FOUND = 21;
-const int FIELD_ID_PULL_TIMEOUT_METADATA = 22;
-const int FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS = 1;
-const int FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS = 2;
-
-// for AtomMetricStats proto
-const int FIELD_ID_ATOM_METRIC_STATS = 17;
-const int FIELD_ID_METRIC_ID = 1;
-const int FIELD_ID_HARD_DIMENSION_LIMIT_REACHED = 2;
-const int FIELD_ID_LATE_LOG_EVENT_SKIPPED = 3;
-const int FIELD_ID_SKIPPED_FORWARD_BUCKETS = 4;
-const int FIELD_ID_BAD_VALUE_TYPE = 5;
-const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
-const int FIELD_ID_INVALIDATED_BUCKET = 7;
-const int FIELD_ID_BUCKET_DROPPED = 8;
-const int FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS = 9;
-const int FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS = 10;
-const int FIELD_ID_BUCKET_UNKNOWN_CONDITION = 11;
-const int FIELD_ID_BUCKET_COUNT = 12;
-
-namespace {
-
-void writeDimensionToProtoHelper(const std::vector<FieldValue>& dims, size_t* index, int depth,
- int prefix, std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- const int fieldNum = dim.mField.getPosAtDepth(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- switch (dim.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
- dim.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
- (long long)dim.mValue.long_value);
- break;
- case FLOAT:
- protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
- dim.mValue.float_value);
- break;
- case STRING:
- if (str_set == nullptr) {
- protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
- dim.mValue.str_value);
- } else {
- str_set->insert(dim.mValue.str_value);
- protoOutput->write(
- FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
- (long long)Hash64(dim.mValue.str_value));
- }
- break;
- default:
- break;
- }
- if (token != 0) {
- protoOutput->end(token);
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- // Writing the sub tree
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- uint64_t tupleToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- writeDimensionToProtoHelper(dims, index, valueDepth, dim.mField.getPrefix(valueDepth),
- str_set, protoOutput);
- protoOutput->end(tupleToken);
- protoOutput->end(dimensionToken);
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-void writeDimensionLeafToProtoHelper(const std::vector<FieldValue>& dims,
- const int dimensionLeafField,
- size_t* index, int depth,
- int prefix, std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- dimensionLeafField);
- switch (dim.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
- dim.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
- (long long)dim.mValue.long_value);
- break;
- case FLOAT:
- protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
- dim.mValue.float_value);
- break;
- case STRING:
- if (str_set == nullptr) {
- protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
- dim.mValue.str_value);
- } else {
- str_set->insert(dim.mValue.str_value);
- protoOutput->write(
- FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
- (long long)Hash64(dim.mValue.str_value));
- }
- break;
- default:
- break;
- }
- if (token != 0) {
- protoOutput->end(token);
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- writeDimensionLeafToProtoHelper(dims, dimensionLeafField,
- index, valueDepth, dim.mField.getPrefix(valueDepth),
- str_set, protoOutput);
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-void writeDimensionPathToProtoHelper(const std::vector<Matcher>& fieldMatchers,
- size_t* index, int depth, int prefix,
- ProtoOutputStream* protoOutput) {
- size_t count = fieldMatchers.size();
- while (*index < count) {
- const Field& field = fieldMatchers[*index].mMatcher;
- const int valueDepth = field.getDepth();
- const int valuePrefix = field.getPrefix(depth);
- const int fieldNum = field.getPosAtDepth(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- if (token != 0) {
- protoOutput->end(token);
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- // Writing the sub tree
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
- uint64_t tupleToken =
- protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- writeDimensionPathToProtoHelper(fieldMatchers, index, valueDepth,
- field.getPrefix(valueDepth), protoOutput);
- protoOutput->end(tupleToken);
- protoOutput->end(dimensionToken);
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-} // namespace
-
-void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (dimension.getValues().size() == 0) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
- dimension.getValues()[0].mField.getTag());
- uint64_t topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- size_t index = 0;
- writeDimensionToProtoHelper(dimension.getValues(), &index, 0, 0, str_set, protoOutput);
- protoOutput->end(topToken);
-}
-
-void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
- const int dimensionLeafFieldId,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput) {
- if (dimension.getValues().size() == 0) {
- return;
- }
- size_t index = 0;
- writeDimensionLeafToProtoHelper(dimension.getValues(), dimensionLeafFieldId,
- &index, 0, 0, str_set, protoOutput);
-}
-
-void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
- ProtoOutputStream* protoOutput) {
- if (fieldMatchers.size() == 0) {
- return;
- }
- protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
- fieldMatchers[0].mMatcher.getTag());
- uint64_t topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
- size_t index = 0;
- writeDimensionPathToProtoHelper(fieldMatchers, &index, 0, 0, protoOutput);
- protoOutput->end(topToken);
-}
-
-// Supported Atoms format
-// XYZ_Atom {
-// repeated SubMsg field_1 = 1;
-// SubMsg2 field_2 = 2;
-// int32/float/string/int63 field_3 = 3;
-// }
-// logd's msg format, doesn't allow us to distinguish between the 2 cases below
-// Case (1):
-// Atom {
-// SubMsg {
-// int i = 1;
-// int j = 2;
-// }
-// repeated SubMsg
-// }
-//
-// and case (2):
-// Atom {
-// SubMsg {
-// repeated int i = 1;
-// repeated int j = 2;
-// }
-// optional SubMsg = 1;
-// }
-//
-//
-void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims,
- size_t* index, int depth, int prefix,
- ProtoOutputStream* protoOutput) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- const int fieldNum = dim.mField.getPosAtDepth(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
-
- if (depth == valueDepth && valuePrefix == prefix) {
- switch (dim.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | fieldNum, dim.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | fieldNum,
- (long long)dim.mValue.long_value);
- break;
- case FLOAT:
- protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
- break;
- case STRING: {
- protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
- break;
- }
- case STORAGE:
- protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
- (const char*)dim.mValue.storage_value.data(),
- dim.mValue.storage_value.size());
- break;
- default:
- break;
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- // Writing the sub tree
- uint64_t msg_token = 0ULL;
- if (valueDepth == depth + 2) {
- msg_token =
- protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
- } else if (valueDepth == depth + 1) {
- msg_token = protoOutput->start(FIELD_TYPE_MESSAGE | fieldNum);
- }
- // Directly jump to the leaf value because the repeated position field is implied
- // by the position of the sub msg in the parent field.
- writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
- dim.mField.getPrefix(valueDepth), protoOutput);
- if (msg_token != 0) {
- protoOutput->end(msg_token);
- }
- } else {
- // Done with the prev sub tree
- return;
- }
- }
-}
-
-void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
- util::ProtoOutputStream* protoOutput) {
- uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
-
- size_t index = 0;
- writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput);
- protoOutput->end(atomToken);
-}
-
-void writeStateToProto(const FieldValue& state, util::ProtoOutputStream* protoOutput) {
- protoOutput->write(FIELD_TYPE_INT32 | STATE_VALUE_ATOM_ID, state.mField.getTag());
-
- switch (state.mValue.getType()) {
- case INT:
- protoOutput->write(FIELD_TYPE_INT32 | STATE_VALUE_CONTENTS_VALUE,
- state.mValue.int_value);
- break;
- case LONG:
- protoOutput->write(FIELD_TYPE_INT64 | STATE_VALUE_CONTENTS_GROUP_ID,
- state.mValue.long_value);
- break;
- default:
- break;
- }
-}
-
-int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit) {
- int64_t bucketSizeMillis = TimeUnitToBucketSizeInMillis(unit);
- if (bucketSizeMillis > 1000 && bucketSizeMillis < 5 * 60 * 1000LL && uid != AID_SHELL &&
- uid != AID_ROOT) {
- bucketSizeMillis = 5 * 60 * 1000LL;
- }
- return bucketSizeMillis;
-}
-
-int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit) {
- switch (unit) {
- case ONE_MINUTE:
- return 60 * 1000LL;
- case FIVE_MINUTES:
- return 5 * 60 * 1000LL;
- case TEN_MINUTES:
- return 10 * 60 * 1000LL;
- case THIRTY_MINUTES:
- return 30 * 60 * 1000LL;
- case ONE_HOUR:
- return 60 * 60 * 1000LL;
- case THREE_HOURS:
- return 3 * 60 * 60 * 1000LL;
- case SIX_HOURS:
- return 6 * 60 * 60 * 1000LL;
- case TWELVE_HOURS:
- return 12 * 60 * 60 * 1000LL;
- case ONE_DAY:
- return 24 * 60 * 60 * 1000LL;
- case ONE_WEEK:
- return 7 * 24 * 60 * 60 * 1000LL;
- case CTS:
- return 1000;
- case TIME_UNIT_UNSPECIFIED:
- default:
- return -1;
- }
-}
-
-void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
- util::ProtoOutputStream* protoOutput) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_PULLED_ATOM_STATS |
- FIELD_COUNT_REPEATED);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_PULL_ATOM_ID, (int32_t)pair.first);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TOTAL_PULL, (long long)pair.second.totalPull);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TOTAL_PULL_FROM_CACHE,
- (long long)pair.second.totalPullFromCache);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_PULL_INTERVAL_SEC,
- (long long)pair.second.minPullIntervalSec);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_AVERAGE_PULL_TIME_NANOS,
- (long long)pair.second.avgPullTimeNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_TIME_NANOS,
- (long long)pair.second.maxPullTimeNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_AVERAGE_PULL_DELAY_NANOS,
- (long long)pair.second.avgPullDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_DELAY_NANOS,
- (long long)pair.second.maxPullDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DATA_ERROR, (long long)pair.second.dataError);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT,
- (long long)pair.second.pullTimeout);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_EXCEED_MAX_DELAY,
- (long long)pair.second.pullExceedMaxDelay);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_FAILED,
- (long long)pair.second.pullFailed);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
- (long long)pair.second.emptyData);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_REGISTERED_COUNT,
- (long long) pair.second.registeredCount);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UNREGISTERED_COUNT,
- (long long) pair.second.unregisteredCount);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ERROR_COUNT, pair.second.atomErrorCount);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BINDER_CALL_FAIL_COUNT,
- (long long)pair.second.binderCallFailCount);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND,
- (long long)pair.second.pullUidProviderNotFound);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULLER_NOT_FOUND,
- (long long)pair.second.pullerNotFound);
- for (const auto& pullTimeoutMetadata : pair.second.pullTimeoutMetadata) {
- uint64_t timeoutMetadataToken = protoOutput->start(FIELD_TYPE_MESSAGE |
- FIELD_ID_PULL_TIMEOUT_METADATA |
- FIELD_COUNT_REPEATED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS,
- pullTimeoutMetadata.pullTimeoutUptimeMillis);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS,
- pullTimeoutMetadata.pullTimeoutElapsedMillis);
- protoOutput->end(timeoutMetadataToken);
- }
- protoOutput->end(token);
-}
-
-void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
- util::ProtoOutputStream *protoOutput) {
- uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_METRIC_STATS |
- FIELD_COUNT_REPEATED);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_ID, (long long)pair.first);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_HARD_DIMENSION_LIMIT_REACHED,
- (long long)pair.second.hardDimensionLimitReached);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_LATE_LOG_EVENT_SKIPPED,
- (long long)pair.second.lateLogEventSkipped);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_FORWARD_BUCKETS,
- (long long)pair.second.skippedForwardBuckets);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BAD_VALUE_TYPE,
- (long long)pair.second.badValueType);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET,
- (long long)pair.second.conditionChangeInNextBucket);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_INVALIDATED_BUCKET,
- (long long)pair.second.invalidatedBucket);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
- (long long)pair.second.bucketDropped);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS,
- (long long)pair.second.minBucketBoundaryDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS,
- (long long)pair.second.maxBucketBoundaryDelayNs);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_UNKNOWN_CONDITION,
- (long long)pair.second.bucketUnknownCondition);
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_COUNT,
- (long long)pair.second.bucketCount);
- protoOutput->end(token);
-}
-
-int64_t getElapsedRealtimeNs() {
- return ::android::elapsedRealtimeNano();
-}
-
-int64_t getElapsedRealtimeSec() {
- return ::android::elapsedRealtimeNano() / NS_PER_SEC;
-}
-
-int64_t getElapsedRealtimeMillis() {
- return ::android::elapsedRealtime();
-}
-
-int64_t getSystemUptimeMillis() {
- return ::android::uptimeMillis();
-}
-
-int64_t getWallClockNs() {
- return time(nullptr) * NS_PER_SEC;
-}
-
-int64_t getWallClockSec() {
- return time(nullptr);
-}
-
-int64_t getWallClockMillis() {
- return time(nullptr) * MS_PER_SEC;
-}
-
-int64_t truncateTimestampIfNecessary(const LogEvent& event) {
- if (event.shouldTruncateTimestamp() ||
- (event.GetTagId() >= StatsdStats::kTimestampTruncationStartTag &&
- event.GetTagId() <= StatsdStats::kTimestampTruncationEndTag)) {
- return event.GetElapsedTimestampNs() / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
- } else {
- return event.GetElapsedTimestampNs();
- }
-}
-
-int64_t NanoToMillis(const int64_t nano) {
- return nano / 1000000;
-}
-
-int64_t MillisToNano(const int64_t millis) {
- return millis * 1000000;
-}
-
-bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid) {
- shared_ptr<IStatsCompanionService> scs = getStatsCompanionService();
- if (scs == nullptr) {
- return false;
- }
-
- bool success;
- ::ndk::ScopedAStatus status = scs->checkPermission(string(permission), pid, uid, &success);
- if (!status.isOk()) {
- return false;
- }
-
- return success;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
deleted file mode 100644
index eb65dc6979c5..000000000000
--- a/cmds/statsd/src/stats_log_util.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/util/ProtoOutputStream.h>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
- ProtoOutputStream* protoOutput);
-void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
- ProtoOutputStream* protoOutput);
-
-void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
- const int dimensionLeafFieldId,
- std::set<string> *str_set,
- ProtoOutputStream* protoOutput);
-
-void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
- ProtoOutputStream* protoOutput);
-
-void writeStateToProto(const FieldValue& state, ProtoOutputStream* protoOutput);
-
-// Convert the TimeUnit enum to the bucket size in millis with a guardrail on
-// bucket size.
-int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit);
-
-// Convert the TimeUnit enum to the bucket size in millis.
-int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit);
-
-// Gets the elapsed timestamp in ns.
-int64_t getElapsedRealtimeNs();
-
-// Gets the elapsed timestamp in millis.
-int64_t getElapsedRealtimeMillis();
-
-// Gets the elapsed timestamp in seconds.
-int64_t getElapsedRealtimeSec();
-
-// Gets the system uptime in millis.
-int64_t getSystemUptimeMillis();
-
-// Gets the wall clock timestamp in ns.
-int64_t getWallClockNs();
-
-// Gets the wall clock timestamp in millis.
-int64_t getWallClockMillis();
-
-// Gets the wall clock timestamp in seconds.
-int64_t getWallClockSec();
-
-int64_t NanoToMillis(const int64_t nano);
-
-int64_t MillisToNano(const int64_t millis);
-
-// Helper function to write PulledAtomStats to ProtoOutputStream
-void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
- ProtoOutputStream* protoOutput);
-
-// Helper function to write AtomMetricStats to ProtoOutputStream
-void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
- ProtoOutputStream *protoOutput);
-
-template<class T>
-bool parseProtoOutputStream(ProtoOutputStream& protoOutput, T* message) {
- std::string pbBytes;
- sp<android::util::ProtoReader> reader = protoOutput.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- pbBytes.append(reinterpret_cast<const char*>(reader->readBuffer()), toRead);
- reader->move(toRead);
- }
- return message->ParseFromArray(pbBytes.c_str(), pbBytes.size());
-}
-
-// Checks the truncate timestamp annotation as well as the blacklisted range of 300,000 - 304,999.
-// Returns the truncated timestamp to the nearest 5 minutes if needed.
-int64_t truncateTimestampIfNecessary(const LogEvent& event);
-
-// Checks permission for given pid and uid.
-bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid);
-
-inline bool isVendorPulledAtom(int atomId) {
- return atomId >= StatsdStats::kVendorPulledAtomStartTag && atomId < StatsdStats::kMaxAtomTag;
-}
-
-inline bool isPulledAtom(int atomId) {
- return atomId >= StatsdStats::kPullAtomStartTag && atomId < StatsdStats::kVendorAtomStartTag;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/stats_util.h b/cmds/statsd/src/stats_util.h
deleted file mode 100644
index cfc411fdd25f..000000000000
--- a/cmds/statsd/src/stats_util.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "HashableDimensionKey.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const HashableDimensionKey DEFAULT_DIMENSION_KEY = HashableDimensionKey();
-const MetricDimensionKey DEFAULT_METRIC_DIMENSION_KEY = MetricDimensionKey();
-
-typedef std::map<int64_t, HashableDimensionKey> ConditionKey;
-
-typedef std::unordered_map<MetricDimensionKey, int64_t> DimToValMap;
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/statscompanion_util.cpp b/cmds/statsd/src/statscompanion_util.cpp
deleted file mode 100644
index ce07ec0ea884..000000000000
--- a/cmds/statsd/src/statscompanion_util.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "statscompanion_util.h"
-#include <android/binder_auto_utils.h>
-#include <android/binder_manager.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-shared_ptr<IStatsCompanionService> getStatsCompanionService() {
- ::ndk::SpAIBinder binder(AServiceManager_getService("statscompanion"));
- return IStatsCompanionService::fromBinder(binder);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/statscompanion_util.h b/cmds/statsd/src/statscompanion_util.h
deleted file mode 100644
index e20c40bba104..000000000000
--- a/cmds/statsd/src/statscompanion_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IStatsCompanionService.h>
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/** Fetches and returns the StatsCompanionService. */
-shared_ptr<IStatsCompanionService> getStatsCompanionService();
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
deleted file mode 100644
index acdffd3d4712..000000000000
--- a/cmds/statsd/src/statsd_config.proto
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "StatsdConfigProto";
-
-enum Position {
- POSITION_UNKNOWN = 0;
-
- FIRST = 1;
-
- LAST = 2;
-
- ANY = 3;
-
- ALL = 4;
-}
-
-enum TimeUnit {
- TIME_UNIT_UNSPECIFIED = 0;
- ONE_MINUTE = 1; // WILL BE GUARDRAILED TO 5 MINS UNLESS UID = SHELL OR ROOT
- FIVE_MINUTES = 2;
- TEN_MINUTES = 3;
- THIRTY_MINUTES = 4;
- ONE_HOUR = 5;
- THREE_HOURS = 6;
- SIX_HOURS = 7;
- TWELVE_HOURS = 8;
- ONE_DAY = 9;
- ONE_WEEK = 10;
- CTS = 1000;
-}
-
-message FieldMatcher {
- optional int32 field = 1;
-
- optional Position position = 2;
-
- repeated FieldMatcher child = 3;
-}
-
-message FieldValueMatcher {
- optional int32 field = 1;
-
- optional Position position = 2;
-
- oneof value_matcher {
- bool eq_bool = 3;
- string eq_string = 4;
- int64 eq_int = 5;
-
- int64 lt_int = 6;
- int64 gt_int = 7;
- float lt_float = 8;
- float gt_float = 9;
-
- int64 lte_int = 10;
- int64 gte_int = 11;
-
- MessageMatcher matches_tuple = 12;
-
- StringListMatcher eq_any_string = 13;
- StringListMatcher neq_any_string = 14;
- }
-}
-
-message MessageMatcher {
- repeated FieldValueMatcher field_value_matcher = 1;
-}
-
-message StringListMatcher {
- repeated string str_value = 1;
-}
-
-enum LogicalOperation {
- LOGICAL_OPERATION_UNSPECIFIED = 0;
- AND = 1;
- OR = 2;
- NOT = 3;
- NAND = 4;
- NOR = 5;
-}
-
-message SimpleAtomMatcher {
- optional int32 atom_id = 1;
-
- repeated FieldValueMatcher field_value_matcher = 2;
-}
-
-message AtomMatcher {
- optional int64 id = 1;
-
- message Combination {
- optional LogicalOperation operation = 1;
-
- repeated int64 matcher = 2;
- }
- oneof contents {
- SimpleAtomMatcher simple_atom_matcher = 2;
- Combination combination = 3;
- }
-}
-
-message SimplePredicate {
- optional int64 start = 1;
-
- optional int64 stop = 2;
-
- optional bool count_nesting = 3 [default = true];
-
- optional int64 stop_all = 4;
-
- enum InitialValue {
- UNKNOWN = 0;
- FALSE = 1;
- }
- optional InitialValue initial_value = 5 [default = UNKNOWN];
-
- optional FieldMatcher dimensions = 6;
-}
-
-message Predicate {
- optional int64 id = 1;
-
- message Combination {
- optional LogicalOperation operation = 1;
-
- repeated int64 predicate = 2;
- }
-
- oneof contents {
- SimplePredicate simple_predicate = 2;
- Combination combination = 3;
- }
-}
-
-message StateMap {
- message StateGroup {
- optional int64 group_id = 1;
-
- repeated int32 value = 2;
- }
-
- repeated StateGroup group = 1;
-}
-
-message State {
- optional int64 id = 1;
-
- optional int32 atom_id = 2;
-
- optional StateMap map = 3;
-}
-
-message MetricConditionLink {
- optional int64 condition = 1;
-
- optional FieldMatcher fields_in_what = 2;
-
- optional FieldMatcher fields_in_condition = 3;
-}
-
-message MetricStateLink {
- optional int32 state_atom_id = 1;
-
- optional FieldMatcher fields_in_what = 2;
-
- optional FieldMatcher fields_in_state = 3;
-}
-
-message FieldFilter {
- optional bool include_all = 1 [default = false];
- optional FieldMatcher fields = 2;
-}
-
-message EventMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 condition = 3;
-
- repeated MetricConditionLink links = 4;
-
- reserved 100;
- reserved 101;
-}
-
-message CountMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 condition = 3;
-
- optional FieldMatcher dimensions_in_what = 4;
-
- repeated int64 slice_by_state = 8;
-
- optional TimeUnit bucket = 5;
-
- repeated MetricConditionLink links = 6;
-
- repeated MetricStateLink state_link = 9;
-
- optional FieldMatcher dimensions_in_condition = 7 [deprecated = true];
-
- reserved 100;
- reserved 101;
-}
-
-message DurationMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 condition = 3;
-
- repeated int64 slice_by_state = 9;
-
- repeated MetricConditionLink links = 4;
-
- repeated MetricStateLink state_link = 10;
-
- enum AggregationType {
- SUM = 1;
-
- MAX_SPARSE = 2;
- }
- optional AggregationType aggregation_type = 5 [default = SUM];
-
- optional FieldMatcher dimensions_in_what = 6;
-
- optional TimeUnit bucket = 7;
-
- optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
-
- reserved 100;
- reserved 101;
-}
-
-message GaugeMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional int64 trigger_event = 12;
-
- optional FieldFilter gauge_fields_filter = 3;
-
- optional int64 condition = 4;
-
- optional FieldMatcher dimensions_in_what = 5;
-
- optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
-
- optional TimeUnit bucket = 6;
-
- repeated MetricConditionLink links = 7;
-
- enum SamplingType {
- RANDOM_ONE_SAMPLE = 1;
- ALL_CONDITION_CHANGES = 2 [deprecated = true];
- CONDITION_CHANGE_TO_TRUE = 3;
- FIRST_N_SAMPLES = 4;
- }
- optional SamplingType sampling_type = 9 [default = RANDOM_ONE_SAMPLE] ;
-
- optional int64 min_bucket_size_nanos = 10;
-
- optional int64 max_num_gauge_atoms_per_bucket = 11 [default = 10];
-
- optional int32 max_pull_delay_sec = 13 [default = 30];
-
- optional bool split_bucket_for_app_upgrade = 14 [default = true];
-
- reserved 100;
- reserved 101;
-}
-
-message ValueMetric {
- optional int64 id = 1;
-
- optional int64 what = 2;
-
- optional FieldMatcher value_field = 3;
-
- optional int64 condition = 4;
-
- optional FieldMatcher dimensions_in_what = 5;
-
- repeated int64 slice_by_state = 18;
-
- optional TimeUnit bucket = 6;
-
- repeated MetricConditionLink links = 7;
-
- repeated MetricStateLink state_link = 19;
-
- enum AggregationType {
- SUM = 1;
- MIN = 2;
- MAX = 3;
- AVG = 4;
- }
- optional AggregationType aggregation_type = 8 [default = SUM];
-
- optional int64 min_bucket_size_nanos = 10;
-
- optional bool use_absolute_value_on_reset = 11 [default = false];
-
- optional bool use_diff = 12;
-
- optional bool use_zero_default_base = 15 [default = false];
-
- enum ValueDirection {
- UNKNOWN = 0;
- INCREASING = 1;
- DECREASING = 2;
- ANY = 3;
- }
- optional ValueDirection value_direction = 13 [default = INCREASING];
-
- optional bool skip_zero_diff_output = 14 [default = true];
-
- optional int32 max_pull_delay_sec = 16 [default = 30];
-
- optional bool split_bucket_for_app_upgrade = 17 [default = true];
-
- optional FieldMatcher dimensions_in_condition = 9 [deprecated = true];
-
- reserved 100;
- reserved 101;
-}
-
-message Alert {
- optional int64 id = 1;
-
- optional int64 metric_id = 2;
-
- optional int32 num_buckets = 3;
-
- optional int32 refractory_period_secs = 4;
-
- optional double trigger_if_sum_gt = 5;
-}
-
-message Alarm {
- optional int64 id = 1;
-
- optional int64 offset_millis = 2;
-
- optional int64 period_millis = 3;
-}
-
-message IncidentdDetails {
- repeated int32 section = 1;
-
- enum Destination {
- AUTOMATIC = 0;
- EXPLICIT = 1;
- }
- optional Destination dest = 2;
-
- // Package name of the incident report receiver.
- optional string receiver_pkg = 3;
-
- // Class name of the incident report receiver.
- optional string receiver_cls = 4;
-
- optional string alert_description = 5;
-}
-
-message PerfettoDetails {
- // The |trace_config| field is a proto-encoded message of type
- // perfetto.protos.TraceConfig defined in
- // //external/perfetto/protos/perfetto/config/. On device,
- // statsd doesn't need to deserialize the message as it's just
- // passed binary-encoded to the perfetto cmdline client.
- optional bytes trace_config = 1;
-}
-
-message BroadcastSubscriberDetails {
- optional int64 subscriber_id = 1;
- repeated string cookie = 2;
-}
-
-message Subscription {
- optional int64 id = 1;
-
- enum RuleType {
- RULE_TYPE_UNSPECIFIED = 0;
- ALARM = 1;
- ALERT = 2;
- }
- optional RuleType rule_type = 2;
-
- optional int64 rule_id = 3;
-
- oneof subscriber_information {
- IncidentdDetails incidentd_details = 4;
- PerfettoDetails perfetto_details = 5;
- BroadcastSubscriberDetails broadcast_subscriber_details = 6;
- }
-
- optional float probability_of_informing = 7 [default = 1.1];
-
- // This was used for perfprofd historically.
- reserved 8;
-}
-
-enum ActivationType {
- ACTIVATION_TYPE_UNKNOWN = 0;
- ACTIVATE_IMMEDIATELY = 1;
- ACTIVATE_ON_BOOT = 2;
-}
-
-message EventActivation {
- optional int64 atom_matcher_id = 1;
- optional int64 ttl_seconds = 2;
- optional int64 deactivation_atom_matcher_id = 3;
- optional ActivationType activation_type = 4;
-}
-
-message MetricActivation {
- optional int64 metric_id = 1;
-
- optional ActivationType activation_type = 3 [deprecated = true];
-
- repeated EventActivation event_activation = 2;
-}
-
-message PullAtomPackages {
- optional int32 atom_id = 1;
-
- repeated string packages = 2;
-}
-
-message StatsdConfig {
- optional int64 id = 1;
-
- repeated EventMetric event_metric = 2;
-
- repeated CountMetric count_metric = 3;
-
- repeated ValueMetric value_metric = 4;
-
- repeated GaugeMetric gauge_metric = 5;
-
- repeated DurationMetric duration_metric = 6;
-
- repeated AtomMatcher atom_matcher = 7;
-
- repeated Predicate predicate = 8;
-
- repeated Alert alert = 9;
-
- repeated Alarm alarm = 10;
-
- repeated Subscription subscription = 11;
-
- repeated string allowed_log_source = 12;
-
- repeated int64 no_report_metric = 13;
-
- message Annotation {
- optional int64 field_int64 = 1;
- optional int32 field_int32 = 2;
- }
- repeated Annotation annotation = 14;
-
- optional int64 ttl_in_seconds = 15;
-
- optional bool hash_strings_in_metric_report = 16 [default = true];
-
- repeated MetricActivation metric_activation = 17;
-
- optional bool version_strings_in_metric_report = 18;
-
- optional bool installer_in_metric_report = 19;
-
- optional bool persist_locally = 20 [default = false];
-
- repeated State state = 21;
-
- repeated string default_pull_packages = 22;
-
- repeated PullAtomPackages pull_atom_packages = 23;
-
- repeated int32 whitelisted_atom_ids = 24;
-
- // Field number 1000 is reserved for later use.
- reserved 1000;
-}
diff --git a/cmds/statsd/src/statsd_metadata.proto b/cmds/statsd/src/statsd_metadata.proto
deleted file mode 100644
index 200b392f7542..000000000000
--- a/cmds/statsd/src/statsd_metadata.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd.metadata;
-
-message ConfigKey {
- optional int64 config_id = 1;
- optional int32 uid = 2;
-}
-
-message Field {
- optional int32 tag = 1;
- optional int32 field = 2;
-}
-
-message FieldValue {
- optional Field field = 1;
- oneof value {
- int32 value_int = 2;
- int64 value_long = 3;
- float value_float = 4;
- double value_double = 5;
- string value_str = 6;
- bytes value_storage = 7;
- }
-}
-
-message MetricDimensionKey {
- repeated FieldValue dimension_key_in_what = 1;
- repeated FieldValue state_values_key = 2;
-}
-
-message AlertDimensionKeyedData {
- // The earliest time the alert can be fired again in wall clock time.
- optional int32 last_refractory_ends_sec = 1;
- optional MetricDimensionKey dimension_key = 2;
-}
-
-message AlertMetadata {
- optional int64 alert_id = 1;
- repeated AlertDimensionKeyedData alert_dim_keyed_data = 2;
-}
-
-// All metadata for a config in statsd
-message StatsMetadata {
- optional ConfigKey config_key = 1;
- repeated AlertMetadata alert_metadata = 2;
-}
-
-message StatsMetadataList {
- repeated StatsMetadata stats_metadata = 1;
-} \ No newline at end of file
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
deleted file mode 100644
index dcfdfe3aae53..000000000000
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "android-base/stringprintf.h"
-#include "guardrail/StatsdStats.h"
-#include "storage/StorageManager.h"
-#include "stats_log_util.h"
-
-#include <android-base/file.h>
-#include <private/android_filesystem_config.h>
-#include <fstream>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_MESSAGE;
-using std::map;
-
-/**
- * NOTE: these directories are protected by SELinux, any changes here must also update
- * the SELinux policies.
- */
-#define STATS_DATA_DIR "/data/misc/stats-data"
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-#define TRAIN_INFO_DIR "/data/misc/train-info"
-#define TRAIN_INFO_PATH "/data/misc/train-info/train-info.bin"
-
-// Magic word at the start of the train info file, change this if changing the file format
-const uint32_t TRAIN_INFO_FILE_MAGIC = 0xfb7447bf;
-
-// for ConfigMetricsReportList
-const int FIELD_ID_REPORTS = 2;
-
-std::mutex StorageManager::sTrainInfoMutex;
-
-using android::base::StringPrintf;
-using std::unique_ptr;
-
-struct FileName {
- int64_t mTimestampSec;
- int mUid;
- int64_t mConfigId;
- bool mIsHistory;
- string getFullFileName(const char* path) {
- return StringPrintf("%s/%lld_%d_%lld%s", path, (long long)mTimestampSec, (int)mUid,
- (long long)mConfigId, (mIsHistory ? "_history" : ""));
- };
-};
-
-string StorageManager::getDataFileName(long wallClockSec, int uid, int64_t id) {
- return StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, wallClockSec, uid,
- (long long)id);
-}
-
-string StorageManager::getDataHistoryFileName(long wallClockSec, int uid, int64_t id) {
- return StringPrintf("%s/%ld_%d_%lld_history", STATS_DATA_DIR, wallClockSec, uid,
- (long long)id);
-}
-
-static string findTrainInfoFileNameLocked(const string& trainName) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", TRAIN_INFO_DIR);
- return "";
- }
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* fileName = de->d_name;
- if (fileName[0] == '.') continue;
-
- size_t fileNameLength = strlen(fileName);
- if (fileNameLength >= trainName.length()) {
- if (0 == strncmp(fileName + fileNameLength - trainName.length(), trainName.c_str(),
- trainName.length())) {
- return string(fileName);
- }
- }
- }
-
- return "";
-}
-
-// Returns array of int64_t which contains timestamp in seconds, uid,
-// configID and whether the file is a local history file.
-static void parseFileName(char* name, FileName* output) {
- int64_t result[3];
- int index = 0;
- char* substr = strtok(name, "_");
- while (substr != nullptr && index < 3) {
- result[index] = StrToInt64(substr);
- index++;
- substr = strtok(nullptr, "_");
- }
- // When index ends before hitting 3, file name is corrupted. We
- // intentionally put -1 at index 0 to indicate the error to caller.
- // TODO(b/110563137): consider removing files with unexpected name format.
- if (index < 3) {
- result[0] = -1;
- }
-
- output->mTimestampSec = result[0];
- output->mUid = result[1];
- output->mConfigId = result[2];
- // check if the file is a local history.
- output->mIsHistory = (substr != nullptr && strcmp("history", substr) == 0);
-}
-
-void StorageManager::writeFile(const char* file, const void* buffer, int numBytes) {
- int fd = open(file, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
- if (fd == -1) {
- VLOG("Attempt to access %s but failed", file);
- return;
- }
- trimToFit(STATS_SERVICE_DIR);
- trimToFit(STATS_DATA_DIR);
-
- if (android::base::WriteFully(fd, buffer, numBytes)) {
- VLOG("Successfully wrote %s", file);
- } else {
- ALOGE("Failed to write %s", file);
- }
-
- int result = fchown(fd, AID_STATSD, AID_STATSD);
- if (result) {
- VLOG("Failed to chown %s to statsd", file);
- }
-
- close(fd);
-}
-
-bool StorageManager::writeTrainInfo(const InstallTrainInfo& trainInfo) {
- std::lock_guard<std::mutex> lock(sTrainInfoMutex);
-
- if (trainInfo.trainName.empty()) {
- return false;
- }
- deleteSuffixedFiles(TRAIN_INFO_DIR, trainInfo.trainName.c_str());
-
- std::string fileName =
- StringPrintf("%s/%ld_%s", TRAIN_INFO_DIR, (long) getWallClockSec(),
- trainInfo.trainName.c_str());
-
- int fd = open(fileName.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
- if (fd == -1) {
- VLOG("Attempt to access %s but failed", fileName.c_str());
- return false;
- }
-
- size_t result;
- // Write the magic word
- result = write(fd, &TRAIN_INFO_FILE_MAGIC, sizeof(TRAIN_INFO_FILE_MAGIC));
- if (result != sizeof(TRAIN_INFO_FILE_MAGIC)) {
- VLOG("Failed to wrtie train info magic");
- close(fd);
- return false;
- }
-
- // Write the train version
- const size_t trainVersionCodeByteCount = sizeof(trainInfo.trainVersionCode);
- result = write(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
- if (result != trainVersionCodeByteCount) {
- VLOG("Failed to wrtie train version code");
- close(fd);
- return false;
- }
-
- // Write # of bytes in trainName to file
- const size_t trainNameSize = trainInfo.trainName.size();
- const size_t trainNameSizeByteCount = sizeof(trainNameSize);
- result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount);
- if (result != trainNameSizeByteCount) {
- VLOG("Failed to write train name size");
- close(fd);
- return false;
- }
-
- // Write trainName to file
- result = write(fd, trainInfo.trainName.c_str(), trainNameSize);
- if (result != trainNameSize) {
- VLOG("Failed to write train name");
- close(fd);
- return false;
- }
-
- // Write status to file
- const size_t statusByteCount = sizeof(trainInfo.status);
- result = write(fd, (uint8_t*)&trainInfo.status, statusByteCount);
- if (result != statusByteCount) {
- VLOG("Failed to write status");
- close(fd);
- return false;
- }
-
- // Write experiment id count to file.
- const size_t experimentIdsCount = trainInfo.experimentIds.size();
- const size_t experimentIdsCountByteCount = sizeof(experimentIdsCount);
- result = write(fd, (uint8_t*) &experimentIdsCount, experimentIdsCountByteCount);
- if (result != experimentIdsCountByteCount) {
- VLOG("Failed to write experiment id count");
- close(fd);
- return false;
- }
-
- // Write experimentIds to file
- for (size_t i = 0; i < experimentIdsCount; i++) {
- const int64_t experimentId = trainInfo.experimentIds[i];
- const size_t experimentIdByteCount = sizeof(experimentId);
- result = write(fd, &experimentId, experimentIdByteCount);
- if (result == experimentIdByteCount) {
- VLOG("Successfully wrote experiment IDs");
- } else {
- VLOG("Failed to write experiment ids");
- close(fd);
- return false;
- }
- }
-
- // Write bools to file
- const size_t boolByteCount = sizeof(trainInfo.requiresStaging);
- result = write(fd, (uint8_t*)&trainInfo.requiresStaging, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to write requires staging");
- close(fd);
- return false;
- }
-
- result = write(fd, (uint8_t*)&trainInfo.rollbackEnabled, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to write rollback enabled");
- close(fd);
- return false;
- }
-
- result = write(fd, (uint8_t*)&trainInfo.requiresLowLatencyMonitor, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to write requires log latency monitor");
- close(fd);
- return false;
- }
-
- close(fd);
- return true;
-}
-
-bool StorageManager::readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo) {
- std::lock_guard<std::mutex> lock(sTrainInfoMutex);
- return readTrainInfoLocked(trainName, trainInfo);
-}
-
-bool StorageManager::readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo) {
- trimToFit(TRAIN_INFO_DIR, /*parseTimestampOnly=*/ true);
- string fileName = findTrainInfoFileNameLocked(trainName);
- if (fileName.empty()) {
- return false;
- }
- int fd = open(StringPrintf("%s/%s", TRAIN_INFO_DIR, fileName.c_str()).c_str(), O_RDONLY | O_CLOEXEC);
- if (fd == -1) {
- VLOG("Failed to open %s", fileName.c_str());
- return false;
- }
-
- // Read the magic word
- uint32_t magic;
- size_t result = read(fd, &magic, sizeof(magic));
- if (result != sizeof(magic)) {
- VLOG("Failed to read train info magic");
- close(fd);
- return false;
- }
-
- if (magic != TRAIN_INFO_FILE_MAGIC) {
- VLOG("Train info magic was 0x%08x, expected 0x%08x", magic, TRAIN_INFO_FILE_MAGIC);
- close(fd);
- return false;
- }
-
- // Read the train version code
- const size_t trainVersionCodeByteCount(sizeof(trainInfo.trainVersionCode));
- result = read(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
- if (result != trainVersionCodeByteCount) {
- VLOG("Failed to read train version code from train info file");
- close(fd);
- return false;
- }
-
- // Read # of bytes taken by trainName in the file.
- size_t trainNameSize;
- result = read(fd, &trainNameSize, sizeof(size_t));
- if (result != sizeof(size_t)) {
- VLOG("Failed to read train name size from train info file");
- close(fd);
- return false;
- }
-
- // Read trainName
- trainInfo.trainName.resize(trainNameSize);
- result = read(fd, trainInfo.trainName.data(), trainNameSize);
- if (result != trainNameSize) {
- VLOG("Failed to read train name from train info file");
- close(fd);
- return false;
- }
-
- // Read status
- const size_t statusByteCount = sizeof(trainInfo.status);
- result = read(fd, &trainInfo.status, statusByteCount);
- if (result != statusByteCount) {
- VLOG("Failed to read train status from train info file");
- close(fd);
- return false;
- }
-
- // Read experiment ids count.
- size_t experimentIdsCount;
- result = read(fd, &experimentIdsCount, sizeof(size_t));
- if (result != sizeof(size_t)) {
- VLOG("Failed to read train experiment id count from train info file");
- close(fd);
- return false;
- }
-
- // Read experimentIds
- for (size_t i = 0; i < experimentIdsCount; i++) {
- int64_t experimentId;
- result = read(fd, &experimentId, sizeof(experimentId));
- if (result != sizeof(experimentId)) {
- VLOG("Failed to read train experiment id from train info file");
- close(fd);
- return false;
- }
- trainInfo.experimentIds.push_back(experimentId);
- }
-
- // Read bools
- const size_t boolByteCount = sizeof(trainInfo.requiresStaging);
- result = read(fd, &trainInfo.requiresStaging, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to read requires requires staging from train info file");
- close(fd);
- return false;
- }
-
- result = read(fd, &trainInfo.rollbackEnabled, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to read requires rollback enabled from train info file");
- close(fd);
- return false;
- }
-
- result = read(fd, &trainInfo.requiresLowLatencyMonitor, boolByteCount);
- if (result != boolByteCount) {
- VLOG("Failed to read requires requires low latency monitor from train info file");
- close(fd);
- return false;
- }
-
- // Expect to be at EOF.
- char c;
- result = read(fd, &c, 1);
- if (result != 0) {
- VLOG("Failed to read train info from file. Did not get expected EOF.");
- close(fd);
- return false;
- }
-
- VLOG("Read train info file successful");
- close(fd);
- return true;
-}
-
-vector<InstallTrainInfo> StorageManager::readAllTrainInfo() {
- std::lock_guard<std::mutex> lock(sTrainInfoMutex);
- vector<InstallTrainInfo> trainInfoList;
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", TRAIN_INFO_DIR);
- return trainInfoList;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
-
- InstallTrainInfo trainInfo;
- bool readSuccess = StorageManager::readTrainInfoLocked(name, trainInfo);
- if (!readSuccess) {
- continue;
- }
- trainInfoList.push_back(trainInfo);
- }
- return trainInfoList;
-}
-
-void StorageManager::deleteFile(const char* file) {
- if (remove(file) != 0) {
- VLOG("Attempt to delete %s but is not found", file);
- } else {
- VLOG("Successfully deleted %s", file);
- }
-}
-
-void StorageManager::deleteAllFiles(const char* path) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", path);
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
- deleteFile(StringPrintf("%s/%s", path, name).c_str());
- }
-}
-
-void StorageManager::deleteSuffixedFiles(const char* path, const char* suffix) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", path);
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
- size_t nameLen = strlen(name);
- size_t suffixLen = strlen(suffix);
- if (suffixLen <= nameLen && strncmp(name + nameLen - suffixLen, suffix, suffixLen) == 0) {
- deleteFile(StringPrintf("%s/%s", path, name).c_str());
- }
- }
-}
-
-void StorageManager::sendBroadcast(const char* path,
- const std::function<void(const ConfigKey&)>& sendBroadcast) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("no stats-data directory on disk");
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
- VLOG("file %s", name);
-
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1 || output.mIsHistory) continue;
- sendBroadcast(ConfigKey((int)output.mUid, output.mConfigId));
- }
-}
-
-bool StorageManager::hasConfigMetricsReport(const ConfigKey& key) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_DATA_DIR), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", STATS_DATA_DIR);
- return false;
- }
-
- string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
-
- size_t nameLen = strlen(name);
- size_t suffixLen = suffix.length();
- if (suffixLen <= nameLen &&
- strncmp(name + nameLen - suffixLen, suffix.c_str(), suffixLen) == 0) {
- // Check again that the file name is parseable.
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1 || output.mIsHistory) continue;
- return true;
- }
- }
- return false;
-}
-
-void StorageManager::appendConfigMetricsReport(const ConfigKey& key, ProtoOutputStream* proto,
- bool erase_data, bool isAdb) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_DATA_DIR), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", STATS_DATA_DIR);
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- string fileName(name);
- if (name[0] == '.') continue;
- FileName output;
- parseFileName(name, &output);
-
- if (output.mTimestampSec == -1 || (output.mIsHistory && !isAdb) ||
- output.mUid != key.GetUid() || output.mConfigId != key.GetId()) {
- continue;
- }
-
- auto fullPathName = StringPrintf("%s/%s", STATS_DATA_DIR, fileName.c_str());
- int fd = open(fullPathName.c_str(), O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- string content;
- if (android::base::ReadFdToString(fd, &content)) {
- proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
- content.c_str(), content.size());
- }
- close(fd);
- } else {
- ALOGE("file cannot be opened");
- }
-
- if (erase_data) {
- remove(fullPathName.c_str());
- } else if (!output.mIsHistory && !isAdb) {
- // This means a real data owner has called to get this data. But the config says it
- // wants to keep a local history. So now this file must be renamed as a history file.
- // So that next time, when owner calls getData() again, this data won't be uploaded
- // again. rename returns 0 on success
- if (rename(fullPathName.c_str(), (fullPathName + "_history").c_str())) {
- ALOGE("Failed to rename file %s", fullPathName.c_str());
- }
- }
- }
-}
-
-bool StorageManager::readFileToString(const char* file, string* content) {
- int fd = open(file, O_RDONLY | O_CLOEXEC);
- bool res = false;
- if (fd != -1) {
- if (android::base::ReadFdToString(fd, content)) {
- res = true;
- } else {
- VLOG("Failed to read file %s\n", file);
- }
- close(fd);
- }
- return res;
-}
-
-void StorageManager::readConfigFromDisk(map<ConfigKey, StatsdConfig>& configsMap) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR), closedir);
- if (dir == NULL) {
- VLOG("no default config on disk");
- return;
- }
- trimToFit(STATS_SERVICE_DIR);
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
-
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1) continue;
- string file_name = output.getFullFileName(STATS_SERVICE_DIR);
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- string content;
- if (android::base::ReadFdToString(fd, &content)) {
- StatsdConfig config;
- if (config.ParseFromString(content)) {
- configsMap[ConfigKey(output.mUid, output.mConfigId)] = config;
- VLOG("map key uid=%lld|configID=%lld", (long long)output.mUid,
- (long long)output.mConfigId);
- }
- }
- close(fd);
- }
- }
-}
-
-bool StorageManager::readConfigFromDisk(const ConfigKey& key, StatsdConfig* config) {
- string content;
- return config != nullptr &&
- StorageManager::readConfigFromDisk(key, &content) && config->ParseFromString(content);
-}
-
-bool StorageManager::readConfigFromDisk(const ConfigKey& key, string* content) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR),
- closedir);
- if (dir == NULL) {
- VLOG("Directory does not exist: %s", STATS_SERVICE_DIR);
- return false;
- }
-
- string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
- size_t nameLen = strlen(name);
- size_t suffixLen = suffix.length();
- // There can be at most one file that matches this suffix (config key).
- if (suffixLen <= nameLen &&
- strncmp(name + nameLen - suffixLen, suffix.c_str(), suffixLen) == 0) {
- int fd = open(StringPrintf("%s/%s", STATS_SERVICE_DIR, name).c_str(),
- O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- if (android::base::ReadFdToString(fd, content)) {
- return true;
- }
- close(fd);
- }
- }
- }
- return false;
-}
-
-bool StorageManager::hasIdenticalConfig(const ConfigKey& key,
- const vector<uint8_t>& config) {
- string content;
- if (StorageManager::readConfigFromDisk(key, &content)) {
- vector<uint8_t> vec(content.begin(), content.end());
- if (vec == config) {
- return true;
- }
- }
- return false;
-}
-
-void StorageManager::sortFiles(vector<FileInfo>* fileNames) {
- // Reverse sort to effectively remove from the back (oldest entries).
- // This will sort files in reverse-chronological order. Local history files have lower
- // priority than regular data files.
- sort(fileNames->begin(), fileNames->end(), [](FileInfo& lhs, FileInfo& rhs) {
- // first consider if the file is a local history
- if (lhs.mIsHistory && !rhs.mIsHistory) {
- return false;
- } else if (rhs.mIsHistory && !lhs.mIsHistory) {
- return true;
- }
-
- // then consider the age.
- if (lhs.mFileAgeSec < rhs.mFileAgeSec) {
- return true;
- } else if (lhs.mFileAgeSec > rhs.mFileAgeSec) {
- return false;
- }
-
- // then good luck.... use string::compare
- return lhs.mFileName.compare(rhs.mFileName) > 0;
- });
-}
-
-void StorageManager::trimToFit(const char* path, bool parseTimestampOnly) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", path);
- return;
- }
- dirent* de;
- int totalFileSize = 0;
- vector<FileInfo> fileNames;
- auto nowSec = getWallClockSec();
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
-
- FileName output;
- string file_name;
- if (parseTimestampOnly) {
- file_name = StringPrintf("%s/%s", path, name);
- output.mTimestampSec = StrToInt64(strtok(name, "_"));
- output.mIsHistory = false;
- } else {
- parseFileName(name, &output);
- file_name = output.getFullFileName(path);
- }
- if (output.mTimestampSec == -1) continue;
-
- // Check for timestamp and delete if it's too old.
- long fileAge = nowSec - output.mTimestampSec;
- if (fileAge > StatsdStats::kMaxAgeSecond ||
- (output.mIsHistory && fileAge > StatsdStats::kMaxLocalHistoryAgeSecond)) {
- deleteFile(file_name.c_str());
- continue;
- }
-
- ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
- int fileSize = 0;
- if (file.is_open()) {
- file.seekg(0, ios::end);
- fileSize = file.tellg();
- file.close();
- totalFileSize += fileSize;
- }
- fileNames.emplace_back(file_name, output.mIsHistory, fileSize, fileAge);
- }
-
- if (fileNames.size() > StatsdStats::kMaxFileNumber ||
- totalFileSize > StatsdStats::kMaxFileSize) {
- sortFiles(&fileNames);
- }
-
- // Start removing files from oldest to be under the limit.
- while (fileNames.size() > 0 && (fileNames.size() > StatsdStats::kMaxFileNumber ||
- totalFileSize > StatsdStats::kMaxFileSize)) {
- totalFileSize -= fileNames.at(fileNames.size() - 1).mFileSizeBytes;
- deleteFile(fileNames.at(fileNames.size() - 1).mFileName.c_str());
- fileNames.pop_back();
- }
-}
-
-void StorageManager::printStats(int outFd) {
- printDirStats(outFd, STATS_SERVICE_DIR);
- printDirStats(outFd, STATS_DATA_DIR);
-}
-
-void StorageManager::printDirStats(int outFd, const char* path) {
- dprintf(outFd, "Printing stats of %s\n", path);
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
- if (dir == NULL) {
- VLOG("Path %s does not exist", path);
- return;
- }
- dirent* de;
- int fileCount = 0;
- int totalFileSize = 0;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') {
- continue;
- }
- FileName output;
- parseFileName(name, &output);
- if (output.mTimestampSec == -1) continue;
- dprintf(outFd, "\t #%d, Last updated: %lld, UID: %d, Config ID: %lld, %s", fileCount + 1,
- (long long)output.mTimestampSec, output.mUid, (long long)output.mConfigId,
- (output.mIsHistory ? "local history" : ""));
- string file_name = output.getFullFileName(path);
- ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
- if (file.is_open()) {
- file.seekg(0, ios::end);
- int fileSize = file.tellg();
- file.close();
- dprintf(outFd, ", File Size: %d bytes", fileSize);
- totalFileSize += fileSize;
- }
- dprintf(outFd, "\n");
- fileCount++;
- }
- dprintf(outFd, "\tTotal number of files: %d, Total size of files: %d bytes.\n", fileCount,
- totalFileSize);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
deleted file mode 100644
index d59046dfbb99..000000000000
--- a/cmds/statsd/src/storage/StorageManager.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STORAGE_MANAGER_H
-#define STORAGE_MANAGER_H
-
-#include <android/util/ProtoOutputStream.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-
-class StorageManager : public virtual RefBase {
-public:
- struct FileInfo {
- FileInfo(std::string name, bool isHistory, int fileSize, long fileAge)
- : mFileName(name),
- mIsHistory(isHistory),
- mFileSizeBytes(fileSize),
- mFileAgeSec(fileAge) {
- }
- std::string mFileName;
- bool mIsHistory;
- int mFileSizeBytes;
- long mFileAgeSec;
- };
-
- /**
- * Writes a given byte array as a file to the specified file path.
- */
- static void writeFile(const char* file, const void* buffer, int numBytes);
-
- /**
- * Writes train info.
- */
- static bool writeTrainInfo(const InstallTrainInfo& trainInfo);
-
- /**
- * Reads train info.
- */
- static bool readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo);
-
- /**
- * Reads train info assuming lock is obtained.
- */
- static bool readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo);
-
- /**
- * Reads all train info and returns a vector of train info.
- */
- static vector<InstallTrainInfo> readAllTrainInfo();
-
- /**
- * Reads the file content to the buffer.
- */
- static bool readFileToString(const char* file, string* content);
-
- /**
- * Deletes a single file given a file name.
- */
- static void deleteFile(const char* file);
-
- /**
- * Deletes all files in a given directory.
- */
- static void deleteAllFiles(const char* path);
-
- /**
- * Deletes all files whose name matches with a provided suffix.
- */
- static void deleteSuffixedFiles(const char* path, const char* suffix);
-
- /**
- * Send broadcasts to relevant receiver for each data stored on disk.
- */
- static void sendBroadcast(const char* path,
- const std::function<void(const ConfigKey&)>& sendBroadcast);
-
- /**
- * Returns true if there's at least one report on disk.
- */
- static bool hasConfigMetricsReport(const ConfigKey& key);
-
- /**
- * Appends the ConfigMetricsReport found on disk to the specifid proto
- * and, if erase_data, deletes it from disk.
- *
- * [isAdb]: if the caller is adb dump. This includes local adb dump or dumpsys by
- * bugreport or incidentd. When true, we will append any local history data too.
- *
- * When
- * erase_data=true, isAdb=true: append history data to output, remove all data after read
- * erase_data=false, isAdb=true: append history data to output, keep data after read
- * erase_data=true, isAdb=false: do not append history data, and remove data after read
- * erase_data=false, isAdb=false: do not append history data and *rename* all data files to
- * history files.
- */
- static void appendConfigMetricsReport(const ConfigKey& key, ProtoOutputStream* proto,
- bool erase_data, bool isAdb);
-
- /**
- * Call to load the saved configs from disk.
- */
- static void readConfigFromDisk(std::map<ConfigKey, StatsdConfig>& configsMap);
-
- /**
- * Call to load the specified config from disk. Returns false if the config file does not
- * exist or error occurs when reading the file.
- */
- static bool readConfigFromDisk(const ConfigKey& key, StatsdConfig* config);
- static bool readConfigFromDisk(const ConfigKey& key, string* config);
-
- /**
- * Trims files in the provided directory to limit the total size, number of
- * files, accumulation of outdated files.
- */
- static void trimToFit(const char* dir, bool parseTimestampOnly = false);
-
- /**
- * Returns true if there already exists identical configuration on device.
- */
- static bool hasIdenticalConfig(const ConfigKey& key,
- const vector<uint8_t>& config);
-
- /**
- * Prints disk usage statistics related to statsd.
- */
- static void printStats(int out);
-
- static string getDataFileName(long wallClockSec, int uid, int64_t id);
-
- static string getDataHistoryFileName(long wallClockSec, int uid, int64_t id);
-
- static void sortFiles(vector<FileInfo>* fileNames);
-
-private:
- /**
- * Prints disk usage statistics about a directory related to statsd.
- */
- static void printDirStats(int out, const char* path);
-
- static std::mutex sTrainInfoMutex;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // STORAGE_MANAGER_H
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
deleted file mode 100644
index 1d77513d9d33..000000000000
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false
-#include "Log.h"
-
-#include "FieldValue.h"
-#include "IncidentdReporter.h"
-#include "packages/UidMap.h"
-#include "stats_log_util.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <incident/incident_report.h>
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using std::vector;
-
-using util::FIELD_TYPE_INT32;
-using util::FIELD_TYPE_INT64;
-using util::FIELD_TYPE_MESSAGE;
-using util::FIELD_TYPE_STRING;
-
-// field ids in IncidentHeaderProto
-const int FIELD_ID_ALERT_ID = 1;
-const int FIELD_ID_REASON = 2;
-const int FIELD_ID_CONFIG_KEY = 3;
-const int FIELD_ID_CONFIG_KEY_UID = 1;
-const int FIELD_ID_CONFIG_KEY_ID = 2;
-
-const int FIELD_ID_TRIGGER_DETAILS = 4;
-const int FIELD_ID_TRIGGER_DETAILS_TRIGGER_METRIC = 1;
-const int FIELD_ID_METRIC_VALUE_METRIC_ID = 1;
-const int FIELD_ID_METRIC_VALUE_DIMENSION_IN_WHAT = 2;
-const int FIELD_ID_METRIC_VALUE_VALUE = 4;
-
-const int FIELD_ID_PACKAGE_INFO = 3;
-
-namespace {
-void getProtoData(const int64_t& rule_id, int64_t metricId, const MetricDimensionKey& dimensionKey,
- int64_t metricValue, const ConfigKey& configKey, const string& reason,
- vector<uint8_t>* protoData) {
- ProtoOutputStream headerProto;
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_ID, (long long)rule_id);
- headerProto.write(FIELD_TYPE_STRING | FIELD_ID_REASON, reason);
- uint64_t token =
- headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
- headerProto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_KEY_UID, configKey.GetUid());
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_KEY_ID, (long long)configKey.GetId());
- headerProto.end(token);
-
- token = headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_TRIGGER_DETAILS);
-
- // MetricValue trigger_metric = 1;
- uint64_t metricToken =
- headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_TRIGGER_DETAILS_TRIGGER_METRIC);
- // message MetricValue {
- // optional int64 metric_id = 1;
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_VALUE_METRIC_ID, (long long)metricId);
- // optional DimensionsValue dimension_in_what = 2;
- uint64_t dimToken =
- headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_METRIC_VALUE_DIMENSION_IN_WHAT);
- writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), nullptr, &headerProto);
- headerProto.end(dimToken);
-
- // deprecated field
- // optional DimensionsValue dimension_in_condition = 3;
-
- // optional int64 value = 4;
- headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_VALUE_VALUE, (long long)metricValue);
-
- // }
- headerProto.end(metricToken);
-
- // write relevant uid package info
- std::set<int32_t> uids;
-
- for (const auto& dim : dimensionKey.getDimensionKeyInWhat().getValues()) {
- int uid = getUidIfExists(dim);
- // any uid <= 2000 are predefined AID_*
- if (uid > 2000) {
- uids.insert(uid);
- }
- }
-
- if (!uids.empty()) {
- uint64_t token = headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PACKAGE_INFO);
- UidMap::getInstance()->writeUidMapSnapshot(getElapsedRealtimeNs(), true, true, uids,
- nullptr /*string set*/, &headerProto);
- headerProto.end(token);
- }
-
- headerProto.end(token);
-
- protoData->resize(headerProto.size());
- size_t pos = 0;
- sp<android::util::ProtoReader> reader = headerProto.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((*protoData)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-}
-} // namespace
-
-bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int64_t metricId,
- const MetricDimensionKey& dimensionKey, int64_t metricValue,
- const ConfigKey& configKey) {
- if (config.section_size() == 0) {
- VLOG("The alert %lld contains zero section in config(%d,%lld)", (unsigned long long)rule_id,
- configKey.GetUid(), (long long)configKey.GetId());
- return false;
- }
-
- AIncidentReportArgs* args = AIncidentReportArgs_init();
-
- vector<uint8_t> protoData;
- getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey,
- config.alert_description(), &protoData);
- AIncidentReportArgs_addHeader(args, protoData.data(), protoData.size());
-
- for (int i = 0; i < config.section_size(); i++) {
- AIncidentReportArgs_addSection(args, config.section(i));
- }
-
- uint8_t dest;
- switch (config.dest()) {
- case IncidentdDetails_Destination_AUTOMATIC:
- dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC;
- break;
- case IncidentdDetails_Destination_EXPLICIT:
- dest = INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT;
- break;
- default:
- dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC;
- }
- AIncidentReportArgs_setPrivacyPolicy(args, dest);
-
- AIncidentReportArgs_setReceiverPackage(args, config.receiver_pkg().c_str());
-
- AIncidentReportArgs_setReceiverClass(args, config.receiver_cls().c_str());
-
- int err = AIncidentReportArgs_takeReport(args);
- AIncidentReportArgs_delete(args);
-
- return err == NO_ERROR;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.h b/cmds/statsd/src/subscriber/IncidentdReporter.h
deleted file mode 100644
index e78a4d98dcd8..000000000000
--- a/cmds/statsd/src/subscriber/IncidentdReporter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "HashableDimensionKey.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert, IncidentdDetails
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Calls incidentd to trigger an incident report and put in dropbox for uploading.
- */
-bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int64_t metricId,
- const MetricDimensionKey& dimensionKey, int64_t metricValue,
- const ConfigKey& configKey);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
deleted file mode 100644
index c915ef3bf069..000000000000
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "SubscriberReporter.h"
-
-using std::lock_guard;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-struct BroadcastSubscriberDeathCookie {
- BroadcastSubscriberDeathCookie(const ConfigKey& configKey, int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir):
- mConfigKey(configKey),
- mSubscriberId(subscriberId),
- mPir(pir) {}
-
- ConfigKey mConfigKey;
- int64_t mSubscriberId;
- shared_ptr<IPendingIntentRef> mPir;
-};
-
-void SubscriberReporter::broadcastSubscriberDied(void* cookie) {
- auto cookie_ = static_cast<BroadcastSubscriberDeathCookie*>(cookie);
- ConfigKey& configKey = cookie_->mConfigKey;
- int64_t subscriberId = cookie_->mSubscriberId;
- shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
- SubscriberReporter& thiz = getInstance();
-
- // Erase the mapping from a (config_key, subscriberId) to a pir if the
- // mapping exists.
- lock_guard<mutex> lock(thiz.mLock);
- auto subscriberMapIt = thiz.mIntentMap.find(configKey);
- if (subscriberMapIt != thiz.mIntentMap.end()) {
- auto subscriberMap = subscriberMapIt->second;
- auto pirIt = subscriberMap.find(subscriberId);
- if (pirIt != subscriberMap.end() && pirIt->second == pir) {
- subscriberMap.erase(subscriberId);
- if (subscriberMap.empty()) {
- thiz.mIntentMap.erase(configKey);
- }
- }
- }
-
- // The death recipient corresponding to this specific pir can never be
- // triggered again, so free up resources.
- delete cookie_;
-}
-
-SubscriberReporter::SubscriberReporter() :
- mBroadcastSubscriberDeathRecipient(AIBinder_DeathRecipient_new(broadcastSubscriberDied)) {
-}
-
-void SubscriberReporter::setBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir) {
- VLOG("SubscriberReporter::setBroadcastSubscriber called.");
- {
- lock_guard<mutex> lock(mLock);
- mIntentMap[configKey][subscriberId] = pir;
- }
- AIBinder_linkToDeath(pir->asBinder().get(), mBroadcastSubscriberDeathRecipient.get(),
- new BroadcastSubscriberDeathCookie(configKey, subscriberId, pir));
-}
-
-void SubscriberReporter::unsetBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId) {
- VLOG("SubscriberReporter::unsetBroadcastSubscriber called.");
- lock_guard<mutex> lock(mLock);
- auto subscriberMapIt = mIntentMap.find(configKey);
- if (subscriberMapIt != mIntentMap.end()) {
- subscriberMapIt->second.erase(subscriberId);
- if (subscriberMapIt->second.empty()) {
- mIntentMap.erase(configKey);
- }
- }
-}
-
-void SubscriberReporter::alertBroadcastSubscriber(const ConfigKey& configKey,
- const Subscription& subscription,
- const MetricDimensionKey& dimKey) const {
- // Reminder about ids:
- // subscription id - name of the Subscription (that ties the Alert to the broadcast)
- // subscription rule_id - the name of the Alert (that triggers the broadcast)
- // subscriber_id - name of the PendingIntent to use to send the broadcast
- // config uid - the uid that uploaded the config (and therefore gave the PendingIntent,
- // although the intent may be to broadcast to a different uid)
- // config id - the name of this config (for this particular uid)
-
- VLOG("SubscriberReporter::alertBroadcastSubscriber called.");
- lock_guard<mutex> lock(mLock);
-
- if (!subscription.has_broadcast_subscriber_details()
- || !subscription.broadcast_subscriber_details().has_subscriber_id()) {
- ALOGE("Broadcast subscriber does not have an id.");
- return;
- }
- int64_t subscriberId = subscription.broadcast_subscriber_details().subscriber_id();
-
- vector<string> cookies;
- cookies.reserve(subscription.broadcast_subscriber_details().cookie_size());
- for (auto& cookie : subscription.broadcast_subscriber_details().cookie()) {
- cookies.push_back(cookie);
- }
-
- auto it1 = mIntentMap.find(configKey);
- if (it1 == mIntentMap.end()) {
- ALOGW("Cannot inform subscriber for missing config key %s ", configKey.ToString().c_str());
- return;
- }
- auto it2 = it1->second.find(subscriberId);
- if (it2 == it1->second.end()) {
- ALOGW("Cannot inform subscriber of config %s for missing subscriberId %lld ",
- configKey.ToString().c_str(), (long long)subscriberId);
- return;
- }
- sendBroadcastLocked(it2->second, configKey, subscription, cookies, dimKey);
-}
-
-void SubscriberReporter::sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
- const ConfigKey& configKey,
- const Subscription& subscription,
- const vector<string>& cookies,
- const MetricDimensionKey& dimKey) const {
- VLOG("SubscriberReporter::sendBroadcastLocked called.");
- pir->sendSubscriberBroadcast(
- configKey.GetUid(),
- configKey.GetId(),
- subscription.id(),
- subscription.rule_id(),
- cookies,
- dimKey.getDimensionKeyInWhat().toStatsDimensionsValueParcel());
-}
-
-shared_ptr<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId) {
- lock_guard<mutex> lock(mLock);
- auto subscriberMapIt = mIntentMap.find(configKey);
- if (subscriberMapIt == mIntentMap.end()) {
- return nullptr;
- }
- auto pirMapIt = subscriberMapIt->second.find(subscriberId);
- if (pirMapIt == subscriberMapIt->second.end()) {
- return nullptr;
- }
- return pirMapIt->second;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
deleted file mode 100644
index 4fe428198e71..000000000000
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // subscription
-#include "HashableDimensionKey.h"
-
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-using aidl::android::os::IPendingIntentRef;
-using std::mutex;
-using std::shared_ptr;
-using std::string;
-using std::unordered_map;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Reports information to subscribers.
-// Single instance shared across the process. All methods are thread safe.
-class SubscriberReporter {
-public:
- /** Get (singleton) instance of SubscriberReporter. */
- static SubscriberReporter& getInstance() {
- static SubscriberReporter subscriberReporter;
- return subscriberReporter;
- }
-
- ~SubscriberReporter(){};
- SubscriberReporter(SubscriberReporter const&) = delete;
- void operator=(SubscriberReporter const&) = delete;
-
- /**
- * Stores the given intentSender, associating it with the given (configKey, subscriberId) pair.
- */
- void setBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId,
- const shared_ptr<IPendingIntentRef>& pir);
-
- /**
- * Erases any intentSender information from the given (configKey, subscriberId) pair.
- */
- void unsetBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId);
-
- /**
- * Sends a broadcast via the intentSender previously stored for the
- * given (configKey, subscriberId) pair by setBroadcastSubscriber.
- * Information about the subscriber, as well as information extracted from the dimKey, is sent.
- */
- void alertBroadcastSubscriber(const ConfigKey& configKey,
- const Subscription& subscription,
- const MetricDimensionKey& dimKey) const;
-
- shared_ptr<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey,
- int64_t subscriberId);
-
-private:
- SubscriberReporter();
-
- mutable mutex mLock;
-
- /** Maps <ConfigKey, SubscriberId> -> IPendingIntentRef (which represents a PendingIntent). */
- unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>> mIntentMap;
-
- /**
- * Sends a broadcast via the given intentSender (using mStatsCompanionService), along
- * with the information in the other parameters.
- */
- void sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
- const ConfigKey& configKey,
- const Subscription& subscription,
- const vector<string>& cookies,
- const MetricDimensionKey& dimKey) const;
-
- ::ndk::ScopedAIBinder_DeathRecipient mBroadcastSubscriberDeathRecipient;
-
- /**
- * Death recipient callback that is called when a broadcast subscriber dies.
- * The cookie is a pointer to a BroadcastSubscriberDeathCookie.
- */
- static void broadcastSubscriberDied(void* cookie);
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/uid_data.proto b/cmds/statsd/src/uid_data.proto
deleted file mode 100644
index a6fa26cd412e..000000000000
--- a/cmds/statsd/src/uid_data.proto
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "UidDataProto";
-
-message ApplicationInfo {
- optional int32 uid = 1;
- optional int64 version = 2;
- optional string version_string = 3;
- optional string package_name = 4;
- optional string installer = 5;
-}
-
-// StatsServiceCompanion uses the proto to supply statsd with uid-package
-// mapping updates.
-message UidData {
- repeated ApplicationInfo app_info = 1;
-}
diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.cpp b/cmds/statsd/src/utils/MultiConditionTrigger.cpp
deleted file mode 100644
index 43a69337f368..000000000000
--- a/cmds/statsd/src/utils/MultiConditionTrigger.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-
-#include "MultiConditionTrigger.h"
-
-#include <thread>
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames,
- function<void()> trigger)
- : mRemainingConditionNames(conditionNames),
- mTrigger(trigger),
- mCompleted(mRemainingConditionNames.empty()) {
- if (mCompleted) {
- thread executorThread([this] { mTrigger(); });
- executorThread.detach();
- }
-}
-
-void MultiConditionTrigger::markComplete(const string& conditionName) {
- bool doTrigger = false;
- {
- lock_guard<mutex> lg(mMutex);
- if (mCompleted) {
- return;
- }
- mRemainingConditionNames.erase(conditionName);
- mCompleted = mRemainingConditionNames.empty();
- doTrigger = mCompleted;
- }
- if (doTrigger) {
- std::thread executorThread([this] { mTrigger(); });
- executorThread.detach();
- }
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.h b/cmds/statsd/src/utils/MultiConditionTrigger.h
deleted file mode 100644
index 51f6029915be..000000000000
--- a/cmds/statsd/src/utils/MultiConditionTrigger.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-#include <mutex>
-#include <set>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * This class provides a utility to wait for a set of named conditions to occur.
- *
- * It will execute the trigger runnable in a detached thread once all conditions have been marked
- * true.
- */
-class MultiConditionTrigger {
-public:
- explicit MultiConditionTrigger(const std::set<std::string>& conditionNames,
- std::function<void()> trigger);
-
- MultiConditionTrigger(const MultiConditionTrigger&) = delete;
- MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
-
- // Mark a specific condition as true. If this condition has called markComplete already or if
- // the event was not specified in the constructor, the function is a no-op.
- void markComplete(const std::string& eventName);
-
-private:
- mutable std::mutex mMutex;
- std::set<std::string> mRemainingConditionNames;
- std::function<void()> mTrigger;
- bool mCompleted;
-
- FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
-};
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/statsd_test.xml b/cmds/statsd/statsd_test.xml
deleted file mode 100644
index 8f9bb1cb6b2a..000000000000
--- a/cmds/statsd/statsd_test.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Runs statsd_test.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-native" />
- <option name="test-suite-tag" value="mts" />
-
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
- <option name="cleanup" value="true" />
- <option name="push" value="statsd_test->/data/local/tmp/statsd_test" />
- <option name="append-bitness" value="true" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="statsd_test" />
- </test>
-
- <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
- <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
- </object>
-</configuration>
diff --git a/cmds/statsd/tests/AlarmMonitor_test.cpp b/cmds/statsd/tests/AlarmMonitor_test.cpp
deleted file mode 100644
index 1dc9795dcf16..000000000000
--- a/cmds/statsd/tests/AlarmMonitor_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "anomaly/AlarmMonitor.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-using std::shared_ptr;
-
-#ifdef __ANDROID__
-TEST(AlarmMonitor, popSoonerThan) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> set;
- AlarmMonitor am(2,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
-
- set = am.popSoonerThan(5);
- EXPECT_TRUE(set.empty());
-
- sp<const InternalAlarm> a = new InternalAlarm{10};
- sp<const InternalAlarm> b = new InternalAlarm{20};
- sp<const InternalAlarm> c = new InternalAlarm{20};
- sp<const InternalAlarm> d = new InternalAlarm{30};
- sp<const InternalAlarm> e = new InternalAlarm{40};
- sp<const InternalAlarm> f = new InternalAlarm{50};
-
- am.add(a);
- am.add(b);
- am.add(c);
- am.add(d);
- am.add(e);
- am.add(f);
-
- set = am.popSoonerThan(5);
- EXPECT_TRUE(set.empty());
-
- set = am.popSoonerThan(30);
- ASSERT_EQ(4u, set.size());
- EXPECT_EQ(1u, set.count(a));
- EXPECT_EQ(1u, set.count(b));
- EXPECT_EQ(1u, set.count(c));
- EXPECT_EQ(1u, set.count(d));
-
- set = am.popSoonerThan(60);
- ASSERT_EQ(2u, set.size());
- EXPECT_EQ(1u, set.count(e));
- EXPECT_EQ(1u, set.count(f));
-
- set = am.popSoonerThan(80);
- ASSERT_EQ(0u, set.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
deleted file mode 100644
index 9455304a1af6..000000000000
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/config/ConfigManager.h"
-#include "src/metrics/MetricsManager.h"
-#include "statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-#include <iostream>
-
-using namespace android;
-using namespace android::os::statsd;
-using namespace testing;
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static ostream& operator<<(ostream& os, const StatsdConfig& config) {
- return os << "StatsdConfig{id=" << config.id() << "}";
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-/**
- * Mock ConfigListener
- */
-class MockListener : public ConfigListener {
-public:
- MOCK_METHOD3(OnConfigUpdated, void(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config));
- MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key));
-};
-
-/**
- * Validate that the ConfigKey is the one we wanted.
- */
-MATCHER_P2(ConfigKeyEq, uid, id, "") {
- return arg.GetUid() == uid && (long long)arg.GetId() == (long long)id;
-}
-
-/**
- * Validate that the StatsdConfig is the one we wanted.
- */
-MATCHER_P(StatsdConfigEq, id, 0) {
- return (long long)arg.id() == (long long)id;
-}
-
-const int64_t testConfigId = 12345;
-
-/**
- * Test the addOrUpdate and remove methods
- */
-TEST(ConfigManagerTest, TestAddUpdateRemove) {
- sp<MockListener> listener = new StrictMock<MockListener>();
-
- sp<ConfigManager> manager = new ConfigManager();
- manager->AddListener(listener);
-
- StatsdConfig config91;
- config91.set_id(91);
- StatsdConfig config92;
- config92.set_id(92);
- StatsdConfig config93;
- config93.set_id(93);
- StatsdConfig config94;
- config94.set_id(94);
-
- {
- InSequence s;
-
- manager->StartupForTest();
-
- // Add another one
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
- StatsdConfigEq(91)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config91);
-
- // Update It
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
- StatsdConfigEq(92)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config92);
-
- // Add one with the same uid but a different name
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")),
- StatsdConfigEq(93)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(1, StringToId("yyy")), config93);
-
- // Add one with the same name but a different uid
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")),
- StatsdConfigEq(94)))
- .RetiresOnSaturation();
- manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config94);
-
- // Remove (1,yyy)
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, StringToId("yyy"))))
- .RetiresOnSaturation();
- manager->RemoveConfig(ConfigKey(1, StringToId("yyy")));
-
- // Remove (2,zzz)
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))))
- .RetiresOnSaturation();
- manager->RemoveConfig(ConfigKey(2, StringToId("zzz")));
-
- // Remove (1,zzz)
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, StringToId("zzz"))))
- .RetiresOnSaturation();
- manager->RemoveConfig(ConfigKey(1, StringToId("zzz")));
-
- // Remove (2,zzz) again and we shouldn't get the callback
- manager->RemoveConfig(ConfigKey(2, StringToId("zzz")));
- }
-}
-
-/**
- * Test removing all of the configs for a uid.
- */
-TEST(ConfigManagerTest, TestRemoveUid) {
- sp<MockListener> listener = new StrictMock<MockListener>();
-
- sp<ConfigManager> manager = new ConfigManager();
- manager->AddListener(listener);
-
- StatsdConfig config;
-
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _)).Times(5);
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("xxx"))));
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("yyy"))));
- EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))));
-
- manager->StartupForTest();
- manager->UpdateConfig(ConfigKey(1, StringToId("aaa")), config);
- manager->UpdateConfig(ConfigKey(2, StringToId("xxx")), config);
- manager->UpdateConfig(ConfigKey(2, StringToId("yyy")), config);
- manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config);
- manager->UpdateConfig(ConfigKey(3, StringToId("bbb")), config);
-
- manager->RemoveConfigs(2);
-}
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
deleted file mode 100644
index a21eb9b9147f..000000000000
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "src/logd/LogEvent.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "subscriber/SubscriberReporter.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-using android::util::ProtoReader;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// These constants must be kept in sync with those in StatsDimensionsValue.java.
-const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
-const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
-const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
-const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
-
-namespace {
-void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const string& name) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const int32_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeInt32(statsEvent, value);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-} // anonymous namespace
-
-TEST(AtomMatcherTest, TestFieldTranslation) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ANY);
-
- child = child->add_child();
- child->set_field(1);
-
- vector<Matcher> output;
- translateFieldMatcher(matcher1, &output);
-
- ASSERT_EQ((size_t)1, output.size());
-
- const auto& matcher12 = output[0];
- EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
- EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
-}
-
-TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
-
- child = child->add_child();
- child->set_field(1);
-
- vector<Matcher> output;
- translateFieldMatcher(matcher1, &output);
-
- ASSERT_EQ((size_t)1, output.size());
-
- const auto& matcher12 = output[0];
- EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
- EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
-}
-
-TEST(AtomMatcherTest, TestFilter_ALL) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
-
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
-
- child = matcher1.add_child();
- child->set_field(2);
-
- vector<Matcher> matchers;
- translateFieldMatcher(matcher1, &matchers);
-
- std::vector<int> attributionUids = {1111, 2222, 3333};
- std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
- HashableDimensionKey output;
-
- filterValues(matchers, event.getValues(), &output);
-
- ASSERT_EQ((size_t)7, output.getValues().size());
- EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
- EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
- EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
- EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
-
- EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
- EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
- EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
- EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
-
- EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
- EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
- EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
- EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
-
- EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
- EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
-}
-
-TEST(AtomMatcherTest, TestSubDimension) {
- HashableDimensionKey dim;
-
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
-
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
-
- Value value11((int32_t)10026);
- Value value22("tag2");
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
-
- HashableDimensionKey subDim1;
- subDim1.addValue(FieldValue(field1, value1));
-
- HashableDimensionKey subDim2;
- subDim1.addValue(FieldValue(field2, value2));
-
- EXPECT_TRUE(dim.contains(dim));
- EXPECT_TRUE(dim.contains(subDim1));
- EXPECT_TRUE(dim.contains(subDim2));
-
- HashableDimensionKey subDim3;
- subDim3.addValue(FieldValue(field1, value11));
- EXPECT_FALSE(dim.contains(subDim3));
-
- HashableDimensionKey subDim4;
- // Empty dimension is always a sub dimension of other dimensions
- EXPECT_TRUE(dim.contains(subDim4));
-}
-
-TEST(AtomMatcherTest, TestMetric2ConditionLink) {
- std::vector<int> attributionUids = {1111, 2222, 3333};
- std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
-
- FieldMatcher whatMatcher;
- whatMatcher.set_field(10);
- FieldMatcher* child11 = whatMatcher.add_child();
- child11->set_field(1);
- child11->set_position(Position::ANY);
- child11 = child11->add_child();
- child11->set_field(1);
-
- FieldMatcher conditionMatcher;
- conditionMatcher.set_field(27);
- FieldMatcher* child2 = conditionMatcher.add_child();
- child2->set_field(2);
- child2->set_position(Position::LAST);
-
- child2 = child2->add_child();
- child2->set_field(2);
-
- Metric2Condition link;
-
- translateFieldMatcher(whatMatcher, &link.metricFields);
- translateFieldMatcher(conditionMatcher, &link.conditionFields);
-
- ASSERT_EQ((size_t)1, link.metricFields.size());
- EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
- EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
-
- ASSERT_EQ((size_t)1, link.conditionFields.size());
- EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
- EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
- EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionPath) {
- for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
- FieldMatcher matcher1;
- matcher1.set_field(10);
- FieldMatcher* child = matcher1.add_child();
- child->set_field(2);
- child->set_position(position);
- child->add_child()->set_field(1);
- child->add_child()->set_field(3);
-
- child = matcher1.add_child();
- child->set_field(4);
-
- child = matcher1.add_child();
- child->set_field(6);
- child->add_child()->set_field(2);
-
- vector<Matcher> matchers;
- translateFieldMatcher(matcher1, &matchers);
-
- android::util::ProtoOutputStream protoOut;
- writeDimensionPathToProto(matchers, &protoOut);
-
- vector<uint8_t> outData;
- outData.resize(protoOut.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOut.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- DimensionsValue result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-
- EXPECT_EQ(10, result.field());
- EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
- ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
-
- const auto& dim1 = result.value_tuple().dimensions_value(0);
- EXPECT_EQ(2, dim1.field());
- ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
-
- const auto& dim11 = dim1.value_tuple().dimensions_value(0);
- EXPECT_EQ(1, dim11.field());
-
- const auto& dim12 = dim1.value_tuple().dimensions_value(1);
- EXPECT_EQ(3, dim12.field());
-
- const auto& dim2 = result.value_tuple().dimensions_value(1);
- EXPECT_EQ(4, dim2.field());
-
- const auto& dim3 = result.value_tuple().dimensions_value(2);
- EXPECT_EQ(6, dim3.field());
- ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
- const auto& dim31 = dim3.value_tuple().dimensions_value(0);
- EXPECT_EQ(2, dim31.field());
- }
-}
-
-void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
- int32_t nodeDepthInAttributionChain,
- int32_t uid, string tag) {
- EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
- ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
- ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
-
- StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
- EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
- EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
- EXPECT_EQ(uidParcel.intValue, uid);
-
- StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
- EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
- EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
- EXPECT_EQ(tagParcel.stringValue, tag);
-}
-
-// Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
-TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
- int atomId = 10;
- // First four fields form an attribution chain
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 2, 1};
- int pos4[] = {1, 2, 2};
- int pos5[] = {2, 1, 1};
-
- Field field1(atomId, pos1, /*depth=*/2);
- Field field2(atomId, pos2, /*depth=*/2);
- Field field3(atomId, pos3, /*depth=*/2);
- Field field4(atomId, pos4, /*depth=*/2);
- Field field5(atomId, pos5, /*depth=*/0);
-
- Value value1((int32_t)1);
- Value value2("string2");
- Value value3((int32_t)3);
- Value value4("string4");
- Value value5((float)5.0);
-
- HashableDimensionKey dimensionKey;
- dimensionKey.addValue(FieldValue(field1, value1));
- dimensionKey.addValue(FieldValue(field2, value2));
- dimensionKey.addValue(FieldValue(field3, value3));
- dimensionKey.addValue(FieldValue(field4, value4));
- dimensionKey.addValue(FieldValue(field5, value5));
-
- StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
- EXPECT_EQ(rootParcel.field, atomId);
- ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
- ASSERT_EQ(rootParcel.tupleValue.size(), 2);
-
- // Check that attribution chain is populated correctly
- StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
- EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
- ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
- ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
- checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
- /*nodeDepthInAttributionChain=*/1,
- value1.int_value, value2.str_value);
- checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
- /*nodeDepthInAttributionChain=*/2,
- value3.int_value, value4.str_value);
-
- // Check that the float is populated correctly
- StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
- EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
- EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
- EXPECT_EQ(floatParcel.floatValue, value5.float_value);
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionToProto) {
- HashableDimensionKey dim;
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int32_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- android::util::ProtoOutputStream protoOut;
- writeDimensionToProto(dim, nullptr /* include strings */, &protoOut);
-
- vector<uint8_t> outData;
- outData.resize(protoOut.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOut.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- DimensionsValue result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
- EXPECT_EQ(10, result.field());
- EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
- ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
-
- const auto& dim1 = result.value_tuple().dimensions_value(0);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
- ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
-
- const auto& dim11 = dim1.value_tuple().dimensions_value(0);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
- EXPECT_EQ(10025, dim11.value_int());
-
- const auto& dim12 = dim1.value_tuple().dimensions_value(1);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
- EXPECT_EQ("tag", dim12.value_str());
-
- const auto& dim13 = dim1.value_tuple().dimensions_value(2);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
- EXPECT_EQ(987654, dim13.value_int());
-
- const auto& dim2 = result.value_tuple().dimensions_value(1);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
- EXPECT_EQ(99999, dim2.value_int());
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
- HashableDimensionKey dim;
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int64_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- android::util::ProtoOutputStream protoOut;
- writeDimensionLeafNodesToProto(dim, 1, nullptr /* include strings */, &protoOut);
-
- vector<uint8_t> outData;
- outData.resize(protoOut.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOut.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- DimensionsValueTuple result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
- ASSERT_EQ(4, result.dimensions_value_size());
-
- const auto& dim1 = result.dimensions_value(0);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
- EXPECT_EQ(10025, dim1.value_int());
-
- const auto& dim2 = result.dimensions_value(1);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
- EXPECT_EQ("tag", dim2.value_str());
-
- const auto& dim3 = result.dimensions_value(2);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
- EXPECT_EQ(987654, dim3.value_int());
-
- const auto& dim4 = result.dimensions_value(3);
- EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
- EXPECT_EQ(99999, dim4.value_long());
-}
-
-TEST(AtomMatcherTest, TestWriteAtomToProto) {
- std::vector<int> attributionUids = {1111, 2222};
- std::vector<string> attributionTags = {"location1", "location2"};
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
-
- android::util::ProtoOutputStream protoOutput;
- writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
-
- vector<uint8_t> outData;
- outData.resize(protoOutput.size());
- size_t pos = 0;
- sp<ProtoReader> reader = protoOutput.data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- Atom result;
- ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
- EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
- const auto& atom = result.ble_scan_result_received();
- ASSERT_EQ(2, atom.attribution_node_size());
- EXPECT_EQ(1111, atom.attribution_node(0).uid());
- EXPECT_EQ("location1", atom.attribution_node(0).tag());
- EXPECT_EQ(2222, atom.attribution_node(1).uid());
- EXPECT_EQ("location2", atom.attribution_node(1).tag());
- EXPECT_EQ(999, atom.num_results());
-}
-
-/*
- * Test two Matchers is not a subset of one Matcher.
- * Test one Matcher is subset of two Matchers.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions1) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
- ASSERT_EQ(2, matchers1.size());
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(10);
-
- child = matcher2.add_child();
- child->set_field(1);
- child->set_position(Position::ALL);
- child->add_child()->set_field(1);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
- ASSERT_EQ(1, matchers2.size());
-
- EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
- EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
-}
-/*
- * Test not a subset with one matching Matcher, one non-matching Matcher.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions2) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
-
- child = matcher1.add_child();
- child->set_field(2);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(10);
-
- child = matcher2.add_child();
- child->set_field(1);
-
- child = matcher2.add_child();
- child->set_field(3);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
-
- EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-}
-
-/*
- * Test not a subset if parent field is not equal.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions3) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(5);
-
- child = matcher2.add_child();
- child->set_field(1);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
-
- EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-}
-
-/*
- * Test is subset with two matching Matchers.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions4) {
- // Initialize first set of matchers
- FieldMatcher matcher1;
- matcher1.set_field(10);
-
- FieldMatcher* child = matcher1.add_child();
- child->set_field(1);
-
- child = matcher1.add_child();
- child->set_field(2);
-
- vector<Matcher> matchers1;
- translateFieldMatcher(matcher1, &matchers1);
-
- // Initialize second set of matchers
- FieldMatcher matcher2;
- matcher2.set_field(10);
-
- child = matcher2.add_child();
- child->set_field(1);
-
- child = matcher2.add_child();
- child->set_field(2);
-
- child = matcher2.add_child();
- child->set_field(3);
-
- vector<Matcher> matchers2;
- translateFieldMatcher(matcher2, &matchers2);
-
- EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
- EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/HashableDimensionKey_test.cpp b/cmds/statsd/tests/HashableDimensionKey_test.cpp
deleted file mode 100644
index 29adcd08a7b8..000000000000
--- a/cmds/statsd/tests/HashableDimensionKey_test.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "src/HashableDimensionKey.h"
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-using android::util::ProtoReader;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Test that #containsLinkedStateValues returns false when the whatKey is
- * smaller than the primaryKey.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_WhatKeyTooSmall) {
- std::vector<Metric2State> mMetric2StateLinks;
-
- int32_t uid1 = 1000;
- HashableDimensionKey whatKey = DEFAULT_DIMENSION_KEY;
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks,
- UID_PROCESS_STATE_ATOM_ID));
-}
-
-/**
- * Test that #containsLinkedStateValues returns false when the linked values
- * are not equal.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_UnequalLinkedValues) {
- int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
- FieldMatcher whatMatcher;
- whatMatcher.set_field(util::OVERLAY_STATE_CHANGED);
- FieldMatcher* child11 = whatMatcher.add_child();
- child11->set_field(1);
-
- FieldMatcher stateMatcher;
- stateMatcher.set_field(stateAtomId);
- FieldMatcher* child21 = stateMatcher.add_child();
- child21->set_field(1);
-
- std::vector<Metric2State> mMetric2StateLinks;
- Metric2State ms;
- ms.stateAtomId = stateAtomId;
- translateFieldMatcher(whatMatcher, &ms.metricFields);
- translateFieldMatcher(stateMatcher, &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
-
- int32_t uid1 = 1000;
- int32_t uid2 = 1001;
- HashableDimensionKey whatKey;
- getOverlayKey(uid2, "package", &whatKey);
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-/**
- * Test that #containsLinkedStateValues returns false when there is no link
- * between the key values.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_MissingMetric2StateLinks) {
- int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
- std::vector<Metric2State> mMetric2StateLinks;
-
- int32_t uid1 = 1000;
- HashableDimensionKey whatKey;
- getOverlayKey(uid1, "package", &whatKey);
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-/**
- * Test that #containsLinkedStateValues returns true when the key values are
- * linked and equal.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_AllConditionsMet) {
- int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
- FieldMatcher whatMatcher;
- whatMatcher.set_field(util::OVERLAY_STATE_CHANGED);
- FieldMatcher* child11 = whatMatcher.add_child();
- child11->set_field(1);
-
- FieldMatcher stateMatcher;
- stateMatcher.set_field(stateAtomId);
- FieldMatcher* child21 = stateMatcher.add_child();
- child21->set_field(1);
-
- std::vector<Metric2State> mMetric2StateLinks;
- Metric2State ms;
- ms.stateAtomId = stateAtomId;
- translateFieldMatcher(whatMatcher, &ms.metricFields);
- translateFieldMatcher(stateMatcher, &ms.stateFields);
- mMetric2StateLinks.push_back(ms);
-
- int32_t uid1 = 1000;
- HashableDimensionKey whatKey;
- getOverlayKey(uid1, "package", &whatKey);
- HashableDimensionKey primaryKey;
- getUidProcessKey(uid1, &primaryKey);
-
- EXPECT_TRUE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
deleted file mode 100644
index 6264c075426a..000000000000
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "annotations.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statsd_test_util.h"
-
-using namespace android::os::statsd;
-using std::unordered_map;
-using std::vector;
-
-const int32_t TAG_ID = 123;
-const int32_t TAG_ID_2 = 28; // hardcoded tag of atom with uid field
-const int FIELD_ID_1 = 1;
-const int FIELD_ID_2 = 2;
-const int FIELD_ID_3 = 2;
-
-const int ATTRIBUTION_UID_FIELD_ID = 1;
-const int ATTRIBUTION_TAG_FIELD_ID = 2;
-
-
-#ifdef __ANDROID__
-
-namespace {
-
-void makeIntLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const int32_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
- AStatsEvent_writeInt32(statsEvent, value);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const float floatValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
- AStatsEvent_writeFloat(statsEvent, floatValue);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const string& name) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
- AStatsEvent_writeString(statsEvent, name.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeIntWithBoolAnnotationLogEvent(LogEvent* logEvent, const int32_t atomId,
- const int32_t field, const uint8_t annotationId,
- const bool annotationValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_writeInt32(statsEvent, field);
- AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags, const string& name) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
- const bool bool1, const bool bool2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- AStatsEvent_writeBool(statsEvent, bool1);
- AStatsEvent_writeBool(statsEvent, bool2);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // anonymous namespace
-
-TEST(AtomMatcherTest, TestSimpleMatcher) {
- UidMap uidMap;
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeIntLogEvent(&event, TAG_ID, 0, 11);
-
- // Test
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Wrong tag id.
- simpleMatcher->set_atom_id(TAG_ID + 1);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestAttributionMatcher) {
- UidMap uidMap;
- std::vector<int> attributionUids = {1111, 2222, 3333};
- std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
- // Set up the log event.
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- // Match first node.
- auto attributionMatcher = simpleMatcher->add_field_value_matcher();
- attributionMatcher->set_field(FIELD_ID_1);
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_TAG_FIELD_ID);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "tag");
-
- auto fieldMatcher = simpleMatcher->add_field_value_matcher();
- fieldMatcher->set_field(FIELD_ID_2);
- fieldMatcher->set_eq_string("some value");
-
- // Tag not matched.
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Match last node.
- attributionMatcher->set_position(Position::LAST);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Match any node.
- attributionMatcher->set_position(Position::ANY);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location4");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Attribution match but primitive field not match.
- attributionMatcher->set_position(Position::ANY);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "location2");
- fieldMatcher->set_eq_string("wrong value");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- fieldMatcher->set_eq_string("some value");
-
- // Uid match.
- attributionMatcher->set_position(Position::ANY);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::LAST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // Uid + tag.
- attributionMatcher->set_position(Position::ANY);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_TAG_FIELD_ID);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location2");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::LAST);
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg0");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg1");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg2");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
- "pkg3");
- attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
- "location1");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestUidFieldMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- // Set up matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- simpleMatcher->add_field_value_matcher()->set_field(1);
- simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0");
-
- // Make event without is_uid annotation.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeIntLogEvent(&event1, TAG_ID, 0, 1111);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
- // Make event with is_uid annotation.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID_2, 1111, ANNOTATION_ID_IS_UID, true);
-
- // Event has is_uid annotation, so mapping from uid to package name occurs.
- simpleMatcher->set_atom_id(TAG_ID_2);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
- // Event has is_uid annotation, but uid maps to different package name.
- simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-}
-
-TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- std::vector<int> attributionUids = {1111, 2222, 3333, 1066};
- std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"};
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- // Match first node.
- auto attributionMatcher = simpleMatcher->add_field_value_matcher();
- attributionMatcher->set_field(FIELD_ID_1);
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- auto neqStringList = attributionMatcher->mutable_matches_tuple()
- ->mutable_field_value_matcher(0)
- ->mutable_neq_any_string();
- neqStringList->add_str_value("pkg2");
- neqStringList->add_str_value("pkg3");
-
- auto fieldMatcher = simpleMatcher->add_field_value_matcher();
- fieldMatcher->set_field(FIELD_ID_2);
- fieldMatcher->set_eq_string("some value");
-
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- neqStringList->Clear();
- neqStringList->add_str_value("pkg1");
- neqStringList->add_str_value("pkg3");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::ANY);
- neqStringList->Clear();
- neqStringList->add_str_value("maps.com");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- neqStringList->Clear();
- neqStringList->add_str_value("PkG3");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::LAST);
- neqStringList->Clear();
- neqStringList->add_str_value("AID_STATSD");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestEqAnyStringMatcher) {
- UidMap uidMap;
- uidMap.updateMap(
- 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
- {android::String16("v1"), android::String16("v1"), android::String16("v2"),
- android::String16("v1"), android::String16("v2")},
- {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
- android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
- {android::String16(""), android::String16(""), android::String16(""),
- android::String16(""), android::String16("")});
-
- std::vector<int> attributionUids = {1067, 2222, 3333, 1066};
- std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"};
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- // Match first node.
- auto attributionMatcher = simpleMatcher->add_field_value_matcher();
- attributionMatcher->set_field(FIELD_ID_1);
- attributionMatcher->set_position(Position::FIRST);
- attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- auto eqStringList = attributionMatcher->mutable_matches_tuple()
- ->mutable_field_value_matcher(0)
- ->mutable_eq_any_string();
- eqStringList->add_str_value("AID_ROOT");
- eqStringList->add_str_value("AID_INCIDENTD");
-
- auto fieldMatcher = simpleMatcher->add_field_value_matcher();
- fieldMatcher->set_field(FIELD_ID_2);
- fieldMatcher->set_eq_string("some value");
-
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- attributionMatcher->set_position(Position::ANY);
- eqStringList->Clear();
- eqStringList->add_str_value("AID_STATSD");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- eqStringList->Clear();
- eqStringList->add_str_value("pkg1");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- auto normalStringField = fieldMatcher->mutable_eq_any_string();
- normalStringField->add_str_value("some value123");
- normalStringField->add_str_value("some value");
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- normalStringField->Clear();
- normalStringField->add_str_value("AID_STATSD");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- eqStringList->Clear();
- eqStringList->add_str_value("maps.com");
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestBoolMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue1 = simpleMatcher->add_field_value_matcher();
- keyValue1->set_field(FIELD_ID_1);
- auto keyValue2 = simpleMatcher->add_field_value_matcher();
- keyValue2->set_field(FIELD_ID_2);
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeBoolLogEvent(&event, TAG_ID, 0, true, false);
-
- // Test
- keyValue1->set_eq_bool(true);
- keyValue2->set_eq_bool(false);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_bool(false);
- keyValue2->set_eq_bool(false);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_bool(false);
- keyValue2->set_eq_bool(true);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_bool(true);
- keyValue2->set_eq_bool(true);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestStringMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(FIELD_ID_1);
- keyValue->set_eq_string("some value");
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeStringLogEvent(&event, TAG_ID, 0, "some value");
-
- // Test
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestMultiFieldsMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue1 = simpleMatcher->add_field_value_matcher();
- keyValue1->set_field(FIELD_ID_1);
- auto keyValue2 = simpleMatcher->add_field_value_matcher();
- keyValue2->set_field(FIELD_ID_2);
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event, TAG_ID, 0, 2, 3);
-
- // Test
- keyValue1->set_eq_int(2);
- keyValue2->set_eq_int(3);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_int(2);
- keyValue2->set_eq_int(4);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- keyValue1->set_eq_int(4);
- keyValue2->set_eq_int(3);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestIntComparisonMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-
- simpleMatcher->set_atom_id(TAG_ID);
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(FIELD_ID_1);
-
- // Set up the event
- LogEvent event(/*uid=*/0, /*pid=*/0);
- makeIntLogEvent(&event, TAG_ID, 0, 11);
-
- // Test
-
- // eq_int
- keyValue->set_eq_int(10);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_eq_int(11);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_eq_int(12);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // lt_int
- keyValue->set_lt_int(10);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lt_int(11);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lt_int(12);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // lte_int
- keyValue->set_lte_int(10);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lte_int(11);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_lte_int(12);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // gt_int
- keyValue->set_gt_int(10);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gt_int(11);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gt_int(12);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
- // gte_int
- keyValue->set_gte_int(10);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gte_int(11);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
- keyValue->set_gte_int(12);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestFloatComparisonMatcher) {
- UidMap uidMap;
- // Set up the matcher
- AtomMatcher matcher;
- auto simpleMatcher = matcher.mutable_simple_atom_matcher();
- simpleMatcher->set_atom_id(TAG_ID);
-
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(FIELD_ID_1);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event1, TAG_ID, 0, 10.1f);
- keyValue->set_lt_float(10.0);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event2, TAG_ID, 0, 9.9f);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event3, TAG_ID, 0, 10.1f);
- keyValue->set_gt_float(10.0);
- EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3));
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeFloatLogEvent(&event4, TAG_ID, 0, 9.9f);
- EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4));
-}
-
-// Helper for the composite matchers.
-void addSimpleMatcher(SimpleAtomMatcher* simpleMatcher, int tag, int key, int val) {
- simpleMatcher->set_atom_id(tag);
- auto keyValue = simpleMatcher->add_field_value_matcher();
- keyValue->set_field(key);
- keyValue->set_eq_int(val);
-}
-
-TEST(AtomMatcherTest, TestAndMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::AND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestOrMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::OR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNotMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOT;
-
- vector<int> children;
- children.push_back(0);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNandMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NAND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
-
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNorMatcher) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<MatchingState> matcherResults;
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
-
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kNotMatched);
- matcherResults.push_back(MatchingState::kNotMatched);
- EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
- matcherResults.clear();
- matcherResults.push_back(MatchingState::kMatched);
- matcherResults.push_back(MatchingState::kMatched);
- EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
deleted file mode 100644
index 5c170c07eb7d..000000000000
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/logd/LogEvent.h"
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h"
-#include "log/log_event_list.h"
-#include "stats_event.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::string;
-using std::vector;
-using util::ProtoOutputStream;
-using util::ProtoReader;
-
-namespace {
-
-Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) {
- Field f(tag, (int32_t*)pos.data(), depth);
-
- // For loop starts at 1 because the last field at depth 0 is not decorated.
- for (int i = 1; i < depth; i++) {
- if (last[i]) f.decorateLastPos(i);
- }
-
- return f;
-}
-
-void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
- bool annotationValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
- AStatsEvent_writeInt32(statsEvent, 10);
- AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- EXPECT_TRUE(logEvent->parseBuffer(buf, size));
-
- AStatsEvent_release(statsEvent);
-}
-
-void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
- int annotationValue) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
- AStatsEvent_writeInt32(statsEvent, 10);
- AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue);
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- EXPECT_TRUE(logEvent->parseBuffer(buf, size));
-
- AStatsEvent_release(statsEvent);
-}
-
-} // anonymous namespace
-
-TEST(LogEventTest, TestPrimitiveParsing) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- AStatsEvent_writeInt32(event, 10);
- AStatsEvent_writeInt64(event, 0x123456789);
- AStatsEvent_writeFloat(event, 2.0);
- AStatsEvent_writeBool(event, true);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
- EXPECT_FALSE(logEvent.hasAttributionChain());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(4, values.size());
-
- const FieldValue& int32Item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, int32Item.mField);
- EXPECT_EQ(Type::INT, int32Item.mValue.getType());
- EXPECT_EQ(10, int32Item.mValue.int_value);
-
- const FieldValue& int64Item = values[1];
- expectedField = getField(100, {2, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, int64Item.mField);
- EXPECT_EQ(Type::LONG, int64Item.mValue.getType());
- EXPECT_EQ(0x123456789, int64Item.mValue.long_value);
-
- const FieldValue& floatItem = values[2];
- expectedField = getField(100, {3, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, floatItem.mField);
- EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType());
- EXPECT_EQ(2.0, floatItem.mValue.float_value);
-
- const FieldValue& boolItem = values[3];
- expectedField = getField(100, {4, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, boolItem.mField);
- EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type
- EXPECT_EQ(1, boolItem.mValue.int_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestStringAndByteArrayParsing) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- string str = "test";
- AStatsEvent_writeString(event, str.c_str());
- AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length());
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
- EXPECT_FALSE(logEvent.hasAttributionChain());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(2, values.size());
-
- const FieldValue& stringItem = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
- EXPECT_EQ(expectedField, stringItem.mField);
- EXPECT_EQ(Type::STRING, stringItem.mValue.getType());
- EXPECT_EQ(str, stringItem.mValue.str_value);
-
- const FieldValue& storageItem = values[1];
- expectedField = getField(100, {2, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, storageItem.mField);
- EXPECT_EQ(Type::STORAGE, storageItem.mValue.getType());
- vector<uint8_t> expectedValue = {'t', 'e', 's', 't'};
- EXPECT_EQ(expectedValue, storageItem.mValue.storage_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestEmptyString) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- string empty = "";
- AStatsEvent_writeString(event, empty.c_str());
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
- EXPECT_FALSE(logEvent.hasAttributionChain());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(1, values.size());
-
- const FieldValue& item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, item.mField);
- EXPECT_EQ(Type::STRING, item.mValue.getType());
- EXPECT_EQ(empty, item.mValue.str_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestByteArrayWithNullCharacter) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
- uint8_t message[] = {'\t', 'e', '\0', 's', 't'};
- AStatsEvent_writeByteArray(event, message, 5);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(1, values.size());
-
- const FieldValue& item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
- EXPECT_EQ(expectedField, item.mField);
- EXPECT_EQ(Type::STORAGE, item.mValue.getType());
- vector<uint8_t> expectedValue(message, message + 5);
- EXPECT_EQ(expectedValue, item.mValue.storage_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAttributionChain) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, 100);
-
- string tag1 = "tag1";
- string tag2 = "tag2";
-
- uint32_t uids[] = {1001, 1002};
- const char* tags[] = {tag1.c_str(), tag2.c_str()};
-
- AStatsEvent_writeAttributionChain(event, uids, tags, 2);
- AStatsEvent_build(event);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
- LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
- EXPECT_EQ(100, logEvent.GetTagId());
- EXPECT_EQ(1000, logEvent.GetUid());
- EXPECT_EQ(1001, logEvent.GetPid());
-
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(4, values.size()); // 2 per attribution node
-
- std::pair<int, int> attrIndexRange;
- EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
- EXPECT_EQ(0, attrIndexRange.first);
- EXPECT_EQ(3, attrIndexRange.second);
-
- // Check first attribution node
- const FieldValue& uid1Item = values[0];
- Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false});
- EXPECT_EQ(expectedField, uid1Item.mField);
- EXPECT_EQ(Type::INT, uid1Item.mValue.getType());
- EXPECT_EQ(1001, uid1Item.mValue.int_value);
-
- const FieldValue& tag1Item = values[1];
- expectedField = getField(100, {1, 1, 2}, 2, {true, false, true});
- EXPECT_EQ(expectedField, tag1Item.mField);
- EXPECT_EQ(Type::STRING, tag1Item.mValue.getType());
- EXPECT_EQ(tag1, tag1Item.mValue.str_value);
-
- // Check second attribution nodes
- const FieldValue& uid2Item = values[2];
- expectedField = getField(100, {1, 2, 1}, 2, {true, true, false});
- EXPECT_EQ(expectedField, uid2Item.mField);
- EXPECT_EQ(Type::INT, uid2Item.mValue.getType());
- EXPECT_EQ(1002, uid2Item.mValue.int_value);
-
- const FieldValue& tag2Item = values[3];
- expectedField = getField(100, {1, 2, 2}, 2, {true, true, true});
- EXPECT_EQ(expectedField, tag2Item.mField);
- EXPECT_EQ(Type::STRING, tag2Item.mValue.getType());
- EXPECT_EQ(tag2, tag2Item.mValue.str_value);
-
- AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_EQ(event.getUidFieldIndex(), 0);
-}
-
-TEST(LogEventTest, TestAnnotationIdStateNested) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_STATE_NESTED, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_TRUE(values[0].mAnnotations.isNested());
-}
-
-TEST(LogEventTest, TestPrimaryFieldAnnotation) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_TRUE(values[0].mAnnotations.isPrimaryField());
-}
-
-TEST(LogEventTest, TestExclusiveStateAnnotation) {
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_TRUE(values[0].mAnnotations.isExclusiveState());
-}
-
-TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) {
- // Event has 10 ints and then an attribution chain
- int numInts = 10;
- int firstUidInChainIndex = numInts;
- string tag1 = "tag1";
- string tag2 = "tag2";
- uint32_t uids[] = {1001, 1002};
- const char* tags[] = {tag1.c_str(), tag2.c_str()};
-
- // Construct AStatsEvent
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 100);
- for (int i = 0; i < numInts; i++) {
- AStatsEvent_writeInt32(statsEvent, 10);
- }
- AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
- AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
- AStatsEvent_build(statsEvent);
-
- // Construct LogEvent
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- LogEvent logEvent(/*uid=*/0, /*pid=*/0);
- EXPECT_TRUE(logEvent.parseBuffer(buf, size));
- AStatsEvent_release(statsEvent);
-
- // Check annotation
- const vector<FieldValue>& values = logEvent.getValues();
- ASSERT_EQ(values.size(), numInts + 4);
- EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField());
-}
-
-TEST(LogEventTest, TestResetStateAnnotation) {
- int32_t resetState = 10;
- LogEvent event(/*uid=*/0, /*pid=*/0);
- createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState);
-
- const vector<FieldValue>& values = event.getValues();
- ASSERT_EQ(values.size(), 1);
- EXPECT_EQ(event.getResetState(), resetState);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogReader_test.cpp b/cmds/statsd/tests/LogReader_test.cpp
deleted file mode 100644
index 7ce1d6a71c85..000000000000
--- a/cmds/statsd/tests/LogReader_test.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-TEST(LogReaderTest, TestNothingAtAll) {
- printf("yay!");
-}
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
deleted file mode 100644
index 6259757fe092..000000000000
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ /dev/null
@@ -1,799 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "metrics/metrics_test_helper.h"
-#include "src/condition/ConditionTracker.h"
-#include "src/matchers/LogMatchingTracker.h"
-#include "src/metrics/CountMetricProducer.h"
-#include "src/metrics/GaugeMetricProducer.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/metrics/ValueMetricProducer.h"
-#include "src/metrics/metrics_manager_util.h"
-#include "src/state/StateManager.h"
-#include "statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using android::os::statsd::Predicate;
-using std::map;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-const long kAlertId = 3;
-
-const long timeBaseSec = 1000;
-
-StatsdConfig buildGoodConfig() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- combination->add_matcher(StringToId("SCREEN_IS_OFF"));
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_IS_ON"));
- metric->set_bucket(ONE_MINUTE);
- metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- config.add_no_report_metric(3);
-
- auto alert = config.add_alert();
- alert->set_id(kAlertId);
- alert->set_metric_id(3);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildCircleMatchers() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- // Circle dependency
- combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
-
- return config;
-}
-
-StatsdConfig buildAlertWithUnknownMetric() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_IS_ON"));
- metric->set_bucket(ONE_MINUTE);
- metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- auto alert = config.add_alert();
- alert->set_id(3);
- alert->set_metric_id(2);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildMissingMatchers() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("SCREEN_IS_ON"));
- // undefined matcher
- combination->add_matcher(StringToId("ABC"));
-
- return config;
-}
-
-StatsdConfig buildMissingPredicate() {
- StatsdConfig config;
- config.set_id(12345);
-
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("SCREEN_EVENT"));
- metric->set_bucket(ONE_MINUTE);
- metric->set_condition(StringToId("SOME_CONDITION"));
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_EVENT"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2);
-
- return config;
-}
-
-StatsdConfig buildDimensionMetricsWithMultiTags() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(3);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("BATTERY_LOW"));
-
- AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
- combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
-
- // Count process state changes, slice by uid, while SCREEN_IS_OFF
- CountMetric* metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(StringToId("BATTERY_LOW"));
- metric->set_bucket(ONE_MINUTE);
- // This case is interesting. We want to dimension across two atoms.
- metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
- auto alert = config.add_alert();
- alert->set_id(kAlertId);
- alert->set_metric_id(3);
- alert->set_num_buckets(10);
- alert->set_refractory_period_secs(100);
- alert->set_trigger_if_sum_gt(100);
- return config;
-}
-
-StatsdConfig buildCirclePredicates() {
- StatsdConfig config;
- config.set_id(12345);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
- simpleAtomMatcher->add_field_value_matcher()->set_field(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
- simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
- 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
- auto condition = config.add_predicate();
- condition->set_id(StringToId("SCREEN_IS_ON"));
- SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
- simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
- simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
-
- condition = config.add_predicate();
- condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
- Predicate_Combination* combination = condition->mutable_combination();
- combination->set_operation(LogicalOperation::OR);
- combination->add_predicate(StringToId("SCREEN_IS_ON"));
- combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
- return config;
-}
-
-StatsdConfig buildConfigWithDifferentPredicates() {
- StatsdConfig config;
- config.set_id(12345);
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = screenOnAtomMatcher;
- auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOffAtomMatcher;
- auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = batteryNoneAtomMatcher;
- auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
- *config.add_atom_matcher() = batteryUsbAtomMatcher;
-
- // Simple condition with InitialValue set to default (unknown).
- auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnUnknownPredicate;
-
- // Simple condition with InitialValue set to false.
- auto screenOnFalsePredicate = config.add_predicate();
- screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
- SimplePredicate* simpleScreenOnFalsePredicate =
- screenOnFalsePredicate->mutable_simple_predicate();
- simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
- simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
- simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- // Simple condition with InitialValue set to false.
- auto onBatteryFalsePredicate = config.add_predicate();
- onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
- SimplePredicate* simpleOnBatteryFalsePredicate =
- onBatteryFalsePredicate->mutable_simple_predicate();
- simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
- simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
- simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- // Combination condition with both simple condition InitialValues set to false.
- auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
- screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
- screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
- LogicalOperation::AND);
- addPredicateToPredicateCombination(*screenOnFalsePredicate,
- screenOnFalseOnBatteryFalsePredicate);
- addPredicateToPredicateCombination(*onBatteryFalsePredicate,
- screenOnFalseOnBatteryFalsePredicate);
-
- // Combination condition with one simple condition InitialValue set to unknown and one set to
- // false.
- auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
- screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
- screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
- LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnUnknownPredicate,
- screenOnUnknownOnBatteryFalsePredicate);
- addPredicateToPredicateCombination(*onBatteryFalsePredicate,
- screenOnUnknownOnBatteryFalsePredicate);
-
- // Simple condition metric with initial value false.
- ValueMetric* metric1 = config.add_value_metric();
- metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
- metric1->set_what(pulledAtomMatcher.id());
- *metric1->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric1->set_bucket(FIVE_MINUTES);
- metric1->set_condition(screenOnFalsePredicate->id());
-
- // Simple condition metric with initial value unknown.
- ValueMetric* metric2 = config.add_value_metric();
- metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
- metric2->set_what(pulledAtomMatcher.id());
- *metric2->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric2->set_bucket(FIVE_MINUTES);
- metric2->set_condition(screenOnUnknownPredicate.id());
-
- // Combination condition metric with initial values false and false.
- ValueMetric* metric3 = config.add_value_metric();
- metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
- metric3->set_what(pulledAtomMatcher.id());
- *metric3->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric3->set_bucket(FIVE_MINUTES);
- metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
-
- // Combination condition metric with initial values unknown and false.
- ValueMetric* metric4 = config.add_value_metric();
- metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
- metric4->set_what(pulledAtomMatcher.id());
- *metric4->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- metric4->set_bucket(FIVE_MINUTES);
- metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
-
- return config;
-}
-
-bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) {
- return std::includes(set2.begin(), set2.end(), set1.begin(), set1.end());
-}
-} // anonymous namespace
-
-TEST(MetricsManagerTest, TestInitialConditions) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildConfigWithDifferentPredicates();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_TRUE(initStatsdConfig(
- kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, allConditionTrackers,
- allMetricProducers, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
- deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
- ASSERT_EQ(4u, allMetricProducers.size());
- ASSERT_EQ(5u, allConditionTrackers.size());
-
- ConditionKey queryKey;
- vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
-
- allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
- allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
-
- EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
- EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
-}
-
-TEST(MetricsManagerTest, TestGoodConfig) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildGoodConfig();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
- ASSERT_EQ(1u, allMetricProducers.size());
- ASSERT_EQ(1u, allAnomalyTrackers.size());
- ASSERT_EQ(1u, noReportMetricIds.size());
- ASSERT_EQ(1u, alertTrackerMap.size());
- EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
- EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
-}
-
-TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildDimensionMetricsWithMultiTags();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildCircleMatchers();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingMatchers) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildMissingMatchers();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingPredicate) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildMissingPredicate();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCirclePredicateDependency) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildCirclePredicates();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
- UidMap uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- StatsdConfig config = buildAlertWithUnknownMetric();
- set<int> allTagIds;
- vector<sp<LogMatchingTracker>> allAtomMatchers;
- vector<sp<ConditionTracker>> allConditionTrackers;
- vector<sp<MetricProducer>> allMetricProducers;
- std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
- std::vector<sp<AlarmTracker>> allAlarmTrackers;
- unordered_map<int, std::vector<int>> conditionToMetricMap;
- unordered_map<int, std::vector<int>> trackerToMetricMap;
- unordered_map<int, std::vector<int>> trackerToConditionMap;
- unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
- unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
- unordered_map<int64_t, int> alertTrackerMap;
- vector<int> metricsWithActivation;
- std::set<int64_t> noReportMetricIds;
-
- EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
- periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
- allAtomMatchers, allConditionTrackers, allMetricProducers,
- allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
- trackerToMetricMap, trackerToConditionMap,
- activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
- alertTrackerMap, metricsWithActivation,
- noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestLogSources) {
- string app1 = "app1";
- set<int32_t> app1Uids = {1111, 11111};
- string app2 = "app2";
- set<int32_t> app2Uids = {2222};
- string app3 = "app3";
- set<int32_t> app3Uids = {3333, 1111};
-
- map<string, set<int32_t>> pkgToUids;
- pkgToUids[app1] = app1Uids;
- pkgToUids[app2] = app2Uids;
- pkgToUids[app3] = app3Uids;
-
- int32_t atom1 = 10;
- int32_t atom2 = 20;
- int32_t atom3 = 30;
- sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
- EXPECT_CALL(*uidMap, getAppUid(_))
- .Times(4)
- .WillRepeatedly(Invoke([&pkgToUids](const string& pkg) {
- const auto& it = pkgToUids.find(pkg);
- if (it != pkgToUids.end()) {
- return it->second;
- }
- return set<int32_t>();
- }));
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
- EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
-
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- config.add_allowed_log_source("AID_SYSTEM");
- config.add_allowed_log_source(app1);
- config.add_default_pull_packages("AID_SYSTEM");
- config.add_default_pull_packages("AID_ROOT");
-
- const set<int32_t> defaultPullUids = {AID_SYSTEM, AID_ROOT};
-
- PullAtomPackages* pullAtomPackages = config.add_pull_atom_packages();
- pullAtomPackages->set_atom_id(atom1);
- pullAtomPackages->add_packages(app1);
- pullAtomPackages->add_packages(app3);
-
- pullAtomPackages = config.add_pull_atom_packages();
- pullAtomPackages->set_atom_id(atom2);
- pullAtomPackages->add_packages(app2);
- pullAtomPackages->add_packages("AID_STATSD");
-
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- EXPECT_TRUE(metricsManager.isConfigValid());
-
- ASSERT_EQ(metricsManager.mAllowedUid.size(), 1);
- EXPECT_EQ(metricsManager.mAllowedUid[0], AID_SYSTEM);
-
- ASSERT_EQ(metricsManager.mAllowedPkg.size(), 1);
- EXPECT_EQ(metricsManager.mAllowedPkg[0], app1);
-
- ASSERT_EQ(metricsManager.mAllowedLogSources.size(), 3);
- EXPECT_TRUE(isSubset({AID_SYSTEM}, metricsManager.mAllowedLogSources));
- EXPECT_TRUE(isSubset(app1Uids, metricsManager.mAllowedLogSources));
-
- ASSERT_EQ(metricsManager.mDefaultPullUids.size(), 2);
- EXPECT_TRUE(isSubset(defaultPullUids, metricsManager.mDefaultPullUids));
- ;
-
- vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
- ASSERT_EQ(atom1Uids.size(), 5);
- set<int32_t> expectedAtom1Uids;
- expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
- expectedAtom1Uids.insert(app1Uids.begin(), app1Uids.end());
- expectedAtom1Uids.insert(app3Uids.begin(), app3Uids.end());
- EXPECT_TRUE(isSubset(expectedAtom1Uids, set<int32_t>(atom1Uids.begin(), atom1Uids.end())));
-
- vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
- ASSERT_EQ(atom2Uids.size(), 4);
- set<int32_t> expectedAtom2Uids;
- expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
- expectedAtom1Uids.insert(app2Uids.begin(), app2Uids.end());
- expectedAtom1Uids.insert(AID_STATSD);
- EXPECT_TRUE(isSubset(expectedAtom2Uids, set<int32_t>(atom2Uids.begin(), atom2Uids.end())));
-
- vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
- ASSERT_EQ(atom3Uids.size(), 2);
- EXPECT_TRUE(isSubset(defaultPullUids, set<int32_t>(atom3Uids.begin(), atom3Uids.end())));
-}
-
-TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
- sp<UidMap> uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- config.add_whitelisted_atom_ids(3);
- config.add_whitelisted_atom_ids(4);
-
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- LogEvent event(0 /* uid */, 0 /* pid */);
- CreateNoValuesLogEvent(&event, 10 /* atom id */, 0 /* timestamp */);
- EXPECT_FALSE(metricsManager.checkLogCredentials(event));
-
- CreateNoValuesLogEvent(&event, 3 /* atom id */, 0 /* timestamp */);
- EXPECT_TRUE(metricsManager.checkLogCredentials(event));
-
- CreateNoValuesLogEvent(&event, 4 /* atom id */, 0 /* timestamp */);
- EXPECT_TRUE(metricsManager.checkLogCredentials(event));
-}
-
-TEST(MetricsManagerTest, TestWhitelistedAtomStateTracker) {
- sp<UidMap> uidMap;
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
-
- StatsdConfig config = buildGoodConfig();
- config.add_allowed_log_source("AID_SYSTEM");
- config.add_whitelisted_atom_ids(3);
- config.add_whitelisted_atom_ids(4);
-
- State state;
- state.set_id(1);
- state.set_atom_id(3);
-
- *config.add_state() = state;
-
- config.mutable_count_metric(0)->add_slice_by_state(state.id());
-
- StateManager::getInstance().clear();
-
- MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
- pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
- EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
- EXPECT_FALSE(metricsManager.isConfigValid());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
deleted file mode 100644
index 1e6680c47567..000000000000
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ /dev/null
@@ -1,1886 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "StatsLogProcessor.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-#include "statslog_statsdtest.h"
-#include "storage/StorageManager.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android;
-using namespace testing;
-using ::ndk::SharedRefBase;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-
-#ifdef __ANDROID__
-
-/**
- * Mock MetricsManager (ByteSize() is called).
- */
-class MockMetricsManager : public MetricsManager {
-public:
- MockMetricsManager()
- : MetricsManager(ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, new UidMap(),
- new StatsPullerManager(),
- new AlarmMonitor(10,
- [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
- [](const shared_ptr<IStatsCompanionService>&) {}),
- new AlarmMonitor(10,
- [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
- [](const shared_ptr<IStatsCompanionService>&) {})) {
- }
-
- MOCK_METHOD0(byteSize, size_t());
-
- MOCK_METHOD1(dropData, void(const int64_t dropTimeNs));
-};
-
-TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> periodicAlarmMonitor;
- // Construct the processor with a dummy sendBroadcast function that does nothing.
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) {return true;});
-
- MockMetricsManager mockMetricsManager;
-
- ConfigKey key(100, 12345);
- // Expect only the first flush to trigger a check for byte size since the last two are
- // rate-limited.
- EXPECT_CALL(mockMetricsManager, byteSize()).Times(1);
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- p.flushIfNecessaryLocked(key, mockMetricsManager);
-}
-
-TEST(StatsLogProcessorTest, TestRateLimitBroadcast) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
-
- MockMetricsManager mockMetricsManager;
-
- ConfigKey key(100, 12345);
- EXPECT_CALL(mockMetricsManager, byteSize())
- .Times(1)
- .WillRepeatedly(::testing::Return(int(
- StatsdStats::kMaxMetricsBytesPerConfig * .95)));
-
- // Expect only one broadcast despite always returning a size that should trigger broadcast.
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- EXPECT_EQ(1, broadcastCount);
-
- // b/73089712
- // This next call to flush should not trigger a broadcast.
- // p.mLastByteSizeTimes.clear(); // Force another check for byte size.
- // p.flushIfNecessaryLocked(2, key, mockMetricsManager);
- // EXPECT_EQ(1, broadcastCount);
-}
-
-TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
-
- MockMetricsManager mockMetricsManager;
-
- ConfigKey key(100, 12345);
- EXPECT_CALL(mockMetricsManager, byteSize())
- .Times(1)
- .WillRepeatedly(::testing::Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));
-
- EXPECT_CALL(mockMetricsManager, dropData(_)).Times(1);
-
- // Expect to call the onDumpReport and skip the broadcast.
- p.flushIfNecessaryLocked(key, mockMetricsManager);
- EXPECT_EQ(0, broadcastCount);
-}
-
-StatsdConfig MakeConfig(bool includeMetric) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- if (includeMetric) {
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(StringToId("AppCrashes"));
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- }
- return config;
-}
-
-TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
- {String16("p1"), String16("p2")}, {String16(""), String16("")});
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(true);
- p.OnConfigUpdated(0, key, config);
-
- // Expect to get no metrics, but snapshot specified above in uidmap.
- vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_TRUE(output.reports_size() > 0);
- auto uidmap = output.reports(0).uid_map();
- EXPECT_TRUE(uidmap.snapshots_size() > 0);
- ASSERT_EQ(2, uidmap.snapshots(0).package_info_size());
-}
-
-TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
- {String16("p1"), String16("p2")}, {String16(""), String16("")});
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(false);
- p.OnConfigUpdated(0, key, config);
-
- // Expect to get no metrics, but snapshot specified above in uidmap.
- vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_TRUE(output.reports_size() > 0);
- EXPECT_FALSE(output.reports(0).has_uid_map());
-}
-
-TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config;
- auto annotation = config.add_annotation();
- annotation->set_field_int64(1);
- annotation->set_field_int32(2);
- config.add_allowed_log_source("AID_ROOT");
- p.OnConfigUpdated(1, key, config);
-
- // Expect to get no metrics, but snapshot specified above in uidmap.
- vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_TRUE(output.reports_size() > 0);
- auto report = output.reports(0);
- ASSERT_EQ(1, report.annotation_size());
- EXPECT_EQ(1, report.annotation(0).field_int64());
- EXPECT_EQ(2, report.annotation(0).field_int32());
-}
-
-TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) {
- // Setup a simple config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
-
- ConfigKey cfgKey;
- sp<StatsLogProcessor> processor = CreateStatsLogProcessor(1, 1, config, cfgKey);
-
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(2 /*timestamp*/, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event.get());
-
- vector<uint8_t> bytes;
- ConfigMetricsReportList output;
-
- // Dump report WITHOUT erasing data.
- processor->onDumpReport(cfgKey, 3, true, false /* Do NOT erase data. */, ADB_DUMP, FAST,
- &bytes);
- output.ParseFromArray(bytes.data(), bytes.size());
- ASSERT_EQ(output.reports_size(), 1);
- ASSERT_EQ(output.reports(0).metrics_size(), 1);
- ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
-
- // Dump report WITH erasing data. There should be data since we didn't previously erase it.
- processor->onDumpReport(cfgKey, 4, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
- output.ParseFromArray(bytes.data(), bytes.size());
- ASSERT_EQ(output.reports_size(), 1);
- ASSERT_EQ(output.reports(0).metrics_size(), 1);
- ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
-
- // Dump report again. There should be no data since we erased it.
- processor->onDumpReport(cfgKey, 5, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
- output.ParseFromArray(bytes.data(), bytes.size());
- // We don't care whether statsd has a report, as long as it has no count metrics in it.
- bool noData = output.reports_size() == 0 || output.reports(0).metrics_size() == 0 ||
- output.reports(0).metrics(0).count_metrics().data_size() == 0;
- EXPECT_TRUE(noData);
-}
-
-TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- StatsLogProcessor p(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) { return true; });
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(false);
- p.OnConfigUpdated(0, key, config);
- EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-
- config.add_default_pull_packages("AID_STATSD");
- p.OnConfigUpdated(5, key, config);
- EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-
- p.OnConfigRemoved(key);
- EXPECT_EQ(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-}
-
-TEST(StatsLogProcessorTest, InvalidConfigRemoved) {
- // Setup simple config key corresponding to empty config.
- StatsdStats::getInstance().reset();
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
- {String16("p1"), String16("p2")}, {String16(""), String16("")});
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) {return true;});
- ConfigKey key(3, 4);
- StatsdConfig config = MakeConfig(true);
- p.OnConfigUpdated(0, key, config);
- EXPECT_EQ(1, p.mMetricsManagers.size());
- EXPECT_NE(p.mMetricsManagers.find(key), p.mMetricsManagers.end());
- // Cannot assert the size of mConfigStats since it is static and does not get cleared on reset.
- EXPECT_NE(StatsdStats::getInstance().mConfigStats.end(),
- StatsdStats::getInstance().mConfigStats.find(key));
- EXPECT_EQ(0, StatsdStats::getInstance().mIceBox.size());
-
- StatsdConfig invalidConfig = MakeConfig(true);
- invalidConfig.clear_allowed_log_source();
- p.OnConfigUpdated(0, key, invalidConfig);
- EXPECT_EQ(0, p.mMetricsManagers.size());
- // The current configs should not contain the invalid config.
- EXPECT_EQ(StatsdStats::getInstance().mConfigStats.end(),
- StatsdStats::getInstance().mConfigStats.find(key));
- // Both "config" and "invalidConfig" should be in the icebox.
- EXPECT_EQ(2, StatsdStats::getInstance().mIceBox.size());
-
-}
-
-
-TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
- int uid = 1111;
-
- // Setup a simple config, no activation
- StatsdConfig config1;
- int64_t cfgId1 = 12341;
- config1.set_id(cfgId1);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- ConfigKey cfgKey1(uid, cfgId1);
-
- // Add another config, with two metrics, one with activation
- StatsdConfig config2;
- int64_t cfgId2 = 12342;
- config2.set_id(cfgId2);
- config2.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config2.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId3 = 1234561;
- long metricId4 = 1234562;
-
- auto countMetric3 = config2.add_count_metric();
- countMetric3->set_id(metricId3);
- countMetric3->set_what(wakelockAcquireMatcher.id());
- countMetric3->set_bucket(FIVE_MINUTES);
-
- auto countMetric4 = config2.add_count_metric();
- countMetric4->set_id(metricId4);
- countMetric4->set_what(wakelockAcquireMatcher.id());
- countMetric4->set_bucket(FIVE_MINUTES);
-
- auto metric3Activation = config2.add_metric_activation();
- metric3Activation->set_metric_id(metricId3);
- metric3Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto metric3ActivationTrigger = metric3Activation->add_event_activation();
- metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric3ActivationTrigger->set_ttl_seconds(100);
-
- ConfigKey cfgKey2(uid, cfgId2);
-
- // Add another config, with two metrics, both with activations
- StatsdConfig config3;
- int64_t cfgId3 = 12343;
- config3.set_id(cfgId3);
- config3.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config3.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId5 = 1234565;
- long metricId6 = 1234566;
- auto countMetric5 = config3.add_count_metric();
- countMetric5->set_id(metricId5);
- countMetric5->set_what(wakelockAcquireMatcher.id());
- countMetric5->set_bucket(FIVE_MINUTES);
-
- auto countMetric6 = config3.add_count_metric();
- countMetric6->set_id(metricId6);
- countMetric6->set_what(wakelockAcquireMatcher.id());
- countMetric6->set_bucket(FIVE_MINUTES);
-
- auto metric5Activation = config3.add_metric_activation();
- metric5Activation->set_metric_id(metricId5);
- metric5Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto metric5ActivationTrigger = metric5Activation->add_event_activation();
- metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric5ActivationTrigger->set_ttl_seconds(100);
-
- auto metric6Activation = config3.add_metric_activation();
- metric6Activation->set_metric_id(metricId6);
- metric6Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto metric6ActivationTrigger = metric6Activation->add_event_activation();
- metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric6ActivationTrigger->set_ttl_seconds(200);
-
- ConfigKey cfgKey3(uid, cfgId3);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, timeBase1,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(1, cfgKey1, config1);
- processor.OnConfigUpdated(2, cfgKey2, config2);
- processor.OnConfigUpdated(3, cfgKey3, config3);
-
- ASSERT_EQ(3, processor.mMetricsManagers.size());
-
- // Expect the first config and both metrics in it to be active.
- auto it = processor.mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor.mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_TRUE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- // Expect config 2 to be active. Metric 3 shouldn't be active, metric 4 should be active.
- it = processor.mMetricsManagers.find(cfgKey2);
- EXPECT_TRUE(it != processor.mMetricsManagers.end());
- auto& metricsManager2 = it->second;
- EXPECT_TRUE(metricsManager2->isActive());
-
- metricIt = metricsManager2->mAllMetricProducers.begin();
- for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId3) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
- auto& metricProducer3 = *metricIt;
- EXPECT_FALSE(metricProducer3->isActive());
-
- metricIt = metricsManager2->mAllMetricProducers.begin();
- for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId4) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
- auto& metricProducer4 = *metricIt;
- EXPECT_TRUE(metricProducer4->isActive());
-
- // Expect the third config and both metrics in it to be inactive.
- it = processor.mMetricsManagers.find(cfgKey3);
- EXPECT_TRUE(it != processor.mMetricsManagers.end());
- auto& metricsManager3 = it->second;
- EXPECT_FALSE(metricsManager3->isActive());
-
- metricIt = metricsManager3->mAllMetricProducers.begin();
- for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId5) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
- auto& metricProducer5 = *metricIt;
- EXPECT_FALSE(metricProducer5->isActive());
-
- metricIt = metricsManager3->mAllMetricProducers.begin();
- for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId6) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
- auto& metricProducer6 = *metricIt;
- EXPECT_FALSE(metricProducer6->isActive());
-
- // No broadcast for active configs should have happened yet.
- EXPECT_EQ(broadcastCount, 0);
-
- // Activate all 3 metrics that were not active.
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor.OnLogEvent(event.get());
-
- // Assert that all 3 configs are active.
- EXPECT_TRUE(metricsManager1->isActive());
- EXPECT_TRUE(metricsManager2->isActive());
- EXPECT_TRUE(metricsManager3->isActive());
-
- // A broadcast should have happened, and all 3 configs should be active in the broadcast.
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 3);
- EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId1) !=
- activeConfigsBroadcast.end());
- EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId2) !=
- activeConfigsBroadcast.end());
- EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId3) !=
- activeConfigsBroadcast.end());
-
- // When we shut down, metrics 3 & 5 have 100ns remaining, metric 6 has 100s + 100ns.
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor.SaveActiveConfigsToDisk(shutDownTime);
- const int64_t ttl3 = event->GetElapsedTimestampNs() +
- metric3ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
- const int64_t ttl5 = event->GetElapsedTimestampNs() +
- metric5ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
- const int64_t ttl6 = event->GetElapsedTimestampNs() +
- metric6ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
-
- // Create a second StatsLogProcessor and push the same 3 configs.
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
- processor2->OnConfigUpdated(timeBase2, cfgKey2, config2);
- processor2->OnConfigUpdated(timeBase2, cfgKey3, config3);
-
- ASSERT_EQ(3, processor2->mMetricsManagers.size());
-
- // First config and both metrics are active.
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_TRUE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- // Second config is active. Metric 3 is inactive, metric 4 is active.
- it = processor2->mMetricsManagers.find(cfgKey2);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1002 = it->second;
- EXPECT_TRUE(metricsManager1002->isActive());
-
- metricIt = metricsManager1002->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId3) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
- auto& metricProducer1003 = *metricIt;
- EXPECT_FALSE(metricProducer1003->isActive());
-
- metricIt = metricsManager1002->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId4) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
- auto& metricProducer1004 = *metricIt;
- EXPECT_TRUE(metricProducer1004->isActive());
-
- // Config 3 is inactive. both metrics are inactive.
- it = processor2->mMetricsManagers.find(cfgKey3);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1003 = it->second;
- EXPECT_FALSE(metricsManager1003->isActive());
- ASSERT_EQ(2, metricsManager1003->mAllMetricProducers.size());
-
- metricIt = metricsManager1003->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId5) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
- auto& metricProducer1005 = *metricIt;
- EXPECT_FALSE(metricProducer1005->isActive());
-
- metricIt = metricsManager1003->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId6) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
- auto& metricProducer1006 = *metricIt;
- EXPECT_FALSE(metricProducer1006->isActive());
-
- // Assert that all 3 metrics with activation are inactive and that the ttls were properly set.
- EXPECT_FALSE(metricProducer1003->isActive());
- const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
- EXPECT_EQ(0, activation1003->start_ns);
- EXPECT_FALSE(metricProducer1005->isActive());
- const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1005->ttl_ns);
- EXPECT_EQ(0, activation1005->start_ns);
- EXPECT_FALSE(metricProducer1006->isActive());
- const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second;
- EXPECT_EQ(200 * NS_PER_SEC, activation1006->ttl_ns);
- EXPECT_EQ(0, activation1006->start_ns);
-
- processor2->LoadActiveConfigsFromDisk();
-
- // After loading activations from disk, assert that all 3 metrics are active.
- EXPECT_TRUE(metricProducer1003->isActive());
- EXPECT_EQ(timeBase2 + ttl3 - activation1003->ttl_ns, activation1003->start_ns);
- EXPECT_TRUE(metricProducer1005->isActive());
- EXPECT_EQ(timeBase2 + ttl5 - activation1005->ttl_ns, activation1005->start_ns);
- EXPECT_TRUE(metricProducer1006->isActive());
- EXPECT_EQ(timeBase2 + ttl6 - activation1006->ttl_ns, activation1003->start_ns);
-
- // Make sure no more broadcasts have happened.
- EXPECT_EQ(broadcastCount, 1);
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBoot) {
- int uid = 1111;
-
- StatsdConfig config1;
- config1.set_id(12341);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger = metric1Activation->add_event_activation();
- metric1ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger->set_ttl_seconds(100);
-
- ConfigKey cfgKey1(uid, 12341);
- long timeBase1 = 1;
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_FALSE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
-
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event.get());
-
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
-
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1->isActive());
- const int64_t ttl1 = metric1ActivationTrigger->ttl_seconds() * NS_PER_SEC;
-
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
- ASSERT_EQ(1, processor2->mMetricsManagers.size());
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_FALSE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second;
- EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
- EXPECT_EQ(0, activation1001->start_ns);
- EXPECT_EQ(kNotActive, activation1001->state);
-
- processor2->LoadActiveConfigsFromDisk();
-
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001->ttl_ns, activation1001->start_ns);
- EXPECT_EQ(kActive, activation1001->state);
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) {
- int uid = 1111;
-
- // Create config with 2 metrics:
- // Metric 1: Activate on boot with 2 activations
- // Metric 2: Always active
- StatsdConfig config1;
- config1.set_id(12341);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
- *config1.add_atom_matcher() = screenOnMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
-
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
- metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger1->set_ttl_seconds(100);
- auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
- metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
- metric1ActivationTrigger2->set_ttl_seconds(200);
-
- ConfigKey cfgKey1(uid, 12341);
- long timeBase1 = 1;
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_FALSE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- int i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
-
- i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation2 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
- // }}}------------------------------------------------------------------------------
-
- // Trigger Activation 1 for Metric 1
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event.get());
-
- // Metric 1 is not active; Activation 1 set to kActiveOnBoot
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
-
- EXPECT_TRUE(metricProducer2->isActive());
- // }}}-----------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1->isActive());
- int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor2->mMetricsManagers.size());
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_FALSE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns);
- EXPECT_EQ(0, activation1001_1->start_ns);
- EXPECT_EQ(kNotActive, activation1001_1->state);
-
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
- // }}}-----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor2->LoadActiveConfigsFromDisk();
-
- // Metric 1 active; Activation 1 is active, Activation 2 is not active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
-
- EXPECT_TRUE(metricProducer1002->isActive());
- // }}}--------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1.
- auto screenOnEvent =
- CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON);
- processor2->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is active, Activation 2 is set to kActiveOnBoot
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1001_2->state);
-
- EXPECT_TRUE(metricProducer1002->isActive());
- // }}}---------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- shutDownTime = timeBase2 + 50 * NS_PER_SEC;
- processor2->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_TRUE(metricProducer1002->isActive());
- ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime;
- int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC;
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase3 = timeBase2 + 120 * NS_PER_SEC;
- sp<StatsLogProcessor> processor3 =
- CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor3->mMetricsManagers.size());
- it = processor3->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor3->mMetricsManagers.end());
- auto& metricsManagerTimeBase3 = it->second;
- EXPECT_TRUE(metricsManagerTimeBase3->isActive());
-
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_1 = *metricIt;
- EXPECT_FALSE(metricProducerTimeBase3_1->isActive());
-
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_2 = *metricIt;
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
-
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
- // }}}----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor3->LoadActiveConfigsFromDisk();
-
- // Metric 1 active: Activation 1 is active, Activation 2 is active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
- // }}}-------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1 again.
- screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC,
- android::view::DISPLAY_STATE_ON);
- processor3->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is not active, Activation 2 is set to active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
- // }}}---------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk.
- shutDownTime = timeBase3 + 500 * NS_PER_SEC;
- processor3->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_TRUE(metricProducer1002->isActive());
- ttl1 = timeBase3 + ttl1 - shutDownTime;
- ttl2 = timeBase3 + metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime;
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase4 = timeBase3 + 600 * NS_PER_SEC;
- sp<StatsLogProcessor> processor4 =
- CreateStatsLogProcessor(timeBase4, timeBase4, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor4->mMetricsManagers.size());
- it = processor4->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor4->mMetricsManagers.end());
- auto& metricsManagerTimeBase4 = it->second;
- EXPECT_TRUE(metricsManagerTimeBase4->isActive());
-
- metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end());
- auto& metricProducerTimeBase4_1 = *metricIt;
- EXPECT_FALSE(metricProducerTimeBase4_1->isActive());
-
- metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end());
- auto& metricProducerTimeBase4_2 = *metricIt;
- EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
-
- i = 0;
- for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activationTimeBase4_1 = metricProducerTimeBase4_1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase4_1->ttl_ns);
- EXPECT_EQ(0, activationTimeBase4_1->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase4_1->state);
-
- i = 0;
- for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activationTimeBase4_2 = metricProducerTimeBase4_1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase4_2->ttl_ns);
- EXPECT_EQ(0, activationTimeBase4_2->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase4_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
- // }}}----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor4->LoadActiveConfigsFromDisk();
-
- // Metric 1 active: Activation 1 is not active, Activation 2 is not active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducerTimeBase4_1->isActive());
- EXPECT_EQ(kNotActive, activationTimeBase4_1->state);
- EXPECT_EQ(kNotActive, activationTimeBase4_2->state);
-
- EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
- // }}}-------------------------------------------------------------------------------
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) {
- int uid = 1111;
-
- // Create config with 2 metrics:
- // Metric 1: Activate on boot with 2 activations
- // Metric 2: Always active
- StatsdConfig config1;
- config1.set_id(12341);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
- *config1.add_atom_matcher() = screenOnMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
-
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
- metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger1->set_ttl_seconds(100);
- auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
- metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
- metric1ActivationTrigger2->set_ttl_seconds(200);
- metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
- ConfigKey cfgKey1(uid, 12341);
- long timeBase1 = 1;
- sp<StatsLogProcessor> processor1 =
- CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor1->mMetricsManagers.size());
- auto it = processor1->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor1->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
-
- ASSERT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
- // We assume that the index of a MetricProducer within the mAllMetricProducers
- // array follows the order in which metrics are added to the config.
- auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0];
- EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1);
- EXPECT_FALSE(metricProducer1_1->isActive()); // inactive due to associated MetricActivation
-
- auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1];
- EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2);
- EXPECT_TRUE(metricProducer1_2->isActive());
-
- ASSERT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
- // The key in mEventActivationMap is the index of the associated atom matcher. We assume
- // that matchers are indexed in the order that they are added to the config.
- const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns);
- EXPECT_EQ(0, activation1_1_1->start_ns);
- EXPECT_EQ(kNotActive, activation1_1_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType);
-
- const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns);
- EXPECT_EQ(0, activation1_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation1_1_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType);
- // }}}------------------------------------------------------------------------------
-
- // Trigger Activation 1 for Metric 1
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event =
- CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
- processor1->OnLogEvent(event.get());
-
- // Metric 1 is not active; Activation 1 set to kActiveOnBoot
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1_1->isActive());
- EXPECT_EQ(0, activation1_1_1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1_1_1->state);
- EXPECT_EQ(0, activation1_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation1_1_2->state);
-
- EXPECT_TRUE(metricProducer1_2->isActive());
- // }}}-----------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor1->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1_1->isActive());
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase2 = 1000;
- sp<StatsLogProcessor> processor2 =
- CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor2->mMetricsManagers.size());
- it = processor2->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager2 = it->second;
- EXPECT_TRUE(metricsManager2->isActive());
-
- ASSERT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
- // We assume that the index of a MetricProducer within the mAllMetricProducers
- // array follows the order in which metrics are added to the config.
- auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0];
- EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1);
- EXPECT_FALSE(metricProducer2_1->isActive());
-
- auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1];
- EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2);
- EXPECT_TRUE(metricProducer2_2->isActive());
-
- ASSERT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
- // The key in mEventActivationMap is the index of the associated atom matcher. We assume
- // that matchers are indexed in the order that they are added to the config.
- const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns);
- EXPECT_EQ(0, activation2_1_1->start_ns);
- EXPECT_EQ(kNotActive, activation2_1_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType);
-
- const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns);
- EXPECT_EQ(0, activation2_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation2_1_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType);
- // }}}-----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor2->LoadActiveConfigsFromDisk();
-
- // Metric 1 active; Activation 1 is active, Activation 2 is not active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer2_1->isActive());
- int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
- EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
- EXPECT_EQ(kActive, activation2_1_1->state);
- EXPECT_EQ(0, activation2_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation2_1_2->state);
-
- EXPECT_TRUE(metricProducer2_2->isActive());
- // }}}--------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1.
- auto screenOnEvent =
- CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON);
- processor2->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is active, Activation 2 is active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer2_1->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
- EXPECT_EQ(kActive, activation2_1_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns);
- EXPECT_EQ(kActive, activation2_1_2->state);
-
- EXPECT_TRUE(metricProducer2_2->isActive());
- // }}}---------------------------------------------------------------------------
-
- // Simulate shutdown by saving state to disk
- shutDownTime = timeBase2 + 50 * NS_PER_SEC;
- processor2->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer2_1->isActive());
- EXPECT_TRUE(metricProducer2_2->isActive());
- ttl1 -= shutDownTime - timeBase2;
- int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC -
- (shutDownTime - screenOnEvent->GetElapsedTimestampNs());
-
- // Simulate device restarted state by creating new instance of StatsLogProcessor with the
- // same config.
- long timeBase3 = timeBase2 + 120 * NS_PER_SEC;
- sp<StatsLogProcessor> processor3 =
- CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1);
-
- // Metric 1 is not active.
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor3->mMetricsManagers.size());
- it = processor3->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor3->mMetricsManagers.end());
- auto& metricsManager3 = it->second;
- EXPECT_TRUE(metricsManager3->isActive());
-
- ASSERT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
- // We assume that the index of a MetricProducer within the mAllMetricProducers
- // array follows the order in which metrics are added to the config.
- auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0];
- EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1);
- EXPECT_FALSE(metricProducer3_1->isActive());
-
- auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1];
- EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2);
- EXPECT_TRUE(metricProducer3_2->isActive());
-
- ASSERT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
- // The key in mEventActivationMap is the index of the associated atom matcher. We assume
- // that matchers are indexed in the order that they are added to the config.
- const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns);
- EXPECT_EQ(0, activation3_1_1->start_ns);
- EXPECT_EQ(kNotActive, activation3_1_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType);
-
- const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns);
- EXPECT_EQ(0, activation3_1_2->start_ns);
- EXPECT_EQ(kNotActive, activation3_1_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType);
- // }}}----------------------------------------------------------------------------------
-
- // Load saved state from disk.
- processor3->LoadActiveConfigsFromDisk();
-
- // Metric 1 active: Activation 1 is active, Activation 2 is active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer3_1->isActive());
- EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns);
- EXPECT_EQ(kActive, activation3_1_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns);
- EXPECT_EQ(kActive, activation3_1_2->state);
-
- EXPECT_TRUE(metricProducer3_2->isActive());
- // }}}-------------------------------------------------------------------------------
-
- // Trigger Activation 2 for Metric 1 again.
- screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC,
- android::view::DISPLAY_STATE_ON);
- processor3->OnLogEvent(screenOnEvent.get());
-
- // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire),
- // Activation 2 is set to active
- // Metric 2 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer3_1->isActive());
- EXPECT_EQ(kNotActive, activation3_1_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns);
- EXPECT_EQ(kActive, activation3_1_2->state);
-
- EXPECT_TRUE(metricProducer3_2->isActive());
- // }}}---------------------------------------------------------------------------
-}
-
-TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) {
- int uid = 9876;
- long configId = 12341;
-
- // Create config with 3 metrics:
- // Metric 1: Activate on 2 activations, 1 on boot, 1 immediate.
- // Metric 2: Activate on 2 activations, 1 on boot, 1 immediate.
- // Metric 3: Always active
- StatsdConfig config1;
- config1.set_id(configId);
- config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto jobStartMatcher = CreateStartScheduledJobAtomMatcher();
- auto jobFinishMatcher = CreateFinishScheduledJobAtomMatcher();
- *config1.add_atom_matcher() = wakelockAcquireMatcher;
- *config1.add_atom_matcher() = screenOnMatcher;
- *config1.add_atom_matcher() = jobStartMatcher;
- *config1.add_atom_matcher() = jobFinishMatcher;
-
- long metricId1 = 1234561;
- long metricId2 = 1234562;
- long metricId3 = 1234563;
-
- auto countMetric1 = config1.add_count_metric();
- countMetric1->set_id(metricId1);
- countMetric1->set_what(wakelockAcquireMatcher.id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- auto countMetric2 = config1.add_count_metric();
- countMetric2->set_id(metricId2);
- countMetric2->set_what(wakelockAcquireMatcher.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- auto countMetric3 = config1.add_count_metric();
- countMetric3->set_id(metricId3);
- countMetric3->set_what(wakelockAcquireMatcher.id());
- countMetric3->set_bucket(FIVE_MINUTES);
-
- // Metric 1 activates on boot for wakelock acquire, immediately for screen on.
- auto metric1Activation = config1.add_metric_activation();
- metric1Activation->set_metric_id(metricId1);
- auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
- metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
- metric1ActivationTrigger1->set_ttl_seconds(100);
- metric1ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
- metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
- metric1ActivationTrigger2->set_ttl_seconds(200);
- metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
- // Metric 2 activates on boot for scheduled job start, immediately for scheduled job finish.
- auto metric2Activation = config1.add_metric_activation();
- metric2Activation->set_metric_id(metricId2);
- auto metric2ActivationTrigger1 = metric2Activation->add_event_activation();
- metric2ActivationTrigger1->set_atom_matcher_id(jobStartMatcher.id());
- metric2ActivationTrigger1->set_ttl_seconds(100);
- metric2ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
- auto metric2ActivationTrigger2 = metric2Activation->add_event_activation();
- metric2ActivationTrigger2->set_atom_matcher_id(jobFinishMatcher.id());
- metric2ActivationTrigger2->set_ttl_seconds(200);
- metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
- // Send the config.
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- string serialized = config1.SerializeAsString();
- service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
-
- // Make sure the config is stored on disk. Otherwise, we will not reset on system server death.
- StatsdConfig tmpConfig;
- ConfigKey cfgKey1(uid, configId);
- EXPECT_TRUE(StorageManager::readConfigFromDisk(cfgKey1, &tmpConfig));
-
- // Metric 1 is not active.
- // Metric 2 is not active.
- // Metric 3 is active.
- // {{{---------------------------------------------------------------------------
- sp<StatsLogProcessor> processor = service->mProcessor;
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager1 = it->second;
- EXPECT_TRUE(metricsManager1->isActive());
- ASSERT_EQ(3, metricsManager1->mAllMetricProducers.size());
-
- auto& metricProducer1 = metricsManager1->mAllMetricProducers[0];
- EXPECT_EQ(metricId1, metricProducer1->getMetricId());
- EXPECT_FALSE(metricProducer1->isActive());
-
- auto& metricProducer2 = metricsManager1->mAllMetricProducers[1];
- EXPECT_EQ(metricId2, metricProducer2->getMetricId());
- EXPECT_FALSE(metricProducer2->isActive());
-
- auto& metricProducer3 = metricsManager1->mAllMetricProducers[2];
- EXPECT_EQ(metricId3, metricProducer3->getMetricId());
- EXPECT_TRUE(metricProducer3->isActive());
-
- // Check event activations.
- ASSERT_EQ(metricsManager1->mAllAtomMatchers.size(), 4);
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[0]->getId(),
- metric1ActivationTrigger1->atom_matcher_id());
- const auto& activation1 = metricProducer1->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType);
-
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[1]->getId(),
- metric1ActivationTrigger2->atom_matcher_id());
- const auto& activation2 = metricProducer1->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType);
-
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[2]->getId(),
- metric2ActivationTrigger1->atom_matcher_id());
- const auto& activation3 = metricProducer2->mEventActivationMap.at(2);
- EXPECT_EQ(100 * NS_PER_SEC, activation3->ttl_ns);
- EXPECT_EQ(0, activation3->start_ns);
- EXPECT_EQ(kNotActive, activation3->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation3->activationType);
-
- EXPECT_EQ(metricsManager1->mAllAtomMatchers[3]->getId(),
- metric2ActivationTrigger2->atom_matcher_id());
- const auto& activation4 = metricProducer2->mEventActivationMap.at(3);
- EXPECT_EQ(200 * NS_PER_SEC, activation4->ttl_ns);
- EXPECT_EQ(0, activation4->start_ns);
- EXPECT_EQ(kNotActive, activation4->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation4->activationType);
- // }}}------------------------------------------------------------------------------
-
- // Trigger Activation 1 for Metric 1. Should activate on boot.
- // Trigger Activation 4 for Metric 2. Should activate immediately.
- int64_t configAddedTimeNs = metricsManager1->mLastReportTimeNs;
- std::vector<int> attributionUids = {111};
- std::vector<string> attributionTags = {"App1"};
- std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(
- 1 + configAddedTimeNs, attributionUids, attributionTags, "wl1");
- processor->OnLogEvent(event1.get());
-
- std::unique_ptr<LogEvent> event2 = CreateFinishScheduledJobEvent(
- 2 + configAddedTimeNs, attributionUids, attributionTags, "finish1");
- processor->OnLogEvent(event2.get());
-
- // Metric 1 is not active; Activation 1 set to kActiveOnBoot
- // Metric 2 is active. Activation 4 set to kActive
- // Metric 3 is active.
- // {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
-
- EXPECT_TRUE(metricProducer2->isActive());
- EXPECT_EQ(0, activation3->start_ns);
- EXPECT_EQ(kNotActive, activation3->state);
- EXPECT_EQ(2 + configAddedTimeNs, activation4->start_ns);
- EXPECT_EQ(kActive, activation4->state);
-
- EXPECT_TRUE(metricProducer3->isActive());
- // }}}-----------------------------------------------------------------------------
-
- // Can't fake time with StatsService.
- // Lets get a time close to the system server death time and make sure it's sane.
- int64_t approximateSystemServerDeath = getElapsedRealtimeNs();
- EXPECT_TRUE(approximateSystemServerDeath > 2 + configAddedTimeNs);
- EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs);
-
- // System server dies.
- service->statsCompanionServiceDiedImpl();
-
- // We should have a new metrics manager. Lets get it and ensure activation status is restored.
- // {{{---------------------------------------------------------------------------
- ASSERT_EQ(1, processor->mMetricsManagers.size());
- it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
- auto& metricsManager2 = it->second;
- EXPECT_TRUE(metricsManager2->isActive());
- ASSERT_EQ(3, metricsManager2->mAllMetricProducers.size());
-
- auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0];
- EXPECT_EQ(metricId1, metricProducer1001->getMetricId());
- EXPECT_FALSE(metricProducer1001->isActive());
-
- auto& metricProducer1002 = metricsManager2->mAllMetricProducers[1];
- EXPECT_EQ(metricId2, metricProducer1002->getMetricId());
- EXPECT_TRUE(metricProducer1002->isActive());
-
- auto& metricProducer1003 = metricsManager2->mAllMetricProducers[2];
- EXPECT_EQ(metricId3, metricProducer1003->getMetricId());
- EXPECT_TRUE(metricProducer1003->isActive());
-
- // Check event activations.
- // Activation 1 is kActiveOnBoot.
- // Activation 2 and 3 are not active.
- // Activation 4 is active.
- ASSERT_EQ(metricsManager2->mAllAtomMatchers.size(), 4);
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[0]->getId(),
- metric1ActivationTrigger1->atom_matcher_id());
- const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0);
- EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
- EXPECT_EQ(0, activation1001->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1001->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001->activationType);
-
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[1]->getId(),
- metric1ActivationTrigger2->atom_matcher_id());
- const auto& activation1002 = metricProducer1001->mEventActivationMap.at(1);
- EXPECT_EQ(200 * NS_PER_SEC, activation1002->ttl_ns);
- EXPECT_EQ(0, activation1002->start_ns);
- EXPECT_EQ(kNotActive, activation1002->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1002->activationType);
-
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[2]->getId(),
- metric2ActivationTrigger1->atom_matcher_id());
- const auto& activation1003 = metricProducer1002->mEventActivationMap.at(2);
- EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
- EXPECT_EQ(0, activation1003->start_ns);
- EXPECT_EQ(kNotActive, activation1003->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1003->activationType);
-
- EXPECT_EQ(metricsManager2->mAllAtomMatchers[3]->getId(),
- metric2ActivationTrigger2->atom_matcher_id());
- const auto& activation1004 = metricProducer1002->mEventActivationMap.at(3);
- EXPECT_EQ(200 * NS_PER_SEC, activation1004->ttl_ns);
- EXPECT_EQ(2 + configAddedTimeNs, activation1004->start_ns);
- EXPECT_EQ(kActive, activation1004->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1004->activationType);
- // }}}------------------------------------------------------------------------------
-
- // Clear the data stored on disk as a result of the system server death.
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey1, configAddedTimeNs + NS_PER_SEC, false, true, ADB_DUMP, FAST,
- &buffer);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUid) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent = makeUidLogEvent(atomId, eventTimeNs, hostUid, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUid) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent =
- makeUidLogEvent(atomId, eventTimeNs, isolatedUid, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUidAttributionChain) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {hostUid, 200},
- {"tag1", "tag2"}, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUidAttributionChain) {
- int hostUid = 20;
- int isolatedUid = 30;
- uint64_t eventTimeNs = 12355;
- int atomId = 89;
- int field1 = 90;
- int field2 = 28;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey cfgKey;
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
- shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {isolatedUid, 200},
- {"tag1", "tag2"}, field1, field2);
-
- processor->OnLogEvent(logEvent.get());
-
- const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest, TestDumpReportWithoutErasingDataDoesNotUpdateTimestamp) {
- int hostUid = 20;
- int isolatedUid = 30;
- sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
- ConfigKey key(3, 4);
-
- // TODO: All tests should not persist state on disk. This removes any reports that were present.
- ProtoOutputStream proto;
- StorageManager::appendConfigMetricsReport(key, &proto, /*erase data=*/true, /*isAdb=*/false);
-
- StatsdConfig config = MakeConfig(false);
- sp<StatsLogProcessor> processor =
- CreateStatsLogProcessor(1, 1, config, key, nullptr, 0, mockUidMap);
- vector<uint8_t> bytes;
-
- int64_t dumpTime1Ns = 1 * NS_PER_SEC;
- processor->onDumpReport(key, dumpTime1Ns, false /* include_current_bucket */,
- true /* erase_data */, ADB_DUMP, FAST, &bytes);
-
- ConfigMetricsReportList output;
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_EQ(output.reports_size(), 1);
- EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime1Ns);
-
- int64_t dumpTime2Ns = 5 * NS_PER_SEC;
- processor->onDumpReport(key, dumpTime2Ns, false /* include_current_bucket */,
- false /* erase_data */, ADB_DUMP, FAST, &bytes);
-
- // Check that the dump report without clearing data is successful.
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_EQ(output.reports_size(), 1);
- EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime2Ns);
- EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
-
- int64_t dumpTime3Ns = 10 * NS_PER_SEC;
- processor->onDumpReport(key, dumpTime3Ns, false /* include_current_bucket */,
- true /* erase_data */, ADB_DUMP, FAST, &bytes);
-
- // Check that the previous dump report that didn't clear data did not overwrite the first dump's
- // timestamps.
- output.ParseFromArray(bytes.data(), bytes.size());
- EXPECT_EQ(output.reports_size(), 1);
- EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime3Ns);
- EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
-
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp
deleted file mode 100644
index cc38c4a4067a..000000000000
--- a/cmds/statsd/tests/StatsService_test.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <android/binder_interface_utils.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-using namespace android;
-using namespace testing;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using ::ndk::SharedRefBase;
-
-#ifdef __ANDROID__
-
-TEST(StatsServiceTest, TestAddConfig_simple) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- StatsdConfig config;
- config.set_id(12345);
- string serialized = config.SerializeAsString();
-
- EXPECT_TRUE(
- service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestAddConfig_empty) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- string serialized = "";
-
- EXPECT_TRUE(
- service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestAddConfig_invalid) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- string serialized = "Invalid config!";
-
- EXPECT_FALSE(
- service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestGetUidFromArgs) {
- Vector<String8> args;
- args.push(String8("-1"));
- args.push(String8("0"));
- args.push(String8("1"));
- args.push(String8("a1"));
- args.push(String8(""));
-
- int32_t uid;
-
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mEngBuild = true;
-
- // "-1"
- EXPECT_FALSE(service->getUidFromArgs(args, 0, uid));
-
- // "0"
- EXPECT_TRUE(service->getUidFromArgs(args, 1, uid));
- EXPECT_EQ(0, uid);
-
- // "1"
- EXPECT_TRUE(service->getUidFromArgs(args, 2, uid));
- EXPECT_EQ(1, uid);
-
- // "a1"
- EXPECT_FALSE(service->getUidFromArgs(args, 3, uid));
-
- // ""
- EXPECT_FALSE(service->getUidFromArgs(args, 4, uid));
-
- // For a non-userdebug, uid "1" cannot be impersonated.
- service->mEngBuild = false;
- EXPECT_FALSE(service->getUidFromArgs(args, 2, uid));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
deleted file mode 100644
index 293e8ed1c44c..000000000000
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "packages/UidMap.h"
-#include "StatsLogProcessor.h"
-#include "config/ConfigKey.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "hash.h"
-#include "statslog_statsdtest.h"
-#include "statsd_test_util.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using android::util::ProtoReader;
-
-#ifdef __ANDROID__
-const string kApp1 = "app1.sharing.1";
-const string kApp2 = "app2.sharing.1";
-
-TEST(UidMapTest, TestIsolatedUID) {
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- // Construct the processor with a dummy sendBroadcast function that does nothing.
- StatsLogProcessor p(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [](const ConfigKey& key) { return true; },
- [](const int&, const vector<int64_t>&) { return true; });
-
- std::unique_ptr<LogEvent> addEvent = CreateIsolatedUidChangedEvent(
- 1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 1 /*is_create*/);
- EXPECT_EQ(101, m->getHostUidOrSelf(101));
- p.OnLogEvent(addEvent.get());
- EXPECT_EQ(100, m->getHostUidOrSelf(101));
-
- std::unique_ptr<LogEvent> removeEvent = CreateIsolatedUidChangedEvent(
- 1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 0 /*is_create*/);
- p.OnLogEvent(removeEvent.get());
- EXPECT_EQ(101, m->getHostUidOrSelf(101));
-}
-
-TEST(UidMapTest, TestMatching) {
- UidMap m;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
-
- uids.push_back(1000);
- uids.push_back(1000);
- versionStrings.push_back(String16("v1"));
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- installers.push_back(String16(""));
- apps.push_back(String16(kApp1.c_str()));
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(4);
- versions.push_back(5);
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
- EXPECT_TRUE(m.hasApp(1000, kApp1));
- EXPECT_TRUE(m.hasApp(1000, kApp2));
- EXPECT_FALSE(m.hasApp(1000, "not.app"));
-
- std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */);
- EXPECT_TRUE(name_set.empty());
-}
-
-TEST(UidMapTest, TestAddAndRemove) {
- UidMap m;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
-
- uids.push_back(1000);
- uids.push_back(1000);
- versionStrings.push_back(String16("v1"));
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- installers.push_back(String16(""));
- apps.push_back(String16(kApp1.c_str()));
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(4);
- versions.push_back(5);
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- // Update the app1 version.
- m.updateApp(2, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
- EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
-
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- m.removeApp(3, String16(kApp1.c_str()), 1000);
- EXPECT_FALSE(m.hasApp(1000, kApp1));
- EXPECT_TRUE(m.hasApp(1000, kApp2));
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 1u);
- EXPECT_TRUE(name_set.find(kApp1) == name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- // Remove app2.
- m.removeApp(4, String16(kApp2.c_str()), 1000);
- EXPECT_FALSE(m.hasApp(1000, kApp1));
- EXPECT_FALSE(m.hasApp(1000, kApp2));
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- EXPECT_TRUE(name_set.empty());
-}
-
-TEST(UidMapTest, TestUpdateApp) {
- UidMap m;
- m.updateMap(1, {1000, 1000}, {4, 5}, {String16("v4"), String16("v5")},
- {String16(kApp1.c_str()), String16(kApp2.c_str())}, {String16(""), String16("")});
- std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 2u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
- // Adds a new name for uid 1000.
- m.updateApp(2, String16("NeW_aPP1_NAmE"), 1000, 40, String16("v40"), String16(""));
- name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 3u);
- EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
- EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
- EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
- EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
-
- // This name is also reused by another uid 2000.
- m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1, String16("v1"), String16(""));
- name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */);
- ASSERT_EQ(name_set.size(), 1u);
- EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
- EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
-}
-
-static void protoOutputStreamToUidMapping(ProtoOutputStream* proto, UidMapping* results) {
- vector<uint8_t> bytes;
- bytes.resize(proto->size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto->data();
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
- results->ParseFromArray(bytes.data(), bytes.size());
-}
-
-// Test that uid map returns at least one snapshot even if we already obtained
-// this snapshot from a previous call to getData.
-TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot) {
- UidMap m;
- // Initialize single config key.
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
- uids.push_back(1000);
- apps.push_back(String16(kApp2.c_str()));
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- versions.push_back(5);
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- // Set the last timestamp for this config key to be newer.
- m.mLastUpdatePerConfigKey[config1] = 2;
-
- ProtoOutputStream proto;
- m.appendUidMap(3, config1, nullptr, true, true, &proto);
-
- // Check there's still a uidmap attached this one.
- UidMapping results;
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- EXPECT_EQ("v1", results.snapshots(0).package_info(0).version_string());
-}
-
-TEST(UidMapTest, TestRemovedAppRetained) {
- UidMap m;
- // Initialize single config key.
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- uids.push_back(1000);
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(5);
- versionStrings.push_back(String16("v5"));
- installers.push_back(String16(""));
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
- m.removeApp(2, String16(kApp2.c_str()), 1000);
-
- ProtoOutputStream proto;
- m.appendUidMap(3, config1, nullptr, true, true, &proto);
-
- // Snapshot should still contain this item as deleted.
- UidMapping results;
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots(0).package_info_size());
- EXPECT_EQ(true, results.snapshots(0).package_info(0).deleted());
-}
-
-TEST(UidMapTest, TestRemovedAppOverGuardrail) {
- UidMap m;
- // Initialize single config key.
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- const int maxDeletedApps = StatsdStats::kMaxDeletedAppsInUidMap;
- for (int j = 0; j < maxDeletedApps + 10; j++) {
- uids.push_back(j);
- apps.push_back(String16(kApp1.c_str()));
- versions.push_back(j);
- versionStrings.push_back(String16("v"));
- installers.push_back(String16(""));
- }
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- // First, verify that we have the expected number of items.
- UidMapping results;
- ProtoOutputStream proto;
- m.appendUidMap(3, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size());
-
- // Now remove all the apps.
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
- for (int j = 0; j < maxDeletedApps + 10; j++) {
- m.removeApp(4, String16(kApp1.c_str()), j);
- }
-
- proto.clear();
- m.appendUidMap(5, config1, nullptr, true, true, &proto);
- // Snapshot drops the first nine items.
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(maxDeletedApps, results.snapshots(0).package_info_size());
-}
-
-TEST(UidMapTest, TestClearingOutput) {
- UidMap m;
-
- ConfigKey config1(1, StringToId("config1"));
- ConfigKey config2(1, StringToId("config2"));
-
- m.OnConfigUpdated(config1);
-
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- uids.push_back(1000);
- uids.push_back(1000);
- apps.push_back(String16(kApp1.c_str()));
- apps.push_back(String16(kApp2.c_str()));
- versions.push_back(4);
- versions.push_back(5);
- versionStrings.push_back(String16("v4"));
- versionStrings.push_back(String16("v5"));
- installers.push_back(String16(""));
- installers.push_back(String16(""));
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- ProtoOutputStream proto;
- m.appendUidMap(2, config1, nullptr, true, true, &proto);
- UidMapping results;
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
-
- // We have to keep at least one snapshot in memory at all times.
- proto.clear();
- m.appendUidMap(2, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
-
- // Now add another configuration.
- m.OnConfigUpdated(config2);
- m.updateApp(5, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
- ASSERT_EQ(1U, m.mChanges.size());
- proto.clear();
- m.appendUidMap(6, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- ASSERT_EQ(1, results.changes_size());
- ASSERT_EQ(1U, m.mChanges.size());
-
- // Add another delta update.
- m.updateApp(7, String16(kApp2.c_str()), 1001, 41, String16("v41"), String16(""));
- ASSERT_EQ(2U, m.mChanges.size());
-
- // We still can't remove anything.
- proto.clear();
- m.appendUidMap(8, config1, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- ASSERT_EQ(1, results.changes_size());
- ASSERT_EQ(2U, m.mChanges.size());
-
- proto.clear();
- m.appendUidMap(9, config2, nullptr, true, true, &proto);
- protoOutputStreamToUidMapping(&proto, &results);
- ASSERT_EQ(1, results.snapshots_size());
- ASSERT_EQ(2, results.changes_size());
- // At this point both should be cleared.
- ASSERT_EQ(0U, m.mChanges.size());
-}
-
-TEST(UidMapTest, TestMemoryComputed) {
- UidMap m;
-
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
-
- size_t startBytes = m.mBytesUsed;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> apps;
- vector<String16> versionStrings;
- vector<String16> installers;
- uids.push_back(1000);
- apps.push_back(String16(kApp1.c_str()));
- versions.push_back(1);
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- m.updateApp(3, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
-
- ProtoOutputStream proto;
- vector<uint8_t> bytes;
- m.appendUidMap(2, config1, nullptr, true, true, &proto);
- size_t prevBytes = m.mBytesUsed;
-
- m.appendUidMap(4, config1, nullptr, true, true, &proto);
- EXPECT_TRUE(m.mBytesUsed < prevBytes);
-}
-
-TEST(UidMapTest, TestMemoryGuardrail) {
- UidMap m;
- string buf;
-
- ConfigKey config1(1, StringToId("config1"));
- m.OnConfigUpdated(config1);
-
- size_t startBytes = m.mBytesUsed;
- vector<int32_t> uids;
- vector<int64_t> versions;
- vector<String16> versionStrings;
- vector<String16> installers;
- vector<String16> apps;
- for (int i = 0; i < 100; i++) {
- uids.push_back(1);
- buf = "EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY." + to_string(i);
- apps.push_back(String16(buf.c_str()));
- versions.push_back(1);
- versionStrings.push_back(String16("v1"));
- installers.push_back(String16(""));
- }
- m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
- m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2,
- String16("v2"), String16(""));
- ASSERT_EQ(1U, m.mChanges.size());
-
- // Now force deletion by limiting the memory to hold one delta change.
- m.maxBytesOverride = 120; // Since the app string alone requires >45 characters.
- m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4,
- String16("v4"), String16(""));
- ASSERT_EQ(1U, m.mChanges.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
deleted file mode 100644
index 64ea219c8465..000000000000
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/anomaly/AlarmTracker.h"
-
-#include <gtest/gtest.h>
-#include <log/log_time.h>
-#include <stdio.h>
-#include <vector>
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::shared_ptr;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-TEST(AlarmTrackerTest, TestTriggerTimestamp) {
- sp<AlarmMonitor> subscriberAlarmMonitor =
- new AlarmMonitor(100,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
- Alarm alarm;
- alarm.set_offset_millis(15 * MS_PER_SEC);
- alarm.set_period_millis(60 * 60 * MS_PER_SEC); // 1hr
- int64_t startMillis = 100000000 * MS_PER_SEC;
- int64_t nextAlarmTime = startMillis / MS_PER_SEC + 15;
- AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor);
-
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-
- uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
- subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- EXPECT_TRUE(firedAlarmSet.empty());
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
- currentTimeSec = startMillis / MS_PER_SEC + 7000;
- nextAlarmTime = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
- firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- ASSERT_EQ(firedAlarmSet.size(), 1u);
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
- // Alarm fires exactly on time.
- currentTimeSec = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
- nextAlarmTime = startMillis / MS_PER_SEC + 15 + 3 * 60 * 60;
- firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- ASSERT_EQ(firedAlarmSet.size(), 1u);
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
- // Alarm fires exactly 1 period late.
- currentTimeSec = startMillis / MS_PER_SEC + 15 + 4 * 60 * 60;
- nextAlarmTime = startMillis / MS_PER_SEC + 15 + 5 * 60 * 60;
- firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- ASSERT_EQ(firedAlarmSet.size(), 1u);
- tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
- EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
deleted file mode 100644
index 0cc8af16c782..000000000000
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/anomaly/AnomalyTracker.h"
-
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-MetricDimensionKey getMockMetricDimensionKey(int key, string value) {
- int pos[] = {key, 0, 0};
- HashableDimensionKey dim;
- dim.addValue(FieldValue(Field(1, pos, 0), Value(value)));
- return MetricDimensionKey(dim, DEFAULT_DIMENSION_KEY);
-}
-
-void AddValueToBucket(const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list,
- std::shared_ptr<DimToValMap> bucket) {
- for (auto itr = key_value_pair_list.begin(); itr != key_value_pair_list.end(); itr++) {
- (*bucket)[itr->first] += itr->second;
- }
-}
-
-std::shared_ptr<DimToValMap> MockBucket(
- const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list) {
- std::shared_ptr<DimToValMap> bucket = std::make_shared<DimToValMap>();
- AddValueToBucket(key_value_pair_list, bucket);
- return bucket;
-}
-
-// Returns the value, for the given key, in that bucket, or 0 if not present.
-int64_t getBucketValue(const std::shared_ptr<DimToValMap>& bucket,
- const MetricDimensionKey& key) {
- const auto& itr = bucket->find(key);
- if (itr != bucket->end()) {
- return itr->second;
- }
- return 0;
-}
-
-// Returns true if keys in trueList are detected as anomalies and keys in falseList are not.
-bool detectAnomaliesPass(AnomalyTracker& tracker,
- const int64_t& bucketNum,
- const std::shared_ptr<DimToValMap>& currentBucket,
- const std::set<const MetricDimensionKey>& trueList,
- const std::set<const MetricDimensionKey>& falseList) {
- for (const MetricDimensionKey& key : trueList) {
- if (!tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
- return false;
- }
- }
- for (const MetricDimensionKey& key : falseList) {
- if (tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
- return false;
- }
- }
- return true;
-}
-
-// Calls tracker.detectAndDeclareAnomaly on each key in the bucket.
-void detectAndDeclareAnomalies(AnomalyTracker& tracker,
- const int64_t& bucketNum,
- const std::shared_ptr<DimToValMap>& bucket,
- const int64_t& eventTimestamp) {
- for (const auto& kv : *bucket) {
- tracker.detectAndDeclareAnomaly(eventTimestamp, bucketNum, 0 /*metric_id*/, kv.first,
- kv.second);
- }
-}
-
-// Asserts that the refractory time for each key in timestamps is the corresponding
-// timestamp (in ns) + refractoryPeriodSec.
-// If a timestamp value is negative, instead asserts that the refractory period is inapplicable
-// (either non-existant or already past).
-void checkRefractoryTimes(AnomalyTracker& tracker,
- const int64_t& currTimestampNs,
- const int32_t& refractoryPeriodSec,
- const std::unordered_map<MetricDimensionKey, int64_t>& timestamps) {
- for (const auto& kv : timestamps) {
- if (kv.second < 0) {
- // Make sure that, if there is a refractory period, it is already past.
- EXPECT_LT(tracker.getRefractoryPeriodEndsSec(kv.first) * NS_PER_SEC,
- (uint64_t)currTimestampNs)
- << "Failure was at currTimestampNs " << currTimestampNs;
- } else {
- EXPECT_EQ(tracker.getRefractoryPeriodEndsSec(kv.first),
- std::ceil(1.0 * kv.second / NS_PER_SEC) + refractoryPeriodSec)
- << "Failure was at currTimestampNs " << currTimestampNs;
- }
- }
-}
-
-TEST(AnomalyTrackerTest, TestConsecutiveBuckets) {
- const int64_t bucketSizeNs = 30 * NS_PER_SEC;
- const int32_t refractoryPeriodSec = 2 * bucketSizeNs / NS_PER_SEC;
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_refractory_period_secs(refractoryPeriodSec);
- alert.set_trigger_if_sum_gt(2);
-
- AnomalyTracker anomalyTracker(alert, kConfigKey);
- MetricDimensionKey keyA = getMockMetricDimensionKey(1, "a");
- MetricDimensionKey keyB = getMockMetricDimensionKey(1, "b");
- MetricDimensionKey keyC = getMockMetricDimensionKey(1, "c");
-
- int64_t eventTimestamp0 = 10 * NS_PER_SEC;
- int64_t eventTimestamp1 = bucketSizeNs + 11 * NS_PER_SEC;
- int64_t eventTimestamp2 = 2 * bucketSizeNs + 12 * NS_PER_SEC;
- int64_t eventTimestamp3 = 3 * bucketSizeNs + 13 * NS_PER_SEC;
- int64_t eventTimestamp4 = 4 * bucketSizeNs + 14 * NS_PER_SEC;
- int64_t eventTimestamp5 = 5 * bucketSizeNs + 5 * NS_PER_SEC;
- int64_t eventTimestamp6 = 6 * bucketSizeNs + 16 * NS_PER_SEC;
-
- std::shared_ptr<DimToValMap> bucket0 = MockBucket({{keyA, 1}, {keyB, 2}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket1 = MockBucket({{keyA, 1}});
- std::shared_ptr<DimToValMap> bucket2 = MockBucket({{keyB, 1}});
- std::shared_ptr<DimToValMap> bucket3 = MockBucket({{keyA, 2}});
- std::shared_ptr<DimToValMap> bucket4 = MockBucket({{keyB, 5}});
- std::shared_ptr<DimToValMap> bucket5 = MockBucket({{keyA, 2}});
- std::shared_ptr<DimToValMap> bucket6 = MockBucket({{keyA, 2}});
-
- // Start time with no events.
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0u);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
-
- // Event from bucket #0 occurs.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 0, bucket0, {}, {keyA, keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 0, bucket0, eventTimestamp1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp0, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
- // Adds past bucket #0
- anomalyTracker.addPastBucket(bucket0, 0);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 0LL);
-
- // Event from bucket #1 occurs.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 1, bucket1, {}, {keyA, keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 1, bucket1, eventTimestamp1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
- // Adds past bucket #0 again. The sum does not change.
- anomalyTracker.addPastBucket(bucket0, 0);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 0LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 1, bucket1, {}, {keyA, keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 1, bucket1, eventTimestamp1 + 1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
- // Adds past bucket #1.
- anomalyTracker.addPastBucket(bucket1, 1);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-
- // Event from bucket #2 occurs. New anomaly on keyB.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 2, bucket2, {keyB}, {keyA, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 2, bucket2, eventTimestamp2);
- checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}});
-
- // Adds past bucket #1 again. Nothing changes.
- anomalyTracker.addPastBucket(bucket1, 1);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- // Event from bucket #2 occurs (again).
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 2, bucket2, {keyB}, {keyA, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 2, bucket2, eventTimestamp2 + 1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}});
-
- // Adds past bucket #2.
- anomalyTracker.addPastBucket(bucket2, 2);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 2L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-
- // Event from bucket #3 occurs. New anomaly on keyA.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 3, bucket3, {keyA}, {keyB, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 3, bucket3, eventTimestamp3);
- checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
- {{keyA, eventTimestamp3}, {keyB, eventTimestamp2}, {keyC, -1}});
-
- // Adds bucket #3.
- anomalyTracker.addPastBucket(bucket3, 3L);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 3L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-
- // Event from bucket #4 occurs. New anomaly on keyB.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 4, bucket4, {keyB}, {keyA, keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 4, bucket4, eventTimestamp4);
- checkRefractoryTimes(anomalyTracker, eventTimestamp4, refractoryPeriodSec,
- {{keyA, eventTimestamp3}, {keyB, eventTimestamp4}, {keyC, -1}});
-
- // Adds bucket #4.
- anomalyTracker.addPastBucket(bucket4, 4);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 4L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
-
- // Event from bucket #5 occurs. New anomaly on keyA, which is still in refractory.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 5, bucket5, {keyA, keyB}, {keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 5, bucket5, eventTimestamp5);
- checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
- {{keyA, eventTimestamp3}, {keyB, eventTimestamp4}, {keyC, -1}});
-
- // Adds bucket #5.
- anomalyTracker.addPastBucket(bucket5, 5);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 5L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
-
- // Event from bucket #6 occurs. New anomaly on keyA, which is now out of refractory.
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 6, bucket6, {keyA, keyB}, {keyC}));
- detectAndDeclareAnomalies(anomalyTracker, 6, bucket6, eventTimestamp6);
- checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
- {{keyA, eventTimestamp6}, {keyB, eventTimestamp4}, {keyC, -1}});
-}
-
-TEST(AnomalyTrackerTest, TestSparseBuckets) {
- const int64_t bucketSizeNs = 30 * NS_PER_SEC;
- const int32_t refractoryPeriodSec = 2 * bucketSizeNs / NS_PER_SEC;
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_refractory_period_secs(refractoryPeriodSec);
- alert.set_trigger_if_sum_gt(2);
-
- AnomalyTracker anomalyTracker(alert, kConfigKey);
- MetricDimensionKey keyA = getMockMetricDimensionKey(1, "a");
- MetricDimensionKey keyB = getMockMetricDimensionKey(1, "b");
- MetricDimensionKey keyC = getMockMetricDimensionKey(1, "c");
- MetricDimensionKey keyD = getMockMetricDimensionKey(1, "d");
- MetricDimensionKey keyE = getMockMetricDimensionKey(1, "e");
-
- std::shared_ptr<DimToValMap> bucket9 = MockBucket({{keyA, 1}, {keyB, 2}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket16 = MockBucket({{keyB, 4}});
- std::shared_ptr<DimToValMap> bucket18 = MockBucket({{keyB, 1}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket20 = MockBucket({{keyB, 3}, {keyC, 1}});
- std::shared_ptr<DimToValMap> bucket25 = MockBucket({{keyD, 1}});
- std::shared_ptr<DimToValMap> bucket28 = MockBucket({{keyE, 2}});
-
- int64_t eventTimestamp1 = bucketSizeNs * 8 + 1;
- int64_t eventTimestamp2 = bucketSizeNs * 15 + 11;
- int64_t eventTimestamp3 = bucketSizeNs * 17 + 1;
- int64_t eventTimestamp4 = bucketSizeNs * 19 + 2;
- int64_t eventTimestamp5 = bucketSizeNs * 24 + 3;
- int64_t eventTimestamp6 = bucketSizeNs * 27 + 3;
-
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 9, bucket9, {}, {keyA, keyB, keyC, keyD}));
- detectAndDeclareAnomalies(anomalyTracker, 9, bucket9, eventTimestamp1);
- checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #9
- anomalyTracker.addPastBucket(bucket9, 9);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 9L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 16, bucket16, {keyB}, {keyA, keyC, keyD}));
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
- detectAndDeclareAnomalies(anomalyTracker, 16, bucket16, eventTimestamp2);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
- checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #16
- anomalyTracker.addPastBucket(bucket16, 16);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 16L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 18, bucket18, {keyB}, {keyA, keyC, keyD}));
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
- // Within refractory period.
- detectAndDeclareAnomalies(anomalyTracker, 18, bucket18, eventTimestamp3);
- checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
-
- // Add past bucket #18
- anomalyTracker.addPastBucket(bucket18, 18);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 18L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4);
- checkRefractoryTimes(anomalyTracker, eventTimestamp4, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add bucket #18 again. Nothing changes.
- anomalyTracker.addPastBucket(bucket18, 18);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4 + 1);
- // Within refractory period.
- checkRefractoryTimes(anomalyTracker, eventTimestamp4 + 1, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #20
- anomalyTracker.addPastBucket(bucket20, 20);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 20L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 3LL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 25, bucket25, {}, {keyA, keyB, keyC, keyD}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 24L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- detectAndDeclareAnomalies(anomalyTracker, 25, bucket25, eventTimestamp5);
- checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
- {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Add past bucket #25
- anomalyTracker.addPastBucket(bucket25, 25);
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 25L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
- EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyD), 1LL);
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {},
- {keyA, keyB, keyC, keyD, keyE}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
- // Updates current bucket #28.
- (*bucket28)[keyE] = 5;
- EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {keyE},
- {keyA, keyB, keyC, keyD}));
- EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6 + 7);
- ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
- checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
- {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, eventTimestamp6 + 7}});
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
deleted file mode 100644
index 1d501fd5a87c..000000000000
--- a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "condition/condition_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-#include <vector>
-
-using namespace android::os::statsd;
-using std::vector;
-
-#ifdef __ANDROID__
-
-TEST(ConditionTrackerTest, TestUnknownCondition) {
- LogicalOperation operation = LogicalOperation::AND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kUnknown);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
- ConditionState::kUnknown);
-}
-
-TEST(ConditionTrackerTest, TestAndCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::AND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestOrCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::OR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
- children.push_back(2);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestNotCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOT;
-
- vector<int> children;
- children.push_back(0);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- children.clear();
- conditionResults.clear();
- EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
- ConditionState::kUnknown);
-}
-
-TEST(ConditionTrackerTest, TestNandCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NAND;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
-
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestNorCondition) {
- // Set up the matcher
- LogicalOperation operation = LogicalOperation::NOR;
-
- vector<int> children;
- children.push_back(0);
- children.push_back(1);
-
- vector<ConditionState> conditionResults;
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kFalse);
-
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kFalse);
- conditionResults.push_back(ConditionState::kFalse);
- EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
- conditionResults.clear();
- conditionResults.push_back(ConditionState::kTrue);
- conditionResults.push_back(ConditionState::kTrue);
- EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/ConditionTimer_test.cpp b/cmds/statsd/tests/condition/ConditionTimer_test.cpp
deleted file mode 100644
index ea02cd3a5ee1..000000000000
--- a/cmds/statsd/tests/condition/ConditionTimer_test.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/condition/ConditionTimer.h"
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static int64_t time_base = 10;
-static int64_t ct_start_time = 200;
-
-TEST(ConditionTimerTest, TestTimer_Inital_False) {
- ConditionTimer timer(false, time_base);
- EXPECT_EQ(false, timer.mCondition);
- EXPECT_EQ(0, timer.mTimerNs);
-
- EXPECT_EQ(0, timer.newBucketStart(ct_start_time));
- EXPECT_EQ(0, timer.mTimerNs);
-
- timer.onConditionChanged(true, ct_start_time + 5);
- EXPECT_EQ(ct_start_time + 5, timer.mLastConditionTrueTimestampNs);
- EXPECT_EQ(true, timer.mCondition);
-
- EXPECT_EQ(95, timer.newBucketStart(ct_start_time + 100));
- EXPECT_EQ(ct_start_time + 100, timer.mLastConditionTrueTimestampNs);
- EXPECT_EQ(true, timer.mCondition);
-}
-
-TEST(ConditionTimerTest, TestTimer_Inital_True) {
- ConditionTimer timer(true, time_base);
- EXPECT_EQ(true, timer.mCondition);
- EXPECT_EQ(0, timer.mTimerNs);
-
- EXPECT_EQ(ct_start_time - time_base, timer.newBucketStart(ct_start_time));
- EXPECT_EQ(true, timer.mCondition);
- EXPECT_EQ(0, timer.mTimerNs);
- EXPECT_EQ(ct_start_time, timer.mLastConditionTrueTimestampNs);
-
- timer.onConditionChanged(false, ct_start_time + 5);
- EXPECT_EQ(5, timer.mTimerNs);
-
- EXPECT_EQ(5, timer.newBucketStart(ct_start_time + 100));
- EXPECT_EQ(0, timer.mTimerNs);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
deleted file mode 100644
index 07b5311b1207..000000000000
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ /dev/null
@@ -1,739 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/condition/SimpleConditionTracker.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <vector>
-#include <numeric>
-
-using std::map;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-
-const int ATTRIBUTION_NODE_FIELD_ID = 1;
-const int ATTRIBUTION_UID_FIELD_ID = 1;
-const int TAG_ID = 1;
-
-SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse,
- bool outputSlicedUid, Position position) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("WAKE_LOCK_ACQUIRE"));
- simplePredicate.set_stop(StringToId("WAKE_LOCK_RELEASE"));
- simplePredicate.set_stop_all(StringToId("RELEASE_ALL"));
- if (outputSlicedUid) {
- simplePredicate.mutable_dimensions()->set_field(TAG_ID);
- simplePredicate.mutable_dimensions()->add_child()->set_field(ATTRIBUTION_NODE_FIELD_ID);
- simplePredicate.mutable_dimensions()->mutable_child(0)->set_position(position);
- simplePredicate.mutable_dimensions()->mutable_child(0)->add_child()->set_field(
- ATTRIBUTION_UID_FIELD_ID);
- }
-
- simplePredicate.set_count_nesting(countNesting);
- simplePredicate.set_initial_value(defaultFalse ? SimplePredicate_InitialValue_FALSE
- : SimplePredicate_InitialValue_UNKNOWN);
- return simplePredicate;
-}
-
-void makeWakeLockEvent(LogEvent* logEvent, uint32_t atomId, uint64_t timestamp,
- const vector<int>& uids, const string& wl, int acquire) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
- vector<std::string> tags(uids.size()); // vector of empty strings
- writeAttribution(statsEvent, uids, tags);
-
- AStatsEvent_writeString(statsEvent, wl.c_str());
- AStatsEvent_writeInt32(statsEvent, acquire);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // anonymous namespace
-
-
-std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey(
- const Position position,
- const std::vector<int> &uids, const string& conditionName) {
- std::map<int64_t, HashableDimensionKey> outputKeyMap;
- std::vector<int> uid_indexes;
- int pos[] = {1, 1, 1};
- int depth = 2;
- Field field(1, pos, depth);
- switch(position) {
- case Position::FIRST:
- uid_indexes.push_back(0);
- break;
- case Position::LAST:
- uid_indexes.push_back(uids.size() - 1);
- field.setField(0x02018001);
- break;
- case Position::ANY:
- uid_indexes.resize(uids.size());
- std::iota(uid_indexes.begin(), uid_indexes.end(), 0);
- field.setField(0x02010001);
- break;
- default:
- break;
- }
-
- for (const int idx : uid_indexes) {
- Value value((int32_t)uids[idx]);
- HashableDimensionKey dim;
- dim.addValue(FieldValue(field, value));
- outputKeyMap[StringToId(conditionName)] = dim;
- }
- return outputKeyMap;
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueFalse) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(false);
- simplePredicate.set_initial_value(SimplePredicate_InitialValue_FALSE);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
- 0 /*tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- ConditionKey queryKey;
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-
- // Check that initial condition is false.
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-
- vector<MatchingState> matcherState;
- vector<bool> changedCache(1, false);
-
- // Matched stop event.
- // Check that condition is still false.
- unique_ptr<LogEvent> screenOffEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched); // On matcher not matched
- matcherState.push_back(MatchingState::kMatched); // Off matcher matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // Matched start event.
- // Check that condition has changed to true.
- unique_ptr<LogEvent> screenOnEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched); // On matcher matched
- matcherState.push_back(MatchingState::kNotMatched); // Off matcher not matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueUnknown) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(false);
- simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
- 0 /*tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- ConditionKey queryKey;
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-
- // Check that initial condition is unknown.
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
-
- vector<MatchingState> matcherState;
- vector<bool> changedCache(1, false);
-
- // Matched stop event.
- // Check that condition is changed to false.
- unique_ptr<LogEvent> screenOffEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched); // On matcher not matched
- matcherState.push_back(MatchingState::kMatched); // Off matcher matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // Matched start event.
- // Check that condition has changed to true.
- unique_ptr<LogEvent> screenOnEvent =
- CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched); // On matcher matched
- matcherState.push_back(MatchingState::kNotMatched); // Off matcher not matched
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(false);
- simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), 0 /*tracker index*/,
- simplePredicate, trackerNameIndexMap);
- EXPECT_FALSE(conditionTracker.isSliced());
-
- // This event is not accessed in this test besides dimensions which is why this is okay.
- // This is technically an invalid LogEvent because we do not call parseBuffer.
- LogEvent event(/*uid=*/0, /*pid=*/0);
-
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
-
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // not matched start or stop. condition doesn't change
- EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // prepare a case for match start.
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // now condition should change to true.
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // match nothing.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // the case for match stop.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
-
- // condition changes to false.
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // match stop again.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // condition should still be false. not changed.
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
- std::vector<sp<ConditionTracker>> allConditions;
- SimplePredicate simplePredicate;
- simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
- simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
- simplePredicate.set_count_nesting(true);
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
- trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
- EXPECT_FALSE(conditionTracker.isSliced());
-
- // This event is not accessed in this test besides dimensions which is why this is okay.
- // This is technically an invalid LogEvent because we do not call parseBuffer.
- LogEvent event(/*uid=*/0, /*pid=*/0);
-
- // one matched start
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
-
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-
- // prepare for another matched start.
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
-
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // ONE MATCHED STOP
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- // result should still be true
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
- EXPECT_FALSE(changedCache[0]);
-
- // ANOTHER MATCHED STOP
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
-
- conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
- std::vector<sp<ConditionTracker>> allConditions;
- for (Position position : {Position::FIRST, Position::LAST}) {
- SimplePredicate simplePredicate = getWakeLockHeldCondition(
- true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
- position);
- string conditionName = "WL_HELD_BY_UID2";
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
- trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
- trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- std::vector<int> uids = {111, 222, 333};
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/1);
-
- // one matched start
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
- changedCache);
-
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u);
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(),
- uids.size());
- }
-
- // Now test query
- const auto queryKey = getWakeLockQueryKey(position, uids, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
-
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // another wake lock acquired by this uid
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/1);
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_FALSE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-
-
- // wake lock 1 release
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/0);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
- changedCache);
- // nothing changes, because wake lock 2 is still held for this uid
- EXPECT_FALSE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/0);
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
- changedCache);
- ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
- EXPECT_TRUE(changedCache[0]);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u);
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(),
- uids.size());
- }
-
- // query again
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- }
-
-}
-
-TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
- std::vector<sp<ConditionTracker>> allConditions;
-
- SimplePredicate simplePredicate =
- getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
- false /*slice output by uid*/, Position::ANY /* position */);
- string conditionName = "WL_HELD";
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
- trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
- trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- EXPECT_FALSE(conditionTracker.isSliced());
-
- std::vector<int> uids1 = {111, 1111, 11111};
- string uid1_wl1 = "wl1_1";
- std::vector<int> uids2 = {222, 2222, 22222};
- string uid2_wl1 = "wl2_1";
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1, /*acquire=*/1);
-
- // one matched start for uid1
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
- changedCache);
-
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- EXPECT_TRUE(changedCache[0]);
-
- // Now test query
- ConditionKey queryKey;
- conditionCache[0] = ConditionState::kNotEvaluated;
-
- conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // another wake lock acquired by this uid
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1, /*acquire=*/1);
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_FALSE(changedCache[0]);
-
- // uid1 wake lock 1 release
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1,
- /*release=*/0); // now release it.
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
- changedCache);
- // nothing changes, because uid2 is still holding wl.
- EXPECT_FALSE(changedCache[0]);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1,
- /*acquire=*/0); // now release it.
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
- changedCache);
- ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
- EXPECT_TRUE(changedCache[0]);
-
- // query again
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestStopAll) {
- std::vector<sp<ConditionTracker>> allConditions;
- for (Position position : {Position::FIRST, Position::LAST}) {
- SimplePredicate simplePredicate =
- getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
- true /*output slice by uid*/, position);
- string conditionName = "WL_HELD_BY_UID3";
-
- unordered_map<int64_t, int> trackerNameIndexMap;
- trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
- trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
- trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
- SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName),
- 0 /*condition tracker index*/, simplePredicate,
- trackerNameIndexMap);
-
- std::vector<int> uids1 = {111, 1111, 11111};
- std::vector<int> uids2 = {222, 2222, 22222};
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, "wl1", /*acquire=*/1);
-
- // one matched start
- vector<MatchingState> matcherState;
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- vector<sp<ConditionTracker>> allPredicates;
- vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
- vector<bool> changedCache(1, false);
-
- conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
- changedCache);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(changedCache[0]);
- {
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(uids1.size(),
- conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- }
- }
-
- // Now test query
- const auto queryKey = getWakeLockQueryKey(position, uids1, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
-
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // another wake lock acquired by uid2
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
- changedCache);
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
- } else {
- ASSERT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
- }
- EXPECT_TRUE(changedCache[0]);
- {
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(uids2.size(),
- conditionTracker.getChangedToTrueDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
- }
- }
-
- // TEST QUERY
- const auto queryKey2 = getWakeLockQueryKey(position, uids2, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-
- EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
- // stop all event
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
-
- matcherState.clear();
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kNotMatched);
- matcherState.push_back(MatchingState::kMatched);
-
- conditionCache[0] = ConditionState::kNotEvaluated;
- changedCache[0] = false;
- conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
- changedCache);
- EXPECT_TRUE(changedCache[0]);
- ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
- {
- if (position == Position::FIRST || position == Position::LAST) {
- ASSERT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- } else {
- EXPECT_EQ(uids1.size() + uids2.size(),
- conditionTracker.getChangedToFalseDimensions(allConditions)->size());
- EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
- }
- }
-
- // TEST QUERY
- const auto queryKey3 = getWakeLockQueryKey(position, uids1, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-
- // TEST QUERY
- const auto queryKey4 = getWakeLockQueryKey(position, uids2, conditionName);
- conditionCache[0] = ConditionState::kNotEvaluated;
- conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
- EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
deleted file mode 100644
index 93b278388a1b..000000000000
--- a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto alarm = config.add_alarm();
- alarm->set_id(123456);
- alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(TEN_MINUTES));
- alarm->set_period_millis(TimeUnitToBucketSizeInMillis(ONE_HOUR));
-
- alarm = config.add_alarm();
- alarm->set_id(654321);
- alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(FIVE_MINUTES));
- alarm->set_period_millis(TimeUnitToBucketSizeInMillis(THIRTY_MINUTES));
- return config;
-}
-
-} // namespace
-
-TEST(AlarmE2eTest, TestMultipleAlarms) {
- auto config = CreateStatsdConfig();
- int64_t bucketStartTimeNs = 10000000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size());
-
- auto alarmTracker1 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[0];
- auto alarmTracker2 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[1];
-
- int64_t alarmTimestampSec0 = bucketStartTimeNs / NS_PER_SEC + 10 * 60;
- int64_t alarmTimestampSec1 = bucketStartTimeNs / NS_PER_SEC + 5 * 60;
- EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
- EXPECT_EQ(alarmTimestampSec1, alarmTracker2->getAlarmTimestampSec());
-
- // Alarm fired.
- const int64_t alarmFiredTimestampSec0 = alarmTimestampSec1 + 5;
- auto alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec0));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onPeriodicAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
- EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
- EXPECT_EQ(alarmTimestampSec1 + 30 * 60, alarmTracker2->getAlarmTimestampSec());
-
- // Alarms fired very late.
- const int64_t alarmFiredTimestampSec1 = alarmTimestampSec0 + 2 * 60 * 60 + 125;
- alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec1));
- ASSERT_EQ(2u, alarmSet.size());
- processor->onPeriodicAlarmFired(alarmFiredTimestampSec1 * NS_PER_SEC, alarmSet);
- EXPECT_EQ(alarmTimestampSec0 + 60 * 60 * 3, alarmTracker1->getAlarmTimestampSec());
- EXPECT_EQ(alarmTimestampSec1 + 30 * 60 * 5, alarmTracker2->getAlarmTimestampSec());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
deleted file mode 100644
index af9436b98ec8..000000000000
--- a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets, int threshold, int refractory_period_sec) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- countMetric->set_bucket(FIVE_MINUTES);
-
- auto alert = config.add_alert();
- alert->set_id(StringToId("alert"));
- alert->set_metric_id(123456);
- alert->set_num_buckets(num_buckets);
- alert->set_refractory_period_secs(refractory_period_sec);
- alert->set_trigger_if_sum_gt(threshold);
- return config;
-}
-
-} // namespace
-
-TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket) {
- const int num_buckets = 1;
- const int threshold = 3;
- const int refractory_period_sec = 10;
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const uint64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
- std::vector<int> attributionUids3 = {111, 333};
- std::vector<string> attributionTags3 = {"App1", "App3"};
- std::vector<int> attributionUids4 = {222, 333};
- std::vector<string> attributionTags4 = {"GMSCoreModule1", "App3"};
- std::vector<int> attributionUids5 = {222};
- std::vector<string> attributionTags5 = {"GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)222));
- HashableDimensionKey whatKey2({fieldValue2});
- MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids4, attributionTags4,
- "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids5, attributionTags5,
- "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids3, attributionTags3,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids5, attributionTags5,
- "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- // Fired alarm and refractory period end timestamp updated.
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 5, attributionUids1, attributionTags1,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 100, attributionUids1, attributionTags1,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids4,
- attributionTags4, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids5,
- attributionTags5, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 3, attributionUids5,
- attributionTags5, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 4, attributionUids5,
- attributionTags5, "wl2");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 4) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-}
-
-TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets) {
- const int num_buckets = 3;
- const int threshold = 3;
- const int refractory_period_sec = 10;
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const uint64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Fired alarm and refractory period end timestamp updated.
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids1, attributionTags1,
- "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 2, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 3 * bucketSizeNs + 2) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written) {
- const int num_buckets = 1;
- const int threshold = 0;
- const int refractory_period_sec = 86400 * 365; // 1 year
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const int64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
-
- int configUid = 2000;
- int64_t configId = 1000;
- ConfigKey cfgKey(configUid, configId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- metadata::StatsMetadataList result;
- int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
- int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
- processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
-
- ASSERT_EQ(result.stats_metadata_size(), 0);
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk) {
- const int num_buckets = 1;
- const int threshold = 0;
- const int refractory_period_sec = 86400 * 365; // 1 year
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const int64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
-
- int configUid = 2000;
- int64_t configId = 1000;
- ConfigKey cfgKey(configUid, configId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 2) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- metadata::StatsMetadataList result;
- int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
- int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
- processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
-
- metadata::StatsMetadata statsMetadata = result.stats_metadata(0);
- ASSERT_EQ(result.stats_metadata_size(), 1);
- EXPECT_EQ(statsMetadata.config_key().config_id(), configId);
- EXPECT_EQ(statsMetadata.config_key().uid(), configUid);
-
- metadata::AlertMetadata alertMetadata = statsMetadata.alert_metadata(0);
- ASSERT_EQ(statsMetadata.alert_metadata_size(), 1);
- EXPECT_EQ(alertMetadata.alert_id(), alert_id);
- metadata::AlertDimensionKeyedData keyedData = alertMetadata.alert_dim_keyed_data(0);
- ASSERT_EQ(alertMetadata.alert_dim_keyed_data_size(), 1);
- EXPECT_EQ(keyedData.last_refractory_ends_sec(),
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
- mockElapsedTimeNs / NS_PER_SEC +
- mockWallClockNs / NS_PER_SEC);
-
- metadata::MetricDimensionKey metadataDimKey = keyedData.dimension_key();
- metadata::FieldValue dimKeyInWhat = metadataDimKey.dimension_key_in_what(0);
- EXPECT_EQ(dimKeyInWhat.field().tag(), fieldValue1.mField.getTag());
- EXPECT_EQ(dimKeyInWhat.field().field(), fieldValue1.mField.getField());
- EXPECT_EQ(dimKeyInWhat.value_int(), fieldValue1.mValue.int_value);
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk) {
- const int num_buckets = 1;
- const int threshold = 0;
- const int refractory_period_sec = 86400 * 365; // 1 year
- auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
- const int64_t alert_id = config.alert(0).id();
-
- int64_t bucketStartTimeNs = 10000000000;
-
- int configUid = 2000;
- int64_t configId = 1000;
- ConfigKey cfgKey(configUid, configId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
- std::vector<int> attributionUids2 = {111, 222};
- std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 2) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
- int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
- processor->SaveMetadataToDisk(mockWallClockNs, mockElapsedTimeNs);
-
- auto processor2 = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- int64_t mockElapsedTimeSinceBoot = 10 * NS_PER_SEC;
- processor2->LoadMetadataFromDisk(mockWallClockNs, mockElapsedTimeSinceBoot);
-
- sp<AnomalyTracker> anomalyTracker2 =
- processor2->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
- EXPECT_EQ(anomalyTracker2->getRefractoryPeriodEndsSec(dimensionKey1) -
- mockElapsedTimeSinceBoot / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
- mockElapsedTimeNs / NS_PER_SEC);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
deleted file mode 100644
index 06779aa89c0a..000000000000
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_ibinder.h>
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/StatsService.h"
-#include "src/anomaly/DurationAnomalyTracker.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int kConfigKey = 789130124;
-const int kCallingUid = 0;
-
-StatsdConfig CreateStatsdConfig(int num_buckets,
- uint64_t threshold_ns,
- DurationMetric::AggregationType aggregationType,
- bool nesting) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- FieldMatcher dimensions = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- dimensions.add_child()->set_field(3); // The wakelock tag is set in field 3 of the wakelock.
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- holdingWakelockPredicate.mutable_simple_predicate()->set_count_nesting(nesting);
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(screenIsOffPredicate.id());
- durationMetric->set_aggregation_type(aggregationType);
- *durationMetric->mutable_dimensions_in_what() =
- CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
-
- auto alert = config.add_alert();
- alert->set_id(StringToId("alert"));
- alert->set_metric_id(StringToId("WakelockDuration"));
- alert->set_num_buckets(num_buckets);
- alert->set_refractory_period_secs(2);
- alert->set_trigger_if_sum_gt(threshold_ns);
- return config;
-}
-
-std::vector<int> attributionUids1 = {111, 222};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1"};
-
-std::vector<int> attributionUids2 = {111, 222};
-std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1"};
-
-std::vector<int> attributionUids3 = {222};
-std::vector<string> attributionTags3 = {"GMSCoreModule1"};
-
-MetricDimensionKey dimensionKey1(
- HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
- (int32_t)0x02010101),
- Value((int32_t)111))}),
- DEFAULT_DIMENSION_KEY);
-
-MetricDimensionKey dimensionKey2(
- HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
- (int32_t)0x02010101), Value((int32_t)222))}),
- DEFAULT_DIMENSION_KEY);
-
-void sendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
- string str;
- config.SerializeToString(&str);
- std::vector<int8_t> configAsVec(str.begin(), str.end());
- service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
-}
-
-} // namespace
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
- const int num_buckets = 1;
- const uint64_t threshold_ns = NS_PER_SEC;
- auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- sendConfig(service, config);
-
- auto processor = service->mProcessor;
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- int64_t bucketStartTimeNs = processor->mTimeBaseNs;
- int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- auto screen_on_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screen_off_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 10, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_on_event.get());
- processor->OnLogEvent(screen_off_event.get());
-
- // Acquire wakelock wl1.
- auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 11, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 11 + threshold_ns) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock wl1. No anomaly detected. Alarm cancelled at the "release" event.
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 101, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock wl1 within bucket #0.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 110, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 110 + threshold_ns - 90) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock wl1. One anomaly detected.
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 109,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock wl1.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 112,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- // Wakelock has been hold longer than the threshold in bucket #0. The alarm is set at the
- // end of the refractory period.
- const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
- (uint32_t)alarmFiredTimestampSec0);
- EXPECT_EQ(alarmFiredTimestampSec0,
- processor->getAnomalyAlarmMonitor()->getRegisteredAlarmTimeSec());
-
- // Anomaly alarm fired.
- auto alarmTriggerEvent = CreateBatterySaverOnEvent(alarmFiredTimestampSec0 * NS_PER_SEC);
- processor->OnLogEvent(alarmTriggerEvent.get(), alarmFiredTimestampSec0 * NS_PER_SEC);
-
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock wl1.
- release_event =
- CreateReleaseWakelockEvent(alarmFiredTimestampSec0 * NS_PER_SEC + NS_PER_SEC + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Within refractory period. No more anomaly detected.
- EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock wl1.
- acquire_event = CreateAcquireWakelockEvent(
- roundedBucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
- (uint64_t)alarmFiredTimestampSec1);
-
- // Release wakelock wl1.
- int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec1));
- ASSERT_EQ(0u, alarmSet.size());
-
- // Acquire wakelock wl1 near the end of bucket #0.
- acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 2,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- // Release the event at early bucket #1.
- release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Anomaly detected when stopping the alarm. The refractory period does not change.
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Condition changes to false.
- screen_on_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 20,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- processor->OnLogEvent(screen_on_event.get());
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 30,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- // The condition is false. Do not start the alarm.
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Condition turns true.
- screen_off_event =
- CreateScreenStateChangedEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- // Condition turns to false.
- int64_t condition_false_time = bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1;
- screen_on_event = CreateScreenStateChangedEvent(
- condition_false_time, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- processor->OnLogEvent(screen_on_event.get(), condition_false_time);
- // Condition turns to false. Cancelled the alarm.
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Detected one anomaly.
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Condition turns to true again.
- screen_off_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 2,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
- const int num_buckets = 3;
- const uint64_t threshold_ns = NS_PER_SEC;
- auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- sendConfig(service, config);
-
- auto processor = service->mProcessor;
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- int64_t bucketStartTimeNs = processor->mTimeBaseNs;
- int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- auto screen_off_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
-
- // Acquire wakelock "wc1" in bucket #0.
- auto acquire_event =
- CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock "wc1" in bucket #0.
- int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 1;
- auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock "wc1" in bucket #1.
- acquire_event =
- CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 1,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 100;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire wakelock "wc2" in bucket #2.
- acquire_event =
- CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + 1,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3,
- anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- // Release wakelock "wc2" in bucket #2.
- release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
- attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
- // Acquire wakelock "wc1" in bucket #2.
- acquire_event =
- CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((roundedBucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3 + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Release wakelock "wc1" in bucket #2.
- release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3.5 * NS_PER_SEC;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
- attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 4,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(acquire_event.get());
- acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 5,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
- anomalyTracker->getAlarmTimestampSec(dimensionKey2));
-
- release_event_time = roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC + 2;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
- attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get(), release_event_time);
- release_event = CreateReleaseWakelockEvent(release_event_time + 4, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time + 4);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- // The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
- EXPECT_EQ(refractory_period_sec +
- (int64_t)(roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC) /
- NS_PER_SEC +
- 1,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
- const int num_buckets = 2;
- const uint64_t threshold_ns = 3 * NS_PER_SEC;
- auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
- const uint64_t alert_id = config.alert(0).id();
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
- const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
- config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
-
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- sendConfig(service, config);
-
- auto processor = service->mProcessor;
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
- int64_t bucketStartTimeNs = processor->mTimeBaseNs;
- int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
-
- sp<AnomalyTracker> anomalyTracker =
- processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
- auto screen_off_event = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screen_off_event.get());
-
- // Acquire wakelock "wc1" in bucket #0.
- auto acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 100,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Acquire the wakelock "wc1" again.
- acquire_event =
- CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- // The alarm does not change.
- EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // Anomaly alarm fired late.
- const int64_t firedAlarmTimestampNs = roundedBucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
- auto alarmTriggerEvent = CreateBatterySaverOnEvent(firedAlarmTimestampNs);
- processor->OnLogEvent(alarmTriggerEvent.get(), firedAlarmTimestampNs);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs - 100,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- int64_t release_event_time = bucketStartTimeNs + 2 * bucketSizeNs + 1;
- auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- // Within the refractory period. No anomaly.
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- // A new wakelock, but still within refractory period.
- acquire_event = CreateAcquireWakelockEvent(
- roundedBucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- release_event =
- CreateReleaseWakelockEvent(roundedBucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
- // Still in the refractory period. No anomaly.
- processor->OnLogEvent(release_event.get());
- EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(
- roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 5, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- release_event_time = roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 4;
- release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get(), release_event_time);
- EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
- acquire_event = CreateAcquireWakelockEvent(
- roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 3, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
- anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
deleted file mode 100644
index 4c2caa904f6a..000000000000
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <iostream>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(const Position position) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
- auto attributionNodeMatcher =
- wakelockAcquireMatcher.mutable_simple_atom_matcher()->add_field_value_matcher();
- attributionNodeMatcher->set_field(1);
- attributionNodeMatcher->set_position(Position::ANY);
- auto uidMatcher = attributionNodeMatcher->mutable_matches_tuple()->add_field_value_matcher();
- uidMatcher->set_field(1); // uid field.
- uidMatcher->set_eq_string("com.android.gmscore");
-
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- *countMetric->mutable_dimensions_in_what() =
- CreateAttributionUidAndTagDimensions(
- util::WAKELOCK_STATE_CHANGED, {position});
- countMetric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-// GMS core node is in the middle.
-std::vector<int> attributionUids1 = {111, 222, 333};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "App3"};
-
-// GMS core node is the last one.
-std::vector<int> attributionUids2 = {111, 333, 222};
-std::vector<string> attributionTags2 = {"App1", "App3", "GMSCoreModule1"};
-
-// GMS core node is the first one.
-std::vector<int> attributionUids3 = {222, 333};
-std::vector<string> attributionTags3 = {"GMSCoreModule1", "App3"};
-
-// Single GMS core node.
-std::vector<int> attributionUids4 = {222};
-std::vector<string> attributionTags4 = {"GMSCoreModule1"};
-
-// GMS core has another uid.
-std::vector<int> attributionUids5 = {111, 444, 333};
-std::vector<string> attributionTags5 = {"App1", "GMSCoreModule2", "App3"};
-
-// Multiple GMS core nodes.
-std::vector<int> attributionUids6 = {444, 222};
-std::vector<string> attributionTags6 = {"GMSCoreModule2", "GMSCoreModule1"};
-
-// No GMS core nodes
-std::vector<int> attributionUids7 = {111, 333};
-std::vector<string> attributionTags7 = {"App1", "App3"};
-
-std::vector<int> attributionUids8 = {111};
-std::vector<string> attributionTags8 = {"App1"};
-
-// GMS core node with isolated uid.
-const int isolatedUid = 666;
-std::vector<int> attributionUids9 = {isolatedUid};
-std::vector<string> attributionTags9 = {"GMSCoreModule3"};
-
-std::vector<int> attributionUids10 = {isolatedUid};
-std::vector<string> attributionTags10 = {"GMSCoreModule1"};
-
-} // namespace
-
-TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) {
- auto config = CreateStatsdConfig(Position::FIRST);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- // Here it assumes that GMS core has two uids.
- processor->getUidMap()->updateMap(
- 1, {222, 444, 111, 333}, {1, 1, 2, 2},
- {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
- {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
- String16("APP3")},
- {String16(""), String16(""), String16(""), String16("")});
-
- std::vector<std::unique_ptr<LogEvent>> events;
- // Events 1~4 are in the 1st bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
- attributionTags2, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids3, attributionTags3, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
- attributionTags4, "wl1"));
-
- // Events 5~8 are in the 3rd bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids5, attributionTags5, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids6, attributionTags6, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
- attributionUids7, attributionTags7, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
- attributionUids8, attributionTags8, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
- attributionUids9, attributionTags9, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
- attributionUids9, attributionTags9, "wl2"));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
- isolatedUid, true /*is_create*/));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
- isolatedUid, false /*is_create*/));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(countMetrics.data_size(), 4);
-
- auto data = countMetrics.data(0);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ASSERT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).count(), 2);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).count(), 1);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
-
- data = countMetrics.data(1);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(data.bucket_info_size(), 2);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).count(), 1);
- EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
-
- data = countMetrics.data(2);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 3 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 4 * bucketSizeNs);
-
- data = countMetrics.data(3);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 444,
- "GMSCoreModule2");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
-}
-
-TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) {
- auto config = CreateStatsdConfig(Position::ALL);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- // Here it assumes that GMS core has two uids.
- processor->getUidMap()->updateMap(
- 1, {222, 444, 111, 333}, {1, 1, 2, 2},
- {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
- {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
- String16("APP3")},
- {String16(""), String16(""), String16(""), String16("")});
-
- std::vector<std::unique_ptr<LogEvent>> events;
- // Events 1~4 are in the 1st bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
- attributionTags2, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids3, attributionTags3, "wl1"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
- attributionTags4, "wl1"));
-
- // Events 5~8 are in the 3rd bucket.
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids5, attributionTags5, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids6, attributionTags6, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
- attributionUids7, attributionTags7, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
- attributionUids8, attributionTags8, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
- attributionUids10, attributionTags10, "wl2"));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
- attributionUids10, attributionTags10, "wl2"));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
- isolatedUid, true /*is_create*/));
- events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
- isolatedUid, false /*is_create*/));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(countMetrics.data_size(), 6);
-
- auto data = countMetrics.data(0);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(1, data.bucket_info(1).count());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
- EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
- data = countMetrics.data(2);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 444);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 444,
- "GMSCoreModule2");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 222);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
- util::WAKELOCK_STATE_CHANGED, 222,
- "GMSCoreModule1");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(5);
- ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
- util::WAKELOCK_STATE_CHANGED, 111, "App1");
- ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 444);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
- util::WAKELOCK_STATE_CHANGED, 444,
- "GMSCoreModule2");
- ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
- ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
- util::WAKELOCK_STATE_CHANGED, 333, "App3");
- ASSERT_EQ(data.bucket_info_size(), 1);
- EXPECT_EQ(data.bucket_info(0).count(), 1);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
deleted file mode 100644
index 0bce0baa049b..000000000000
--- a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-
- *config.add_atom_matcher() = wakelockAcquireMatcher;
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(123456);
- countMetric->set_what(wakelockAcquireMatcher.id());
- *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- countMetric->set_bucket(FIVE_MINUTES);
-
- auto alert = config.add_alert();
- alert->set_id(StringToId("alert"));
- alert->set_metric_id(123456);
- alert->set_num_buckets(num_buckets);
- alert->set_refractory_period_secs(10);
- alert->set_trigger_if_sum_gt(threshold);
-
- // Two hours
- config.set_ttl_in_seconds(2 * 3600);
- return config;
-}
-
-} // namespace
-
-TEST(ConfigTtlE2eTest, TestCountMetric) {
- const int num_buckets = 1;
- const int threshold = 3;
- auto config = CreateStatsdConfig(num_buckets, threshold);
- const uint64_t alert_id = config.alert(0).id();
- const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- std::vector<int> attributionUids1 = {111};
- std::vector<string> attributionTags1 = {"App1"};
-
- FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)111));
- HashableDimensionKey whatKey1({fieldValue1});
- MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
- FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
- Value((int32_t)222));
- HashableDimensionKey whatKey2({fieldValue2});
- MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids1,
- attributionTags1, "wl2");
- processor->OnLogEvent(event.get());
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * bucketSizeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- processor->OnLogEvent(event.get());
-
- EXPECT_EQ((int64_t)(bucketStartTimeNs + 25 * bucketSizeNs + 2 + 2 * 3600 * NS_PER_SEC),
- processor->mMetricsManagers.begin()->second->getTtlEndNs());
-
- // Clear the data stored on disk as a result of the ttl.
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 25 * bucketSizeNs + 3, false, true,
- ADB_DUMP, FAST, &buffer);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
deleted file mode 100644
index 04eb40080631..000000000000
--- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/state/StateManager.h"
-#include "src/state/StateTracker.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-/**
- * Tests the initial condition and condition after the first log events for
- * count metrics with either a combination condition or simple condition.
- *
- * Metrics should be initialized with condition kUnknown (given that the
- * predicate is using the default InitialValue of UNKNOWN). The condition should
- * be updated to either kFalse or kTrue if a condition event is logged for all
- * children conditions.
- */
-TEST(CountMetricE2eTest, TestInitialConditionChanges) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto syncStartMatcher = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = syncStartMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
- auto screenOnPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnPredicate;
-
- auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
- *config.add_predicate() = deviceUnpluggedPredicate;
-
- auto screenOnOnBatteryPredicate = config.add_predicate();
- screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
- screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
- addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
-
- // CountSyncStartWhileScreenOnOnBattery (CombinationCondition)
- CountMetric* countMetric1 = config.add_count_metric();
- countMetric1->set_id(StringToId("CountSyncStartWhileScreenOnOnBattery"));
- countMetric1->set_what(syncStartMatcher.id());
- countMetric1->set_condition(screenOnOnBatteryPredicate->id());
- countMetric1->set_bucket(FIVE_MINUTES);
-
- // CountSyncStartWhileOnBattery (SimpleCondition)
- CountMetric* countMetric2 = config.add_count_metric();
- countMetric2->set_id(StringToId("CountSyncStartWhileOnBatterySliceScreen"));
- countMetric2->set_what(syncStartMatcher.id());
- countMetric2->set_condition(deviceUnpluggedPredicate.id());
- countMetric2->set_bucket(FIVE_MINUTES);
-
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- EXPECT_EQ(2, metricsManager->mAllMetricProducers.size());
-
- sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
- sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
-
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 30, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
- bucketStartTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
- processor->OnLogEvent(pluggedUsbEvent.get());
- EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
-
- auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
- bucketStartTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
- processor->OnLogEvent(pluggedNoneEvent.get());
- EXPECT_EQ(ConditionState::kTrue, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
-}
-
-/**
-* Test a count metric that has one slice_by_state with no primary fields.
-*
-* Once the CountMetricProducer is initialized, it has one atom id in
-* mSlicedStateAtoms and no entries in mStateGroupMap.
-
-* One StateTracker tracks the state atom, and it has one listener which is the
-* CountMetricProducer that was initialized.
-*/
-TEST(CountMetricE2eTest, TestSlicedState) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto syncStartMatcher = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = syncStartMatcher;
-
- auto state = CreateScreenState();
- *config.add_state() = state;
-
- // Create count metric that slices by screen state.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(syncStartMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state.id());
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- x x x x x x (syncStartEvents)
- | | (ScreenIsOnEvent)
- | | (ScreenIsOffEvent)
- | (ScreenDozeEvent)
- */
- // Initialize log events - first bucket.
- std::vector<int> attributionUids1 = {123};
- std::vector<string> attributionTags1 = {"App1"};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 50 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 1:00
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 75 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 1:25
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 2:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 3:30
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 4:20
-
- // Initialize log events - second bucket.
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 350 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 6:00
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 6:50
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 450 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 7:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 475 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 8:05
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 500 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 8:30
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 520 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 8:50
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(3, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(2, data.bucket_info(1).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(1, data.bucket_info(1).count());
-}
-
-/**
- * Test a count metric that has one slice_by_state with a mapping and no
- * primary fields.
- *
- * Once the CountMetricProducer is initialized, it has one atom id in
- * mSlicedStateAtoms and has one entry per state value in mStateGroupMap.
- *
- * One StateTracker tracks the state atom, and it has one listener which is the
- * CountMetricProducer that was initialized.
- */
-TEST(CountMetricE2eTest, TestSlicedStateWithMap) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto syncStartMatcher = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = syncStartMatcher;
-
- int64_t screenOnId = 4444;
- int64_t screenOffId = 9876;
- auto state = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
- *config.add_state() = state;
-
- // Create count metric that slices by screen state with on/off map.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(syncStartMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state.id());
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-
- StateMap map = state.map();
- for (auto group : map.group()) {
- for (auto value : group.value()) {
- EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
- group.group_id());
- }
- }
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- x x x x x x x x x (syncStartEvents)
- -----------------------------------------------------------SCREEN_OFF events
- | | (ScreenStateOffEvent = 1)
- | | (ScreenStateDozeEvent = 3)
- | (ScreenStateDozeSuspendEvent =
- 4)
- -----------------------------------------------------------SCREEN_ON events
- | | (ScreenStateOnEvent = 2)
- | (ScreenStateVrEvent = 5)
- | (ScreenStateOnSuspendEvent = 6)
- */
- // Initialize log events - first bucket.
- std::vector<int> attributionUids1 = {123};
- std::vector<string> attributionTags1 = {"App1"};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 20 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 30 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 0:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 1:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 120 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 2:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 180 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_VR)); // 3:10
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 210 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:40
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 4:20
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 280 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:50
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 285 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 4:55
-
- // Initialize log events - second bucket.
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 360 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 6:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 430 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND)); // 7:20
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 440 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 7:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 540 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 9:10
- events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 570 * NS_PER_SEC, attributionUids1,
- attributionTags1, "sync_name")); // 9:40
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(3, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(1, data.bucket_info(1).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(4, data.bucket_info(0).count());
- EXPECT_EQ(2, data.bucket_info(1).count());
-}
-
-/**
-* Test a count metric that has one slice_by_state with a primary field.
-
-* Once the CountMetricProducer is initialized, it should have one
-* MetricStateLink stored. State querying using a non-empty primary key
-* should also work as intended.
-*/
-TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto appCrashMatcher =
- CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
- *config.add_atom_matcher() = appCrashMatcher;
-
- auto state = CreateUidProcessState();
- *config.add_state() = state;
-
- // Create count metric that slices by uid process state.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state.id());
- MetricStateLink* stateLink = countMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
- ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
-
- /*
- NOTE: "1" or "2" represents the uid associated with the state/app crash event
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10
- |------------------------|-------------------------|--
- 1 1 1 1 1 2 1 1 2 (AppCrashEvents)
- -----------------------------------------------------PROCESS STATE events
- 1 2 (TopEvent = 1002)
- 1 1 (ForegroundServiceEvent = 1003)
- 2 (ImportantBackgroundEvent = 1006)
- 1 1 1 (ImportantForegroundEvent = 1005)
-
- Based on the diagram above, an AppCrashEvent querying for process state value would return:
- - StateTracker::kStateUnknown
- - Important foreground
- - Top
- - Important foreground
- - Foreground service
- - Top (both the app crash and state still have matching uid = 2)
-
- - Foreground service
- - Foreground service
- - Important background
- */
- // Initialize log events - first bucket.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 1:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/)); // 2:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 2:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/)); // 3:30
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 210 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 3:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/)); // 4:20
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 4:50
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/)); // 4:55
-
- // Initialize log events - second bucket.
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/)); // 6:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 6:40
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 430 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 7:20
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 440 * NS_PER_SEC, 1 /*uid*/)); // 7:30
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 9:10
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/)); // 9:40
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(2, data.bucket_info(1).count());
-
- data = countMetrics.data(3);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
-
- data = countMetrics.data(4);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-}
-
-TEST(CountMetricE2eTest, TestMultipleSlicedStates) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto appCrashMatcher =
- CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
- *config.add_atom_matcher() = appCrashMatcher;
-
- int64_t screenOnId = 4444;
- int64_t screenOffId = 9876;
- auto state1 = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
- *config.add_state() = state1;
- auto state2 = CreateUidProcessState();
- *config.add_state() = state2;
-
- // Create count metric that slices by screen state with on/off map and
- // slices by uid process state.
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- countMetric->add_slice_by_state(state1.id());
- countMetric->add_slice_by_state(state2.id());
- MetricStateLink* stateLink = countMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were properly initialized.
- EXPECT_EQ(2, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Check that CountMetricProducer was initialized correctly.
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(1), UID_PROCESS_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
- ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
-
- StateMap map = state1.map();
- for (auto group : map.group()) {
- for (auto value : group.value()) {
- EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
- group.group_id());
- }
- }
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |------------------------|------------------------|--
- 1 1 1 1 1 2 1 1 2 (AppCrashEvents)
- ---------------------------------------------------SCREEN_OFF events
- | | (ScreenOffEvent = 1)
- | | (ScreenDozeEvent = 3)
- ---------------------------------------------------SCREEN_ON events
- | | (ScreenOnEvent = 2)
- | (ScreenOnSuspendEvent = 6)
- ---------------------------------------------------PROCESS STATE events
- 1 2 (TopEvent = 1002)
- 1 (ForegroundServiceEvent = 1003)
- 2 (ImportantBackgroundEvent = 1006)
- 1 1 1 (ImportantForegroundEvent = 1005)
-
- Based on the diagram above, Screen State / Process State pairs for each
- AppCrashEvent are:
- - StateTracker::kStateUnknown / important foreground
- - off / important foreground
- - off / Top
- - on / important foreground
- - off / important foreground
- - off / top
-
- - off / important foreground
- - off / foreground service
- - on / important background
-
- */
- // Initialize log events - first bucket.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 5 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:15
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 30 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 0:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 1:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 90 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/)); // 2:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 2:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 160 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:50
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/)); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 210 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:40
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/)); // 4:20
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 4:50
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/)); // 4:55
-
- // Initialize log events - second bucket.
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/)); // 6:10
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 380 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 6:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 420 * NS_PER_SEC, 2 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 7:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 440 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 7:30
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 450 * NS_PER_SEC, 1 /*uid*/)); // 7:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 520 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 8:50
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 9:10
- events.push_back(
- CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/)); // 9:40
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(6, countMetrics.data_size());
-
- // For each CountMetricData, check StateValue info is correct and buckets
- // have correct counts.
- auto data = countMetrics.data(0);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1, data.slice_by_state(0).value());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(1);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(2);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(3);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
-
- data = countMetrics.data(4);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
-
- data = countMetrics.data(5);
- ASSERT_EQ(2, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
- EXPECT_TRUE(data.slice_by_state(1).has_value());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).count());
- EXPECT_EQ(1, data.bucket_info(1).count());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
deleted file mode 100644
index 4efb038e538d..000000000000
--- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ /dev/null
@@ -1,1473 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/state/StateTracker.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-TEST(DurationMetricE2eTest, TestOneBucket) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = screenOffMatcher;
-
- auto durationPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = durationPredicate;
-
- int64_t metricId = 123456;
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(metricId);
- durationMetric->set_what(durationPredicate.id());
- durationMetric->set_bucket(FIVE_MINUTES);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- const int64_t baseTimeNs = 0; // 0:00
- const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
- const int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
-
- std::unique_ptr<LogEvent> event;
-
- // Screen is off at start of bucket.
- event = CreateScreenStateChangedEvent(configAddedTimeNs,
- android::view::DISPLAY_STATE_OFF); // 0:01
- processor->OnLogEvent(event.get());
-
- // Turn screen on.
- const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
-
- // Turn off screen 30 seconds after turning on.
- const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
- event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(event.get());
-
- event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64); // 0:42
- processor->OnLogEvent(event.get());
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
- ADB_DUMP, FAST, &buffer); // 5:01
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestTwoBuckets) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = screenOffMatcher;
-
- auto durationPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = durationPredicate;
-
- int64_t metricId = 123456;
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(metricId);
- durationMetric->set_what(durationPredicate.id());
- durationMetric->set_bucket(FIVE_MINUTES);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- const int64_t baseTimeNs = 0; // 0:00
- const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
- const int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
-
- std::unique_ptr<LogEvent> event;
-
- // Screen is off at start of bucket.
- event = CreateScreenStateChangedEvent(configAddedTimeNs,
- android::view::DISPLAY_STATE_OFF); // 0:01
- processor->OnLogEvent(event.get());
-
- // Turn screen on.
- const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
-
- // Turn off screen 30 seconds after turning on.
- const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
- event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(event.get());
-
- event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64); // 0:42
- processor->OnLogEvent(event.get());
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false,
- true, ADB_DUMP, FAST, &buffer); // 10:01
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(0, bucketInfo.bucket_num());
- EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
- EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithActivation) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = screenOffMatcher;
- *config.add_atom_matcher() = crashMatcher;
-
- auto durationPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = durationPredicate;
-
- int64_t metricId = 123456;
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(metricId);
- durationMetric->set_what(durationPredicate.id());
- durationMetric->set_bucket(FIVE_MINUTES);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(crashMatcher.id());
- event_activation1->set_ttl_seconds(30); // 30 secs.
-
- const int64_t bucketStartTimeNs = 10000000000;
- const int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config); // 0:00
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- ASSERT_EQ(eventActivationMap.size(), 1u);
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- std::unique_ptr<LogEvent> event;
-
- // Turn screen off.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * NS_PER_SEC,
- android::view::DISPLAY_STATE_OFF); // 0:02
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 2 * NS_PER_SEC);
-
- // Turn screen on.
- const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:05
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), durationStartNs);
-
- // Activate metric.
- const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:10
- const int64_t activationEndNs =
- activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 0:40
- event = CreateAppCrashEvent(activationStartNs, 111);
- processor.OnLogEvent(event.get(), activationStartNs);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- // Expire activation.
- const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
- event = CreateScreenBrightnessChangedEvent(expirationNs, 64); // 0:47
- processor.OnLogEvent(event.get(), expirationNs);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- ASSERT_EQ(eventActivationMap.size(), 1u);
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- // Turn off screen 10 seconds after activation expiration.
- const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC; // 0:50
- event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
- processor.OnLogEvent(event.get(), durationEndNs);
-
- // Turn screen on.
- const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC; // 0:55
- event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), duration2StartNs);
-
- // Turn off screen.
- const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC; // 1:05
- event = CreateScreenStateChangedEvent(duration2EndNs, android::view::DISPLAY_STATE_OFF);
- processor.OnLogEvent(event.get(), duration2EndNs);
-
- // Activate metric.
- const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC; // 1:10
- const int64_t activation2EndNs =
- activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 1:40
- event = CreateAppCrashEvent(activation2StartNs, 211);
- processor.OnLogEvent(event.get(), activation2StartNs);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
- ADB_DUMP, FAST, &buffer); // 5:01
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(0, bucketInfo.bucket_num());
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(isInBackgroundPredicate.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- ConfigKey cfgKey;
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_TRUE(eventActivationMap.empty());
-
- int appUid = 123;
- vector<int> attributionUids1 = {appUid};
- vector<string> attributionTags1 = {"App1"};
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1,
- "wl1"); // 0:10
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid); // 0:22
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
- appUid); // 3:15
- processor->OnLogEvent(event.get());
-
- event = CreateReleaseWakelockEvent(bucketStartTimeNs + 4 * 60 * NS_PER_SEC, attributionUids1,
- attributionTags1,
- "wl1"); // 4:00
- processor->OnLogEvent(event.get());
-
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
-
- // Validate bucket info.
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by first attribution node by uid.
- FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
- {Position::FIRST});
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(isInBackgroundPredicate.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- // The metric is dimensioning by first attribution node and only by uid.
- *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Links between wakelock state atom and condition of app is in background.
- auto links = durationMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::WAKELOCK_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
-
- ConfigKey cfgKey;
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_TRUE(eventActivationMap.empty());
-
- int appUid = 123;
- std::vector<int> attributionUids1 = {appUid};
- std::vector<string> attributionTags1 = {"App1"};
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1"); // 0:10
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid); // 0:22
- processor->OnLogEvent(event.get());
-
- event = CreateReleaseWakelockEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1"); // 1:00
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
- appUid); // 3:15
- processor->OnLogEvent(event.get());
-
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, appUid);
- // Validate bucket info.
- ASSERT_EQ(1, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
- *config.add_atom_matcher() = screenOnMatcher;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by first attribution node by uid.
- FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
- {Position::FIRST});
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(isInBackgroundPredicate.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- // The metric is dimensioning by first attribution node and only by uid.
- *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Links between wakelock state atom and condition of app is in background.
- auto links = durationMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::WAKELOCK_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(durationMetric->id());
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(screenOnMatcher.id());
- event_activation1->set_ttl_seconds(60 * 2); // 2 minutes.
-
- ConfigKey cfgKey;
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- ASSERT_EQ(eventActivationMap.size(), 1u);
- EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- int appUid = 123;
- std::vector<int> attributionUids1 = {appUid};
- std::vector<string> attributionTags1 = {"App1"};
-
- auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
- attributionTags1, "wl1"); // 0:10
- processor->OnLogEvent(event.get());
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid); // 0:22
- processor->OnLogEvent(event.get());
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC; // 0:30
- event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- const int64_t durationEndNs =
- durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC; // 3:00
- event = CreateAppCrashEvent(durationEndNs, 333);
- processor->OnLogEvent(event.get());
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
- appUid); // 3:15
- processor->OnLogEvent(event.get());
-
- event = CreateReleaseWakelockEvent(bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1"); // 4:17
- processor->OnLogEvent(event.get());
-
- event = CreateMoveToBackgroundEvent(bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC,
- appUid); // 4:20
- processor->OnLogEvent(event.get());
-
- event = CreateAcquireWakelockEvent(bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1"); // 4:25
- processor->OnLogEvent(event.get());
-
- const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC; // 4:30
- event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(event.get());
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
- EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(1, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, appUid);
- // Validate bucket info.
- ASSERT_EQ(2, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
-
- bucketInfo = data.bucket_info(1);
- EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedState) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-
- auto batterySaverModePredicate = CreateBatterySaverModePredicate();
- *config.add_predicate() = batterySaverModePredicate;
-
- auto screenState = CreateScreenState();
- *config.add_state() = screenState;
-
- // Create duration metric that slices by screen state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreen"));
- durationMetric->set_what(batterySaverModePredicate.id());
- durationMetric->add_slice_by_state(screenState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- ON OFF ON (BatterySaverMode)
- | | | (ScreenIsOnEvent)
- | | (ScreenIsOffEvent)
- | (ScreenDozeEvent)
- */
- // Initialize log events.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 10 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC)); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 50 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:00
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 80 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 1:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 120 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:10
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC)); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 250 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC)); // 4:50
-
- // Bucket boundary.
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 310 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 5:20
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 360 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer); // 6:10
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(3, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
- *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
- auto batterySaverModePredicate = CreateBatterySaverModePredicate();
- *config.add_predicate() = batterySaverModePredicate;
-
- auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
- *config.add_predicate() = deviceUnpluggedPredicate;
-
- auto screenState = CreateScreenState();
- *config.add_state() = screenState;
-
- // Create duration metric that has a condition and slices by screen state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationBatterySaverModeOnBatterySliceScreen"));
- durationMetric->set_what(batterySaverModePredicate.id());
- durationMetric->set_condition(deviceUnpluggedPredicate.id());
- durationMetric->add_slice_by_state(screenState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 (minutes)
- |---------------------------------------|------------------
- ON OFF ON (BatterySaverMode)
- T F T (DeviceUnpluggedPredicate)
- | | | (ScreenIsOnEvent)
- | | | (ScreenIsOffEvent)
- | (ScreenDozeEvent)
- */
- // Initialize log events.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 20 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:30
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 60 * NS_PER_SEC)); // 1:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 80 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:30
- events.push_back(
- CreateBatteryStateChangedEvent(bucketStartTimeNs + 110 * NS_PER_SEC,
- BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE)); // 2:00
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 145 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:35
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 170 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 3:00
- events.push_back(
- CreateBatteryStateChangedEvent(bucketStartTimeNs + 180 * NS_PER_SEC,
- BatteryPluggedStateEnum::BATTERY_PLUGGED_USB)); // 3:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:30
- events.push_back(
- CreateBatteryStateChangedEvent(bucketStartTimeNs + 230 * NS_PER_SEC,
- BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE)); // 4:00
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 260 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 4:30
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 280 * NS_PER_SEC)); // 4:50
-
- // Bucket boundary.
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 320 * NS_PER_SEC)); // 5:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 380 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 6:30
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 410 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(3, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(60 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(2);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedStateMapped) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-
- auto batterySaverModePredicate = CreateBatterySaverModePredicate();
- *config.add_predicate() = batterySaverModePredicate;
-
- int64_t screenOnId = 4444;
- int64_t screenOffId = 9876;
- auto screenStateWithMap = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
- *config.add_state() = screenStateWithMap;
-
- // Create duration metric that slices by mapped screen state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreenMapped"));
- durationMetric->set_what(batterySaverModePredicate.id());
- durationMetric->add_slice_by_state(screenStateWithMap.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- /*
- bucket #1 bucket #2
- | 1 2 3 4 5 6 7 8 9 10 (minutes)
- |-----------------------------|-----------------------------|--
- ON OFF ON (BatterySaverMode)
- ---------------------------------------------------------SCREEN_OFF events
- | | (ScreenStateOffEvent = 1)
- | (ScreenStateDozeEvent = 3)
- | (ScreenStateDozeSuspendEvent = 4)
- ---------------------------------------------------------SCREEN_ON events
- | | | (ScreenStateOnEvent = 2)
- | (ScreenStateVrEvent = 5)
- | (ScreenStateOnSuspendEvent = 6)
- */
- // Initialize log events.
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 10 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC)); // 0:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 70 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:20
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 100 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 1:50
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 120 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:10
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 170 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_VR)); // 3:00
- events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC)); // 3:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 250 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:20
- events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC)); // 4:50
-
- // Bucket boundary 5:10.
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 320 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 5:30
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 390 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
- events.push_back(CreateScreenStateChangedEvent(
- bucketStartTimeNs + 430 * NS_PER_SEC,
- android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND)); // 7:20
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 490 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(2, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(130 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(80 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create duration metric that slices by uid process state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationHoldingWakelockSliceUidProcessState"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->add_slice_by_state(uidProcessState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // The state has only one primary field (uid).
- auto stateLink = durationMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // This config is rejected because the dimension in what fields are not a superset of the sliced
- // state primary fields.
- ASSERT_EQ(processor->mMetricsManagers.size(), 0);
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset) {
- // Initialize config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create duration metric that slices by uid process state.
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("DurationPartialWakelockPerTagUidSliceProcessState"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->add_slice_by_state(uidProcessState.id());
- durationMetric->set_aggregation_type(DurationMetric::SUM);
- durationMetric->set_bucket(FIVE_MINUTES);
-
- // The metric is dimensioning by first uid of attribution node and tag.
- *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
- // The state has only one primary field (uid).
- auto stateLink = durationMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
- // Initialize StatsLogProcessor.
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- uint64_t bucketStartTimeNs = 10000000000; // 0:10
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- EXPECT_TRUE(metricsManager->isActive());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- EXPECT_TRUE(metricProducer->mIsActive);
- ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
- EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
- ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Initialize log events.
- int appUid1 = 1001;
- int appUid2 = 1002;
- std::vector<int> attributionUids1 = {appUid1};
- std::vector<string> attributionTags1 = {"App1"};
-
- std::vector<int> attributionUids2 = {appUid2};
- std::vector<string> attributionTags2 = {"App2"};
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 10 * NS_PER_SEC, appUid1,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:20
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
- attributionUids1, attributionTags1,
- "wakelock1")); // 0:30
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * NS_PER_SEC,
- attributionUids1, attributionTags1,
- "wakelock2")); // 0:35
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 30 * NS_PER_SEC,
- attributionUids2, attributionTags2,
- "wakelock1")); // 0:40
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC,
- attributionUids2, attributionTags2,
- "wakelock2")); // 0:45
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 50 * NS_PER_SEC, appUid2,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 1:00
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 60 * NS_PER_SEC, appUid1,
- android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 1:10
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 100 * NS_PER_SEC,
- attributionUids2, attributionTags2,
- "wakelock1")); // 1:50
- events.push_back(CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 120 * NS_PER_SEC, appUid2,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 2:10
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 200 * NS_PER_SEC,
- attributionUids1, attributionTags1,
- "wakelock2")); // 3:30
-
- // Send log events to StatsLogProcessor.
- for (auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- // Check dump report.
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 320 * NS_PER_SEC,
- true /* include current partial bucket */, true, ADB_DUMP, FAST,
- &buffer);
- ASSERT_GT(buffer.size(), 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
- StatsLogReport::DurationMetricDataWrapper durationMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
- &durationMetrics);
- ASSERT_EQ(9, durationMetrics.data_size());
-
- DurationMetricData data = durationMetrics.data(0);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(1);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(240 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(2);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(3);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(140 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(4);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(5);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock1");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(6);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(15 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(7);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(180 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
- data = durationMetrics.data(8);
- ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
- "wakelock2");
- ASSERT_EQ(1, data.slice_by_state_size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
- EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
deleted file mode 100644
index 1be261297e0a..000000000000
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int64_t metricId = 123456;
-const int32_t ATOM_TAG = util::SUBSYSTEM_SLEEP_STATE;
-
-StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
- bool useCondition = true) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
- auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG);
- *config.add_atom_matcher() = atomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(metricId);
- gaugeMetric->set_what(atomMatcher.id());
- if (useCondition) {
- gaugeMetric->set_condition(screenIsOffPredicate.id());
- }
- gaugeMetric->set_sampling_type(sampling_type);
- gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
- *gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(ATOM_TAG, {1 /* subsystem name */});
- gaugeMetric->set_bucket(FIVE_MINUTES);
- gaugeMetric->set_max_pull_delay_sec(INT_MAX);
- config.set_hash_strings_in_metric_report(false);
-
- return config;
-}
-
-} // namespaces
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-
- auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
-
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- processor->informPullAlarmFired(nextPullTimeNs + 3);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(nextPullTimeNs + 2);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 2);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(6, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(3).atom_size());
- ASSERT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, data.bucket_info(3).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(4).atom_size());
- ASSERT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(4).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(5).atom_size());
- ASSERT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, data.bucket_info(5).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
- auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 3,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 10,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(2, data.bucket_info(2).atom_size());
- ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, data.bucket_info(2).elapsed_timestamp_nanos(1));
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
- EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- // Pulling alarm arrives one bucket size late.
- processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 11,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives more than one bucket size late.
- processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
- data.bucket_info(1).elapsed_timestamp_nanos(0));
- EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, data.bucket_info(2).elapsed_timestamp_nanos(0));
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
-
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = batterySaverStartMatcher;
- const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
- auto metric_activation = config.add_metric_activation();
- metric_activation->set_metric_id(metricId);
- metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto event_activation = metric_activation->add_event_activation();
- event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
- event_activation->set_ttl_seconds(ttlNs / 1000000000);
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- // Event should not be kept.
- processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // Activate the metric. A pull occurs upon activation.
- const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
- auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
- processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // This event should be kept. 2 total.
- processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
- // This event should be kept. 3 total.
- processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
-
- // Create random event to deactivate metric.
- auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
- processor->OnLogEvent(deactivationEvent.get());
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // Event should not be kept. 3 total.
- processor->informPullAlarmFired(nextPullTimeNs + 3);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 2);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 0);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- ASSERT_EQ(1, bucketInfo.atom_size());
- ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
- EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-
- bucketInfo = data.bucket_info(1);
- ASSERT_EQ(1, bucketInfo.atom_size());
- ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-
- bucketInfo = data.bucket_info(2);
- ASSERT_EQ(1, bucketInfo.atom_size());
- ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
- EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
- bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
- bucketInfo.end_bucket_elapsed_nanos());
- EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
- auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
-
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- ATOM_TAG);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()->second->
- mAllMetricProducers[0]->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the gauge metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& nextPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(nextPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-
- processor->informPullAlarmFired(nextPullTimeNs + 4);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
- nextPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(
- reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
- ASSERT_GT((int)gaugeMetrics.data_size(), 0);
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 4, data.bucket_info(2).elapsed_timestamp_nanos(0));
- ASSERT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
- EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
deleted file mode 100644
index a40a9484a841..000000000000
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sampling_type) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto atomMatcher = CreateSimpleAtomMatcher("", util::APP_START_OCCURRED);
- *config.add_atom_matcher() = atomMatcher;
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(123456);
- gaugeMetric->set_what(atomMatcher.id());
- gaugeMetric->set_condition(isInBackgroundPredicate.id());
- gaugeMetric->mutable_gauge_fields_filter()->set_include_all(false);
- gaugeMetric->set_sampling_type(sampling_type);
- auto fieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
- fieldMatcher->set_field(util::APP_START_OCCURRED);
- fieldMatcher->add_child()->set_field(3); // type (enum)
- fieldMatcher->add_child()->set_field(4); // activity_name(str)
- fieldMatcher->add_child()->set_field(7); // activity_start_msec(int64)
- *gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::APP_START_OCCURRED, {1 /* uid field */ });
- gaugeMetric->set_bucket(FIVE_MINUTES);
-
- auto links = gaugeMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::APP_START_OCCURRED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- auto dimensionCondition = links->mutable_fields_in_condition();
- dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- dimensionCondition->add_child()->set_field(1); // uid field.
- return config;
-}
-
-std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
- uint64_t timestampNs, const int uid, const string& pkg_name,
- AppStartOccurred::TransitionType type, const string& activity_name,
- const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, pkg_name.c_str());
- AStatsEvent_writeInt32(statsEvent, type);
- AStatsEvent_writeString(statsEvent, activity_name.c_str());
- AStatsEvent_writeString(statsEvent, calling_pkg_name.c_str());
- AStatsEvent_writeInt32(statsEvent, is_instant_app);
- AStatsEvent_writeInt32(statsEvent, activity_start_msec);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-} // namespace
-
-TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
- for (const auto& sampling_type :
- {GaugeMetric::FIRST_N_SAMPLES, GaugeMetric::RANDOM_ONE_SAMPLE}) {
- auto config = CreateStatsdConfigForPushedEvent(sampling_type);
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor =
- CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- int appUid1 = 123;
- int appUid2 = 456;
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid1));
- events.push_back(
- CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid1));
- events.push_back(
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid1));
- events.push_back(
- CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100, appUid1));
-
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 10, appUid1, "app1", AppStartOccurred::WARM, "activity_name1",
- "calling_pkg_name1", true /*is_instant_app*/, 101 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 20, appUid1, "app1", AppStartOccurred::HOT, "activity_name2",
- "calling_pkg_name2", true /*is_instant_app*/, 102 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 30, appUid1, "app1", AppStartOccurred::COLD, "activity_name3",
- "calling_pkg_name3", true /*is_instant_app*/, 103 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + bucketSizeNs + 30, appUid1, "app1", AppStartOccurred::WARM,
- "activity_name4", "calling_pkg_name4", true /*is_instant_app*/,
- 104 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 2 * bucketSizeNs, appUid1, "app1", AppStartOccurred::COLD,
- "activity_name5", "calling_pkg_name5", true /*is_instant_app*/,
- 105 /*activity_start_msec*/));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid1, "app1", AppStartOccurred::HOT,
- "activity_name6", "calling_pkg_name6", false /*is_instant_app*/,
- 106 /*activity_start_msec*/));
-
- events.push_back(
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 10, appUid2));
- events.push_back(CreateAppStartOccurredEvent(
- bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid2, "app2", AppStartOccurred::COLD,
- "activity_name7", "calling_pkg_name7", true /*is_instant_app*/,
- 201 /*activity_start_msec*/));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(),
- &gaugeMetrics);
- ASSERT_EQ(2, gaugeMetrics.data_size());
-
- auto data = gaugeMetrics.data(0);
- EXPECT_EQ(util::APP_START_OCCURRED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(appUid1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(3, data.bucket_info_size());
- if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
- ASSERT_EQ(2, data.bucket_info(0).atom_size());
- ASSERT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
- ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::HOT,
- data.bucket_info(0).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name2",
- data.bucket_info(0).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(102L,
- data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
- EXPECT_EQ(AppStartOccurred::COLD,
- data.bucket_info(0).atom(1).app_start_occurred().type());
- EXPECT_EQ("activity_name3",
- data.bucket_info(0).atom(1).app_start_occurred().activity_name());
- EXPECT_EQ(103L,
- data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::WARM,
- data.bucket_info(1).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name4",
- data.bucket_info(1).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(104L,
- data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(2, data.bucket_info(2).atom_size());
- ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::COLD,
- data.bucket_info(2).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name5",
- data.bucket_info(2).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(105L,
- data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
- EXPECT_EQ(AppStartOccurred::HOT,
- data.bucket_info(2).atom(1).app_start_occurred().type());
- EXPECT_EQ("activity_name6",
- data.bucket_info(2).atom(1).app_start_occurred().activity_name());
- EXPECT_EQ(106L,
- data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
- } else {
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::HOT,
- data.bucket_info(0).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name2",
- data.bucket_info(0).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(102L,
- data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(1, data.bucket_info(1).atom_size());
- ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::WARM,
- data.bucket_info(1).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name4",
- data.bucket_info(1).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(104L,
- data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
-
- ASSERT_EQ(1, data.bucket_info(2).atom_size());
- ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::COLD,
- data.bucket_info(2).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name5",
- data.bucket_info(2).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(105L,
- data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
- }
-
- data = gaugeMetrics.data(1);
-
- EXPECT_EQ(data.dimensions_in_what().field(), util::APP_START_OCCURRED);
- ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(appUid2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- ASSERT_EQ(1, data.bucket_info(0).atom_size());
- ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
- data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(AppStartOccurred::COLD, data.bucket_info(0).atom(0).app_start_occurred().type());
- EXPECT_EQ("activity_name7",
- data.bucket_info(0).atom(0).app_start_occurred().activity_name());
- EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
- }
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
deleted file mode 100644
index e320419a9d44..000000000000
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithOneDeactivation() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithTwoDeactivations() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
- auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
- brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher2;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithSameDeactivations() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithTwoMetricsTwoDeactivations() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
- auto crashMatcher = CreateProcessCrashAtomMatcher();
- auto foregroundMatcher = CreateMoveToForegroundAtomMatcher();
- auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
- auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
- auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
- brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
-
- *config.add_atom_matcher() = saverModeMatcher;
- *config.add_atom_matcher() = crashMatcher;
- *config.add_atom_matcher() = screenOnMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher;
- *config.add_atom_matcher() = brightnessChangedMatcher2;
- *config.add_atom_matcher() = foregroundMatcher;
-
- int64_t metricId = 123456;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(metricId);
- countMetric->set_what(crashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- int64_t metricId2 = 234567;
- countMetric = config.add_count_metric();
- countMetric->set_id(metricId2);
- countMetric->set_what(foregroundMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- countMetric->mutable_dimensions_in_what()->set_field(
- util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- countMetric->mutable_dimensions_in_what()->add_child()->set_field(1); // uid field
-
- auto metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId);
- auto event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- auto event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
- metric_activation1 = config.add_metric_activation();
- metric_activation1->set_metric_id(metricId2);
- event_activation1 = metric_activation1->add_event_activation();
- event_activation1->set_atom_matcher_id(saverModeMatcher.id());
- event_activation1->set_ttl_seconds(60 * 6); // 6 minutes
- event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
- event_activation2 = metric_activation1->add_event_activation();
- event_activation2->set_atom_matcher_id(screenOnMatcher.id());
- event_activation2->set_ttl_seconds(60 * 2); // 2 minutes
- event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
- return config;
-}
-
-} // namespace
-
-TEST(MetricActivationE2eTest, TestCountMetric) {
- auto config = CreateStatsdConfig();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(4, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation) {
- auto config = CreateStatsdConfigWithOneDeactivation();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 1u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // 5th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
- // Cancel battery saver mode activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // Screen-on activation expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 5);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- // Cancel battery saver mode activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 6);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations) {
- auto config = CreateStatsdConfigWithTwoDeactivations();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 2u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // 5th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // Screen-on activation expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 5);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 6);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation) {
- auto config = CreateStatsdConfigWithSameDeactivations();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 1u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 2u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[3][1], eventActivationMap[2]);
- EXPECT_EQ(broadcastCount, 0);
-
- std::unique_ptr<LogEvent> event;
-
- // Event that should be ignored.
- event = CreateAppCrashEvent(bucketStartTimeNs + 1, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 1);
-
- // Activate metric via screen on for 2 minutes.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 10, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
-
- // 1st processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Enable battery saver mode activation for 5 minutes.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 1);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 + 10);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
-
- // 2nd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 40, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 + 40);
-
- // Cancel battery saver mode and screen on activation.
- int64_t firstDeactivation = bucketStartTimeNs + NS_PER_SEC * 61;
- event = CreateScreenBrightnessChangedEvent(firstDeactivation, 64);
- processor.OnLogEvent(event.get(), firstDeactivation);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
- // Should be ignored
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 61 + 80, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 61 + 80);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80);
-
- // Cancel battery saver mode activation.
- int64_t secondDeactivation = bucketStartTimeNs + NS_PER_SEC * 60 * 13;
- event = CreateScreenBrightnessChangedEvent(secondDeactivation, 140);
- processor.OnLogEvent(event.get(), secondDeactivation);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
- // Should be ignored.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(3, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(555, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(secondDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations) {
- auto config = CreateStatsdConfigWithTwoMetricsTwoDeactivations();
-
- int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- vector<int64_t> activeConfigsBroadcast;
-
- long timeBase1 = 1;
- int broadcastCount = 0;
- StatsLogProcessor processor(
- m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
- [](const ConfigKey& key) { return true; },
- [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
- const vector<int64_t>& activeConfigs) {
- broadcastCount++;
- EXPECT_EQ(broadcastUid, uid);
- activeConfigsBroadcast.clear();
- activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
- activeConfigs.end());
- return true;
- });
-
- processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
- ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 2);
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- auto& eventActivationMap = metricProducer->mEventActivationMap;
- auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
- sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
- auto& eventActivationMap2 = metricProducer2->mEventActivationMap;
- auto& eventDeactivationMap2 = metricProducer2->mEventDeactivationMap;
-
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_FALSE(metricProducer2->mIsActive);
- // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
- // triggered by screen on event (tracker index 2).
- ASSERT_EQ(eventActivationMap.size(), 2u);
- EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
- EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap.size(), 2u);
- EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
- EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
- ASSERT_EQ(eventActivationMap2.size(), 2u);
- EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
- EXPECT_TRUE(eventActivationMap2.find(2) != eventActivationMap2.end());
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, 0);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- ASSERT_EQ(eventDeactivationMap2.size(), 2u);
- EXPECT_TRUE(eventDeactivationMap2.find(3) != eventDeactivationMap2.end());
- EXPECT_TRUE(eventDeactivationMap2.find(4) != eventDeactivationMap2.end());
- ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
- ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- std::unique_ptr<LogEvent> event;
-
- event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + 5, 1111);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(broadcastCount, 0);
-
- // Activated by battery save mode.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 1);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // First processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + 15, 2222);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
- // Activated by screen on event.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // 2nd processed event.
- // The activation by screen_on event expires, but the one by battery save mode is still active.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 3333);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
- // No new broadcast since the config should still be active.
- EXPECT_EQ(broadcastCount, 1);
-
- // 3rd processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 4444);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
- // All activations expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 5555);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
- EXPECT_FALSE(metricsManager->isActive());
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 2);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // Re-activate metric via screen on.
- event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
- android::view::DISPLAY_STATE_ON);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // 4th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 6666);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 3);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // 5th processed event.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 7777);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
- EXPECT_FALSE(metricsManager->isActive());
- // New broadcast since the config is no longer active.
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // Screen-on activation expired.
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 8888);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 4);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
- event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 9999);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
- // Re-enable battery saver mode activation.
- event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_TRUE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 5);
- ASSERT_EQ(activeConfigsBroadcast.size(), 1);
- EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
- EXPECT_TRUE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_TRUE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- // Cancel battery saver mode and screen on activation.
- event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
- processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
- EXPECT_FALSE(metricsManager->isActive());
- EXPECT_EQ(broadcastCount, 6);
- ASSERT_EQ(activeConfigsBroadcast.size(), 0);
- EXPECT_FALSE(metricProducer->mIsActive);
- EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
- EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
- EXPECT_FALSE(metricProducer2->mIsActive);
- EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
- EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
- EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
- EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
- EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
- EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
- EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(2, reports.reports(0).metrics_size());
-
- StatsLogReport::CountMetricDataWrapper countMetrics;
-
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- auto data = countMetrics.data(0);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- countMetrics.clear_data();
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(1).count_metrics(), &countMetrics);
- ASSERT_EQ(5, countMetrics.data_size());
-
- data = countMetrics.data(0);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(2222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(1);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(3333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(2);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(4444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- // Partial bucket as metric is deactivated.
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(3);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(6666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-
- data = countMetrics.data(4);
- EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* uid field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_EQ(7777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(1, data.bucket_info(0).count());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
- data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
deleted file mode 100644
index 5e77ee0f0b0a..000000000000
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
- *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
- *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
- *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
- auto isSyncingPredicate = CreateIsSyncingPredicate();
- auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
- *syncDimension = CreateAttributionUidDimensions(
- util::SYNC_STATE_CHANGED, {Position::FIRST});
- syncDimension->add_child()->set_field(2 /* name field*/);
-
- auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
- *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
- CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
-
- *config.add_predicate() = screenIsOffPredicate;
- *config.add_predicate() = isSyncingPredicate;
- *config.add_predicate() = isInBackgroundPredicate;
-
- auto combinationPredicate = config.add_predicate();
- combinationPredicate->set_id(StringToId("combinationPredicate"));
- combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
- addPredicateToPredicateCombination(isInBackgroundPredicate, combinationPredicate);
-
- auto countMetric = config.add_count_metric();
- countMetric->set_id(StringToId("AppCrashes"));
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_condition(combinationPredicate->id());
- // The metric is dimensioning by uid only.
- *countMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1});
- countMetric->set_bucket(FIVE_MINUTES);
-
- // Links between crash atom and condition of app is in syncing.
- auto links = countMetric->add_links();
- links->set_condition(isSyncingPredicate.id());
- auto dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
- util::SYNC_STATE_CHANGED, {Position::FIRST});
-
- // Links between crash atom and condition of app is in background.
- links = countMetric->add_links();
- links->set_condition(isInBackgroundPredicate.id());
- dimensionWhat = links->mutable_fields_in_what();
- dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- dimensionWhat->add_child()->set_field(1); // uid field.
- auto dimensionCondition = links->mutable_fields_in_condition();
- dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- dimensionCondition->add_child()->set_field(1); // uid field.
- return config;
-}
-} // namespace
-
-// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
-// we should use the real API which will clear the data after dump data is called.
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
- auto config = CreateStatsdConfig();
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- int appUid = 123;
- auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
- auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
- auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
-
- auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
- auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
- auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
-
- auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
- auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
-
- auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
- auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
-
- auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- std::vector<int> attributionUids = {appUid, appUid + 1};
- std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
-
- auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
- attributionUids, attributionTags, "ReadDoc");
-
- auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
- auto moveToForegroundEvent1 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
-
- auto moveToBackgroundEvent2 =
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
- auto moveToForegroundEvent2 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
-
- /*
- bucket #1 bucket #2
-
-
- | | | | | | | | | | (crashEvents)
- |-------------------------------------|-----------------------------------|---------
-
- | | (MoveToBkground)
-
- | | (MoveToForeground)
-
- | | (SyncIsOn)
- | (SyncIsOff)
- | | (ScreenIsOn)
- | (ScreenIsOff)
- */
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(std::move(crashEvent1));
- events.push_back(std::move(crashEvent2));
- events.push_back(std::move(crashEvent3));
- events.push_back(std::move(crashEvent4));
- events.push_back(std::move(crashEvent5));
- events.push_back(std::move(crashEvent6));
- events.push_back(std::move(crashEvent7));
- events.push_back(std::move(crashEvent8));
- events.push_back(std::move(crashEvent9));
- events.push_back(std::move(crashEvent10));
- events.push_back(std::move(screenTurnedOnEvent));
- events.push_back(std::move(screenTurnedOffEvent));
- events.push_back(std::move(screenTurnedOnEvent2));
- events.push_back(std::move(syncOnEvent1));
- events.push_back(std::move(syncOffEvent1));
- events.push_back(std::move(syncOnEvent2));
- events.push_back(std::move(moveToBackgroundEvent1));
- events.push_back(std::move(moveToForegroundEvent1));
- events.push_back(std::move(moveToBackgroundEvent2));
- events.push_back(std::move(moveToForegroundEvent2));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
- EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
- auto data = reports.reports(0).metrics(0).count_metrics().data(0);
- // Validate dimension value.
- EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- // Uid field.
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
-}
-
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
- auto config = CreateStatsdConfig();
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
- int appUid = 123;
- auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
- auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
- auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
-
- auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
- auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
- auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
-
- auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
- auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
-
- auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
- auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
-
- auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- std::vector<int> attributionUids = {appUid, appUid + 1};
- std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
-
- auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
- attributionTags, "ReadEmail");
- auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
- attributionUids, attributionTags, "ReadDoc");
-
- auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
- auto moveToForegroundEvent1 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
-
- auto moveToBackgroundEvent2 =
- CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
- auto moveToForegroundEvent2 =
- CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
-
- /*
- bucket #1 bucket #2
-
-
- | | | | | | | | | | (crashEvents)
- |-------------------------------------|-----------------------------------|---------
-
- | | (MoveToBkground)
-
- | | (MoveToForeground)
-
- | | (SyncIsOn)
- | (SyncIsOff)
- | | (ScreenIsOn)
- | (ScreenIsOff)
- */
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(std::move(crashEvent1));
- events.push_back(std::move(crashEvent2));
- events.push_back(std::move(crashEvent3));
- events.push_back(std::move(crashEvent4));
- events.push_back(std::move(crashEvent5));
- events.push_back(std::move(crashEvent6));
- events.push_back(std::move(crashEvent7));
- events.push_back(std::move(crashEvent8));
- events.push_back(std::move(crashEvent9));
- events.push_back(std::move(crashEvent10));
- events.push_back(std::move(screenTurnedOnEvent));
- events.push_back(std::move(screenTurnedOffEvent));
- events.push_back(std::move(screenTurnedOnEvent2));
- events.push_back(std::move(syncOnEvent1));
- events.push_back(std::move(syncOffEvent1));
- events.push_back(std::move(syncOnEvent2));
- events.push_back(std::move(moveToBackgroundEvent1));
- events.push_back(std::move(moveToForegroundEvent1));
- events.push_back(std::move(moveToBackgroundEvent2));
- events.push_back(std::move(moveToForegroundEvent2));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
-
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
- EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
- EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
- auto data = reports.reports(0).metrics(0).count_metrics().data(0);
- // Validate dimension value.
- EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
- // Uid field.
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
deleted file mode 100644
index 783f31c7bde8..000000000000
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_ibinder.h>
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/StatsService.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using::ndk::SharedRefBase;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-namespace {
-const string kApp1 = "app1.sharing.1";
-const int kConfigKey = 789130123; // Randomly chosen to avoid collisions with existing configs.
-const int kCallingUid = 0; // Randomly chosen
-
-void SendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
- string str;
- config.SerializeToString(&str);
- std::vector<int8_t> configAsVec(str.begin(), str.end());
- service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
-}
-
-ConfigMetricsReport GetReports(sp<StatsLogProcessor> processor, int64_t timestamp,
- bool include_current = false) {
- vector<uint8_t> output;
- ConfigKey configKey(AIBinder_getCallingUid(), kConfigKey);
- processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
- true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &output);
- ConfigMetricsReportList reports;
- reports.ParseFromArray(output.data(), output.size());
- EXPECT_EQ(1, reports.reports_size());
- return reports.reports(kCallingUid);
-}
-
-StatsdConfig MakeConfig() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto appCrashMatcher = CreateProcessCrashAtomMatcher();
- *config.add_atom_matcher() = appCrashMatcher;
- auto countMetric = config.add_count_metric();
- countMetric->set_id(StringToId("AppCrashes"));
- countMetric->set_what(appCrashMatcher.id());
- countMetric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-StatsdConfig MakeValueMetricConfig(int64_t minTime) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(123456);
- valueMetric->set_what(pulledAtomMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- *valueMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
- valueMetric->set_bucket(FIVE_MINUTES);
- valueMetric->set_min_bucket_size_nanos(minTime);
- valueMetric->set_use_absolute_value_on_reset(true);
- valueMetric->set_skip_zero_diff_output(false);
- return config;
-}
-
-StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(123456);
- gaugeMetric->set_what(pulledAtomMatcher.id());
- gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
- *gaugeMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
- gaugeMetric->set_bucket(FIVE_MINUTES);
- gaugeMetric->set_min_bucket_size_nanos(minTime);
- return config;
-}
-} // anonymous namespace
-
-TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 2, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
- // Expect no metrics since the bucket has not finished yet.
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- // Force the uidmap to update at timestamp 2.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- // This is a new installation, so there shouldn't be a split (should be same as the without
- // split case).
- service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
- service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
- {String16("")});
-
- // Force the uidmap to update at timestamp 2.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_start_bucket_elapsed_nanos());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_end_bucket_elapsed_nanos());
- EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
- service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
- {String16("")});
-
- // Force the uidmap to update at timestamp 2.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
- service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_start_bucket_elapsed_nanos());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_end_bucket_elapsed_nanos());
- EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- SendConfig(service, MakeConfig());
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- // Goes into the first bucket
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + NS_PER_SEC, 100).get());
- int64_t bootCompleteTimeNs = start + 2 * NS_PER_SEC;
- service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
- // Goes into the second bucket.
- service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3 * NS_PER_SEC, 100).get());
-
- ConfigMetricsReport report = GetReports(service->mProcessor, start + 4 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
- EXPECT_TRUE(report.metrics(0)
- .count_metrics()
- .data(0)
- .bucket_info(0)
- .has_start_bucket_elapsed_nanos());
- EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).count_metrics().data(0).bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- SendConfig(service, MakeValueMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- int64_t appUpgradeTimeNs = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
- service->mUidMap->updateApp(appUpgradeTimeNs, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
-
- ConfigMetricsReport report =
- GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).value_metrics().skipped_size());
-
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
- ASSERT_EQ(2, report.metrics(0).value_metrics().data(0).bucket_info_size());
- EXPECT_EQ(MillisToNano(NanoToMillis(appUpgradeTimeNs)),
- report.metrics(0).value_metrics().data(0).bucket_info(1).end_bucket_elapsed_nanos());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
-
- ConfigMetricsReport report =
- GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
- EXPECT_TRUE(report.metrics(0).value_metrics().skipped(0).has_start_bucket_elapsed_nanos());
- // Can't test the start time since it will be based on the actual time when the pulling occurs.
- EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
- report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
-
- ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- // Initial pull will fail since puller is not registered.
- SendConfig(service, MakeValueMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
-
- int64_t bootCompleteTimeNs = start + NS_PER_SEC;
- service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-
- ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
- backfillStartEndTimestamp(&report);
-
- // First bucket is dropped due to the initial pull failing
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
- EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
-
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
- EXPECT_EQ(
- MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).value_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- SendConfig(service, MakeGaugeMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
- String16("v2"), String16(""));
-
- ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
- backfillStartEndTimestamp(&report);
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- // Partial buckets don't occur when app is first installed.
- service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
- SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2;
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
- service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
- String16(""));
-
- ConfigMetricsReport report =
- GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
- backfillStartEndTimestamp(&report);
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(1, report.metrics(0).gauge_metrics().skipped_size());
- // Can't test the start time since it will be based on the actual time when the pulling occurs.
- EXPECT_TRUE(report.metrics(0).gauge_metrics().skipped(0).has_start_bucket_elapsed_nanos());
- EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
- report.metrics(0).gauge_metrics().skipped(0).end_bucket_elapsed_nanos());
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
- ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) {
- shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
- // Initial pull will fail since puller hasn't been registered.
- SendConfig(service, MakeGaugeMetricConfig(0));
- int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are
- // initialized with.
-
- service->mPullerManager->RegisterPullAtomCallback(
- /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
- SharedRefBase::make<FakeSubsystemSleepCallback>());
-
- int64_t bootCompleteTimeNs = start + NS_PER_SEC;
- service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-
- service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-
- ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
- backfillStartEndTimestamp(&report);
-
- ASSERT_EQ(1, report.metrics_size());
- ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
- // The fake subsystem state sleep puller returns two atoms.
- ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
- // No data in the first bucket, so nothing is reported
- ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
- EXPECT_EQ(
- MillisToNano(NanoToMillis(bootCompleteTimeNs)),
- report.metrics(0).gauge_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
deleted file mode 100644
index 4d3928277527..000000000000
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ /dev/null
@@ -1,679 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int64_t metricId = 123456;
-
-StatsdConfig CreateStatsdConfig(bool useCondition = true) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_what(pulledAtomMatcher.id());
- if (useCondition) {
- valueMetric->set_condition(screenIsOffPredicate.id());
- }
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- *valueMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
- valueMetric->set_bucket(FIVE_MINUTES);
- valueMetric->set_use_absolute_value_on_reset(true);
- valueMetric->set_skip_zero_diff_output(false);
- valueMetric->set_max_pull_delay_sec(INT_MAX);
- return config;
-}
-
-StatsdConfig CreateStatsdConfigWithStates() {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
-
- auto pulledAtomMatcher = CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
- *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
- auto screenOnPredicate = CreateScreenIsOnPredicate();
- *config.add_predicate() = screenOnPredicate;
-
- auto screenOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenOffPredicate;
-
- auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
- *config.add_predicate() = deviceUnpluggedPredicate;
-
- auto screenOnOnBatteryPredicate = config.add_predicate();
- screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
- screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
- addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
-
- auto screenOffOnBatteryPredicate = config.add_predicate();
- screenOffOnBatteryPredicate->set_id(StringToId("ScreenOffOnBattery"));
- screenOffOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
- addPredicateToPredicateCombination(screenOffPredicate, screenOffOnBatteryPredicate);
- addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOffOnBatteryPredicate);
-
- const State screenState =
- CreateScreenStateWithSimpleOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
- *config.add_state() = screenState;
-
- // ValueMetricSubsystemSleepWhileScreenOnOnBattery
- auto valueMetric1 = config.add_value_metric();
- valueMetric1->set_id(metricId);
- valueMetric1->set_what(pulledAtomMatcher.id());
- valueMetric1->set_condition(screenOnOnBatteryPredicate->id());
- *valueMetric1->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- valueMetric1->set_bucket(FIVE_MINUTES);
- valueMetric1->set_use_absolute_value_on_reset(true);
- valueMetric1->set_skip_zero_diff_output(false);
- valueMetric1->set_max_pull_delay_sec(INT_MAX);
-
- // ValueMetricSubsystemSleepWhileScreenOffOnBattery
- ValueMetric* valueMetric2 = config.add_value_metric();
- valueMetric2->set_id(StringToId("ValueMetricSubsystemSleepWhileScreenOffOnBattery"));
- valueMetric2->set_what(pulledAtomMatcher.id());
- valueMetric2->set_condition(screenOffOnBatteryPredicate->id());
- *valueMetric2->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- valueMetric2->set_bucket(FIVE_MINUTES);
- valueMetric2->set_use_absolute_value_on_reset(true);
- valueMetric2->set_skip_zero_diff_output(false);
- valueMetric2->set_max_pull_delay_sec(INT_MAX);
-
- // ValueMetricSubsystemSleepWhileOnBatterySliceScreen
- ValueMetric* valueMetric3 = config.add_value_metric();
- valueMetric3->set_id(StringToId("ValueMetricSubsystemSleepWhileOnBatterySliceScreen"));
- valueMetric3->set_what(pulledAtomMatcher.id());
- valueMetric3->set_condition(deviceUnpluggedPredicate.id());
- *valueMetric3->mutable_value_field() =
- CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
- valueMetric3->add_slice_by_state(screenState.id());
- valueMetric3->set_bucket(FIVE_MINUTES);
- valueMetric3->set_use_absolute_value_on_reset(true);
- valueMetric3->set_skip_zero_diff_output(false);
- valueMetric3->set_max_pull_delay_sec(INT_MAX);
- return config;
-}
-
-} // namespace
-
-/**
- * Tests the initial condition and condition after the first log events for
- * value metrics with either a combination condition or simple condition.
- *
- * Metrics should be initialized with condition kUnknown (given that the
- * predicate is using the default InitialValue of UNKNOWN). The condition should
- * be updated to either kFalse or kTrue if a condition event is logged for all
- * children conditions.
- */
-TEST(ValueMetricE2eTest, TestInitialConditionChanges) {
- StatsdConfig config = CreateStatsdConfigWithStates();
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- int32_t tagId = util::SUBSYSTEM_SLEEP_STATE;
- auto processor =
- CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(), tagId);
-
- EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- EXPECT_EQ(3, metricsManager->mAllMetricProducers.size());
-
- // Combination condition metric - screen on and device unplugged
- sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
- // Simple condition metric - device unplugged
- sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[2];
-
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 30, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 40, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
- EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
- auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
- configAddedTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
- processor->OnLogEvent(pluggedUsbEvent.get());
- EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
-
- auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
- configAddedTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
- processor->OnLogEvent(pluggedNoneEvent.get());
- EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
- EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents) {
- auto config = CreateStatsdConfig();
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- util::SUBSYSTEM_SLEEP_STATE);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the value metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& expectedPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 2 * bucketSizeNs + 15,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 11,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::ValueMetricDataWrapper valueMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
- ASSERT_GT((int)valueMetrics.data_size(), 1);
-
- auto data = valueMetrics.data(0);
- EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- // We have 4 buckets, the first one was incomplete since the condition was unknown.
- ASSERT_EQ(4, data.bucket_info_size());
-
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(0).values_size());
-
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(1).values_size());
-
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(2).values_size());
-
- EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(3).values_size());
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
- auto config = CreateStatsdConfig();
- int64_t baseTimeNs = getElapsedRealtimeNs();
- // 10 mins == 2 bucket durations.
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- util::SUBSYSTEM_SLEEP_STATE);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
-
- // When creating the config, the value metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& expectedPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
- // Screen off/on/off events.
- auto screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- auto screenOnEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- screenOffEvent =
- CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- // Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
- // future, data will be skipped.
- processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
-
- // This screen state change will start a new bucket.
- screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 65,
- android::view::DISPLAY_STATE_ON);
- processor->OnLogEvent(screenOnEvent.get());
-
- // The alarm is delayed but we already created a bucket thanks to the screen state condition.
- // This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
- processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
-
- screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 6 * bucketSizeNs + 31,
- android::view::DISPLAY_STATE_OFF);
- processor->OnLogEvent(screenOffEvent.get());
-
- processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 8 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 9 * bucketSizeNs, expectedPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::ValueMetricDataWrapper valueMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
- ASSERT_GT((int)valueMetrics.data_size(), 1);
-
- auto data = valueMetrics.data(0);
- EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- ASSERT_EQ(3, data.bucket_info_size());
-
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(0).values_size());
-
- EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(1).values_size());
-
- EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- ASSERT_EQ(1, data.bucket_info(2).values_size());
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
- auto config = CreateStatsdConfig(false);
- int64_t baseTimeNs = getElapsedRealtimeNs();
- int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
- auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
- *config.add_atom_matcher() = batterySaverStartMatcher;
- const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
- auto metric_activation = config.add_metric_activation();
- metric_activation->set_metric_id(metricId);
- metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
- auto event_activation = metric_activation->add_event_activation();
- event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
- event_activation->set_ttl_seconds(ttlNs / 1000000000);
-
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
- SharedRefBase::make<FakeSubsystemSleepCallback>(),
- util::SUBSYSTEM_SLEEP_STATE);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- processor->mPullerManager->ForceClearPullerCache();
-
- int startBucketNum = processor->mMetricsManagers.begin()
- ->second->mAllMetricProducers[0]
- ->getCurrentBucketNum();
- EXPECT_GT(startBucketNum, (int64_t)0);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // When creating the config, the value metric producer should register the alarm at the
- // end of the current bucket.
- ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
- EXPECT_EQ(bucketSizeNs,
- processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
- int64_t& expectedPullTimeNs =
- processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
- // Pulling alarm arrives on time and reset the sequential pulling alarm.
- processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- // Activate the metric. A pull occurs here
- const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
- auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
- processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
-
- // Create random event to deactivate metric.
- auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
- processor->OnLogEvent(deactivationEvent.get());
- EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
- processor->informPullAlarmFired(expectedPullTimeNs + 3);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
-
- processor->informPullAlarmFired(expectedPullTimeNs + 4);
- EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
-
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
- ADB_DUMP, FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(1, reports.reports_size());
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- StatsLogReport::ValueMetricDataWrapper valueMetrics;
- sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
- ASSERT_GT((int)valueMetrics.data_size(), 0);
-
- auto data = valueMetrics.data(0);
- EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
- ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
- EXPECT_EQ(1 /* subsystem name field */,
- data.dimensions_in_what().value_tuple().dimensions_value(0).field());
- EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
- // We have 2 full buckets, the two surrounding the activation are dropped.
- ASSERT_EQ(2, data.bucket_info_size());
-
- auto bucketInfo = data.bucket_info(0);
- EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- ASSERT_EQ(1, bucketInfo.values_size());
-
- bucketInfo = data.bucket_info(1);
- EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
- EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
- ASSERT_EQ(1, bucketInfo.values_size());
-}
-
-/**
- * Test initialization of a simple value metric that is sliced by a state.
- *
- * ValueCpuUserTimePerScreenState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState) {
- // Create config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto pulledAtomMatcher =
- CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
- *config.add_atom_matcher() = pulledAtomMatcher;
-
- auto screenState = CreateScreenState();
- *config.add_state() = screenState;
-
- // Create value metric that slices by screen state without a map.
- int64_t metricId = 123456;
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- valueMetric->set_what(pulledAtomMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
- valueMetric->add_slice_by_state(screenState.id());
- valueMetric->set_max_pull_delay_sec(INT_MAX);
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- const uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000LL;
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Check that ValueMetricProducer was initialized correctly.
- ASSERT_EQ(1U, processor->mMetricsManagers.size());
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
- ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
-}
-
-/**
- * Test initialization of a value metric that is sliced by state and has
- * dimensions_in_what.
- *
- * ValueCpuUserTimePerUidPerUidProcessState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions) {
- // Create config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto cpuTimePerUidMatcher =
- CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
- *config.add_atom_matcher() = cpuTimePerUidMatcher;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create value metric that slices by screen state with a complete map.
- int64_t metricId = 123456;
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- valueMetric->set_what(cpuTimePerUidMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
- *valueMetric->mutable_dimensions_in_what() =
- CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
- valueMetric->add_slice_by_state(uidProcessState.id());
- MetricStateLink* stateLink = valueMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
- valueMetric->set_max_pull_delay_sec(INT_MAX);
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
-
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // Check that StateTrackers were initialized correctly.
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Check that ValueMetricProducer was initialized correctly.
- ASSERT_EQ(1U, processor->mMetricsManagers.size());
- sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
- EXPECT_TRUE(metricsManager->isConfigValid());
- ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
- sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
- ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
- ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
-}
-
-/**
- * Test initialization of a value metric that is sliced by state and has
- * dimensions_in_what.
- *
- * ValueCpuUserTimePerUidPerUidProcessState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions) {
- // Create config.
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
- auto cpuTimePerUidMatcher =
- CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
- *config.add_atom_matcher() = cpuTimePerUidMatcher;
-
- auto uidProcessState = CreateUidProcessState();
- *config.add_state() = uidProcessState;
-
- // Create value metric that slices by screen state with a complete map.
- int64_t metricId = 123456;
- auto valueMetric = config.add_value_metric();
- valueMetric->set_id(metricId);
- valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
- valueMetric->set_what(cpuTimePerUidMatcher.id());
- *valueMetric->mutable_value_field() =
- CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
- valueMetric->add_slice_by_state(uidProcessState.id());
- MetricStateLink* stateLink = valueMetric->add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
- valueMetric->set_max_pull_delay_sec(INT_MAX);
-
- // Initialize StatsLogProcessor.
- const uint64_t bucketStartTimeNs = 10000000000; // 0:10
- int uid = 12345;
- int64_t cfgId = 98765;
- ConfigKey cfgKey(uid, cfgId);
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
- // No StateTrackers are initialized.
- EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
-
- // Config initialization fails.
- ASSERT_EQ(0, processor->mMetricsManagers.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
deleted file mode 100644
index 52bc222e5fe2..000000000000
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType) {
- StatsdConfig config;
- config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
- *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
- *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
- *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
- *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
- auto screenIsOffPredicate = CreateScreenIsOffPredicate();
- *config.add_predicate() = screenIsOffPredicate;
-
- auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
- // The predicate is dimensioning by any attribution node and both by uid and tag.
- FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
- // Also slice by the wakelock tag
- dimensions.add_child()->set_field(3); // The wakelock tag is set in field 3 of the wakelock.
- *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
- *config.add_predicate() = holdingWakelockPredicate;
-
- auto durationMetric = config.add_duration_metric();
- durationMetric->set_id(StringToId("WakelockDuration"));
- durationMetric->set_what(holdingWakelockPredicate.id());
- durationMetric->set_condition(screenIsOffPredicate.id());
- durationMetric->set_aggregation_type(aggregationType);
- // The metric is dimensioning by first attribution node and only by uid.
- *durationMetric->mutable_dimensions_in_what() =
- CreateAttributionUidDimensions(
- util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
- durationMetric->set_bucket(FIVE_MINUTES);
- return config;
-}
-
-std::vector<int> attributionUids1 = {111, 222, 222};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
-
-std::vector<int> attributionUids2 = {111, 222, 222};
-std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
-
-/*
-Events:
-Screen off is met from (200ns,1 min+500ns].
-Acquire event for wl1 from 2ns to 1min+2ns
-Acquire event for wl2 from 1min-10ns to 2min-15ns
-*/
-void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
- auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 500,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- auto acquireEvent1 = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
- attributionTags1, "wl1");
- auto releaseEvent1 = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2,
- attributionUids1, attributionTags1, "wl1");
- auto acquireEvent2 = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 10,
- attributionUids2, attributionTags2, "wl2");
- auto releaseEvent2 = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 15,
- attributionUids2, attributionTags2, "wl2");
-
- std::vector<std::unique_ptr<LogEvent>> events;
-
- events.push_back(std::move(screenTurnedOnEvent));
- events.push_back(std::move(screenTurnedOffEvent));
- events.push_back(std::move(screenTurnedOnEvent2));
- events.push_back(std::move(acquireEvent1));
- events.push_back(std::move(acquireEvent2));
- events.push_back(std::move(releaseEvent1));
- events.push_back(std::move(releaseEvent2));
-
- sortLogEventsByTimestamp(&events);
-
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-}
-
-} // namespace
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::SUM);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // Validate bucket info.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
- data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // The wakelock holding interval starts from the screen off event and to the end of the 1st
- // bucket.
- EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::SUM);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- // Dump the report after the end of 2nd bucket.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // Two output buckets.
- // The wakelock holding interval in the 1st bucket starts from the screen off event and to
- // the end of the 1st bucket.
- EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
- bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
- // The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
- // ends at the second screen on event.
- EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::SUM);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- vector<uint8_t> buffer;
- ConfigMetricsReportList reports;
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- sortLogEventsByTimestamp(&events);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // The last wakelock holding spans 4 buckets.
- EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
- EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
-
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
-
- ASSERT_EQ(reports.reports_size(), 1);
-
- // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
- // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
- // itself.
- ASSERT_EQ(1, reports.reports(0).metrics_size());
- ASSERT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- // Dump the report after the end of 2nd bucket. One dimension with one bucket.
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- // Validate dimension value.
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // The max is acquire event for wl1 to screen off start.
- EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
- ConfigKey cfgKey;
- auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
- uint64_t bucketStartTimeNs = 10000000000;
- uint64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
- ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
- EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
- FeedEvents(config, processor);
- ConfigMetricsReportList reports;
- vector<uint8_t> buffer;
-
- std::vector<std::unique_ptr<LogEvent>> events;
- events.push_back(
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
- events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
- attributionUids1, attributionTags1, "wl3"));
- sortLogEventsByTimestamp(&events);
- for (const auto& event : events) {
- processor->OnLogEvent(event.get());
- }
-
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
- FAST, &buffer);
- EXPECT_TRUE(buffer.size() > 0);
- EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
- backfillDimensionPath(&reports);
- backfillStringInReport(&reports);
- backfillStartEndTimestamp(&reports);
- ASSERT_EQ(reports.reports_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
- ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
- auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
- ValidateAttributionUidDimension(data.dimensions_in_what(),
- util::WAKELOCK_STATE_CHANGED, 111);
- // The last wakelock holding spans 4 buckets.
- EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
- bucketStartTimeNs + 5 * bucketSizeNs);
- EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
- bucketStartTimeNs + 6 * bucketSizeNs);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
deleted file mode 100644
index 85a60886349e..000000000000
--- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/external/StatsCallbackPuller.h"
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <android/binder_interface_utils.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <chrono>
-#include <thread>
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomCallback;
-using aidl::android::os::IPullAtomResultReceiver;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using std::this_thread::sleep_for;
-using testing::Contains;
-
-namespace {
-int pullTagId = -12;
-bool pullSuccess;
-vector<int64_t> values;
-int64_t pullDelayNs;
-int64_t pullTimeoutNs;
-int64_t pullCoolDownNs;
-std::thread pullThread;
-
-AStatsEvent* createSimpleEvent(int64_t value) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, pullTagId);
- AStatsEvent_writeInt64(event, value);
- AStatsEvent_build(event);
- return event;
-}
-
-void executePull(const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
- // Convert stats_events into StatsEventParcels.
- vector<StatsEventParcel> parcels;
- for (int i = 0; i < values.size(); i++) {
- AStatsEvent* event = createSimpleEvent(values[i]);
- size_t size;
- uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
- StatsEventParcel p;
- // vector.assign() creates a copy, but this is inevitable unless
- // stats_event.h/c uses a vector as opposed to a buffer.
- p.buffer.assign(buffer, buffer + size);
- parcels.push_back(std::move(p));
- AStatsEvent_release(event);
- }
-
- sleep_for(std::chrono::nanoseconds(pullDelayNs));
- resultReceiver->pullFinished(pullTagId, pullSuccess, parcels);
-}
-
-class FakePullAtomCallback : public BnPullAtomCallback {
-public:
- Status onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
- // Force pull to happen in separate thread to simulate binder.
- pullThread = std::thread(executePull, resultReceiver);
- return Status::ok();
- }
-};
-
-class StatsCallbackPullerTest : public ::testing::Test {
-public:
- StatsCallbackPullerTest() {
- }
-
- void SetUp() override {
- pullSuccess = false;
- pullDelayNs = 0;
- values.clear();
- pullTimeoutNs = 10000000000LL; // 10 seconds.
- pullCoolDownNs = 1000000000; // 1 second.
- }
-
- void TearDown() override {
- if (pullThread.joinable()) {
- pullThread.join();
- }
- values.clear();
- }
-};
-} // Anonymous namespace.
-
-TEST_F(StatsCallbackPullerTest, PullSuccess) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- int64_t value = 43;
- pullSuccess = true;
- values.push_back(value);
-
- StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- int64_t startTimeNs = getElapsedRealtimeNs();
- EXPECT_TRUE(puller.PullInternal(&dataHolder));
- int64_t endTimeNs = getElapsedRealtimeNs();
-
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_LT(startTimeNs, dataHolder[0]->GetElapsedTimestampNs());
- EXPECT_GT(endTimeNs, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(value, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsCallbackPullerTest, PullFail) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- pullSuccess = false;
- int64_t value = 1234;
- values.push_back(value);
-
- StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
- vector<shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.PullInternal(&dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsCallbackPullerTest, PullTimeout) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- pullSuccess = true;
- pullDelayNs = MillisToNano(5); // 5ms.
- pullTimeoutNs = 10000; // 10 microseconds.
- int64_t value = 4321;
- values.push_back(value);
-
- StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
- vector<shared_ptr<LogEvent>> dataHolder;
- int64_t startTimeNs = getElapsedRealtimeNs();
- // Returns true to let StatsPuller code evaluate the timeout.
- EXPECT_TRUE(puller.PullInternal(&dataHolder));
- int64_t endTimeNs = getElapsedRealtimeNs();
- int64_t actualPullDurationNs = endTimeNs - startTimeNs;
-
- // Pull should take at least the timeout amount of time, but should stop early because the delay
- // is bigger.
- EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
- EXPECT_GT(pullDelayNs, actualPullDurationNs);
- ASSERT_EQ(0, dataHolder.size());
-
- // Let the pull return and make sure that the dataHolder is not modified.
- pullThread.join();
- ASSERT_EQ(0, dataHolder.size());
-}
-
-// Register a puller and ensure that the timeout logic works.
-TEST_F(StatsCallbackPullerTest, RegisterAndTimeout) {
- shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
- pullSuccess = true;
- pullDelayNs = MillisToNano(5); // 5 ms.
- pullTimeoutNs = 10000; // 10 microsseconds.
- int64_t value = 4321;
- int32_t uid = 123;
- values.push_back(value);
-
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- pullerManager->RegisterPullAtomCallback(uid, pullTagId, pullCoolDownNs, pullTimeoutNs,
- vector<int32_t>(), cb);
- vector<shared_ptr<LogEvent>> dataHolder;
- int64_t startTimeNs = getElapsedRealtimeNs();
- // Returns false, since StatsPuller code will evaluate the timeout.
- EXPECT_FALSE(pullerManager->Pull(pullTagId, {uid}, startTimeNs, &dataHolder));
- int64_t endTimeNs = getElapsedRealtimeNs();
- int64_t actualPullDurationNs = endTimeNs - startTimeNs;
-
- // Pull should take at least the timeout amount of time, but should stop early because the delay
- // is bigger. Make sure that the time is closer to the timeout, than to the intended delay.
- EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
- EXPECT_GT(pullDelayNs / 5, actualPullDurationNs);
- ASSERT_EQ(0, dataHolder.size());
-
- // Let the pull return and make sure that the dataHolder is not modified.
- pullThread.join();
- ASSERT_EQ(0, dataHolder.size());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/external/StatsPullerManager_test.cpp b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
deleted file mode 100644
index 0d539f477016..000000000000
--- a/cmds/statsd/tests/external/StatsPullerManager_test.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/external/StatsPullerManager.h"
-
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-int pullTagId1 = 10101;
-int pullTagId2 = 10102;
-int uid1 = 9999;
-int uid2 = 8888;
-ConfigKey configKey(50, 12345);
-ConfigKey badConfigKey(60, 54321);
-int unregisteredUid = 98765;
-int64_t coolDownNs = NS_PER_SEC;
-int64_t timeoutNs = NS_PER_SEC / 2;
-
-AStatsEvent* createSimpleEvent(int32_t atomId, int32_t value) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, atomId);
- AStatsEvent_writeInt32(event, value);
- AStatsEvent_build(event);
- return event;
-}
-
-class FakePullAtomCallback : public BnPullAtomCallback {
-public:
- FakePullAtomCallback(int32_t uid) : mUid(uid){};
- Status onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
- vector<StatsEventParcel> parcels;
- AStatsEvent* event = createSimpleEvent(atomTag, mUid);
- size_t size;
- uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
- StatsEventParcel p;
- // vector.assign() creates a copy, but this is inevitable unless
- // stats_event.h/c uses a vector as opposed to a buffer.
- p.buffer.assign(buffer, buffer + size);
- parcels.push_back(std::move(p));
- AStatsEvent_release(event);
- resultReceiver->pullFinished(atomTag, /*success*/ true, parcels);
- return Status::ok();
- }
- int32_t mUid;
-};
-
-class FakePullUidProvider : public PullUidProvider {
-public:
- vector<int32_t> getPullAtomUids(int atomId) override {
- if (atomId == pullTagId1) {
- return {uid2, uid1};
- } else if (atomId == pullTagId2) {
- return {uid2};
- }
- return {};
- }
-};
-
-sp<StatsPullerManager> createPullerManagerAndRegister() {
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- shared_ptr<FakePullAtomCallback> cb1 = SharedRefBase::make<FakePullAtomCallback>(uid1);
- pullerManager->RegisterPullAtomCallback(uid1, pullTagId1, coolDownNs, timeoutNs, {}, cb1);
- shared_ptr<FakePullAtomCallback> cb2 = SharedRefBase::make<FakePullAtomCallback>(uid2);
- pullerManager->RegisterPullAtomCallback(uid2, pullTagId1, coolDownNs, timeoutNs, {}, cb2);
- pullerManager->RegisterPullAtomCallback(uid1, pullTagId2, coolDownNs, timeoutNs, {}, cb1);
- return pullerManager;
-}
-} // anonymous namespace
-
-TEST(StatsPullerManagerTest, TestPullInvalidUid) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, /*timestamp =*/1, &data));
-}
-
-TEST(StatsPullerManagerTest, TestPullChoosesCorrectUid) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, /*timestamp =*/1, &data));
- ASSERT_EQ(data.size(), 1);
- EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
- ASSERT_EQ(data[0]->getValues().size(), 1);
- EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid1);
-}
-
-TEST(StatsPullerManagerTest, TestPullInvalidConfigKey) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
- sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
- pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, /*timestamp =*/1, &data));
-}
-
-TEST(StatsPullerManagerTest, TestPullConfigKeyGood) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
- sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
- pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, /*timestamp =*/1, &data));
- EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
- ASSERT_EQ(data[0]->getValues().size(), 1);
- EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid2);
-}
-
-TEST(StatsPullerManagerTest, TestPullConfigKeyNoPullerWithUid) {
- sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
- sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
- pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
- vector<shared_ptr<LogEvent>> data;
- EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, /*timestamp =*/1, &data));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/tests/external/StatsPuller_test.cpp b/cmds/statsd/tests/external/StatsPuller_test.cpp
deleted file mode 100644
index 55a90365e151..000000000000
--- a/cmds/statsd/tests/external/StatsPuller_test.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <chrono>
-#include <thread>
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using std::this_thread::sleep_for;
-using testing::Contains;
-
-namespace {
-int pullTagId = 10014;
-
-bool pullSuccess;
-vector<std::shared_ptr<LogEvent>> pullData;
-long pullDelayNs;
-
-class FakePuller : public StatsPuller {
-public:
- FakePuller()
- : StatsPuller(pullTagId, /*coolDownNs=*/MillisToNano(10), /*timeoutNs=*/MillisToNano(5)){};
-
-private:
- bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
- (*data) = pullData;
- sleep_for(std::chrono::nanoseconds(pullDelayNs));
- return pullSuccess;
- }
-};
-
-FakePuller puller;
-
-std::unique_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, pullTagId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
- AStatsEvent_writeInt64(statsEvent, value);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-class StatsPullerTest : public ::testing::Test {
-public:
- StatsPullerTest() {
- }
-
- void SetUp() override {
- puller.ForceClearCache();
- pullSuccess = false;
- pullDelayNs = 0;
- pullData.clear();
- }
-};
-
-} // Anonymous namespace.
-
-TEST_F(StatsPullerTest, PullSuccess) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- sleep_for(std::chrono::milliseconds(11));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsPullerTest, PullFailAfterSuccess) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- sleep_for(std::chrono::milliseconds(11));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = false;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- // Fails due to hitting the cool down.
- pullSuccess = true;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-// Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
-TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
- pullData.push_back(createSimpleEvent(1111L, 33));
- pullSuccess = true;
- // timeout is 5ms
- pullDelayNs = MillisToNano(6);
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
- pullDelayNs = 0;
-
- pullSuccess = true;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullFail) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = false;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullTakeTooLong) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
- pullDelayNs = MillisToNano(6);
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullTooFast) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- dataHolder.clear();
- EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsPullerTest, PullFailsAndTooFast) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = false;
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullSameEventTime) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = true;
- int64_t eventTimeNs = getElapsedRealtimeNs();
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- // Sleep to ensure the cool down expires.
- sleep_for(std::chrono::milliseconds(11));
- pullSuccess = true;
-
- dataHolder.clear();
- EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(1, dataHolder.size());
- EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
- EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
- ASSERT_EQ(1, dataHolder[0]->size());
- EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-// Test pull takes longer than timeout, 2nd pull happens at same event time
-TEST_F(StatsPullerTest, PullTakeTooLongAndPullSameEventTime) {
- pullData.push_back(createSimpleEvent(1111L, 33));
- pullSuccess = true;
- int64_t eventTimeNs = getElapsedRealtimeNs();
- // timeout is 5ms
- pullDelayNs = MillisToNano(6);
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- // Sleep to ensure the cool down expires. 6ms is taken by the delay, so only 5 is needed here.
- sleep_for(std::chrono::milliseconds(5));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
- pullDelayNs = 0;
-
- pullSuccess = true;
- dataHolder.clear();
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullFailsAndPullSameEventTime) {
- pullData.push_back(createSimpleEvent(1111L, 33));
-
- pullSuccess = false;
- int64_t eventTimeNs = getElapsedRealtimeNs();
-
- vector<std::shared_ptr<LogEvent>> dataHolder;
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-
- // Sleep to ensure the cool down expires.
- sleep_for(std::chrono::milliseconds(11));
-
- pullData.clear();
- pullData.push_back(createSimpleEvent(2222L, 44));
-
- pullSuccess = true;
-
- EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
- ASSERT_EQ(0, dataHolder.size());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp
deleted file mode 100644
index a21dc8717776..000000000000
--- a/cmds/statsd/tests/external/puller_util_test.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "external/puller_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "FieldValue.h"
-#include "annotations.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::shared_ptr;
-using std::vector;
-/*
- * Test merge isolated and host uid
- */
-namespace {
-const int uidAtomTagId = 100;
-const vector<int> additiveFields = {3};
-const int nonUidAtomTagId = 200;
-const int timestamp = 1234;
-const int isolatedUid1 = 30;
-const int isolatedUid2 = 40;
-const int isolatedNonAdditiveData = 32;
-const int isolatedAdditiveData = 31;
-const int hostUid = 20;
-const int hostNonAdditiveData = 22;
-const int hostAdditiveData = 21;
-const int attributionAtomTagId = 300;
-
-sp<MockUidMap> makeMockUidMap() {
- return makeMockUidMapForOneHost(hostUid, {isolatedUid1, isolatedUid2});
-}
-
-} // anonymous namespace
-
-TEST(PullerUtilTest, MergeNoDimension) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->22->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeWithDimension) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->32->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
- hostAdditiveData),
-
- // 20->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoMergeHostUidOnly) {
- vector<shared_ptr<LogEvent>> data = {
- // 20->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, IsolatedUidOnly) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 30->22->21
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- // 20->32->31
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
- // 20->22->21
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->32->31
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 31->32->21
- makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData,
- hostAdditiveData),
-
- // 20->32->21
- makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
- hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(3, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
- actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoNeedToMerge) {
- vector<shared_ptr<LogEvent>> data = {
- // 32->31
- CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 22->21
- CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData,
- hostAdditiveData),
-
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(2, actualFieldValues->size());
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(2, actualFieldValues->size());
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeNoDimensionAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->tag1->400->tag2->22->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData),
-
- // 20->tag1->400->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeWithDimensionAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 200->tag1->30->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 200->tag1->20->tag2->32->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
- {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-
- // 200->tag1->20->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 20->tag1->400->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 20->tag1->400->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->tag1->400->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 30->tag1->400->tag2->22->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(2, (int)data.size());
-
- // 20->tag1->400->tag2->32->31
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
- // 20->tag1->400->tag2->22->21
- actualFieldValues = &data[1]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) {
- vector<shared_ptr<LogEvent>> data = {
- // 30->tag1->400->tag2->32->31
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData,
- isolatedAdditiveData),
-
- // 31->tag1->400->tag2->32->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-
- // 20->tag1->400->tag2->32->21
- makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
- {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
- };
-
- sp<MockUidMap> uidMap = makeMockUidMap();
- mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
- ASSERT_EQ(1, (int)data.size());
-
- const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
- ASSERT_EQ(6, actualFieldValues->size());
- EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
- EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
- EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
- EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
- EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
- EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
- actualFieldValues->at(5).mValue.int_value);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
deleted file mode 100644
index 428c46f8a0d2..000000000000
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/guardrail/StatsdStats.h"
-#include "statslog_statsdtest.h"
-#include "tests/statsd_test_util.h"
-
-#include <gtest/gtest.h>
-#include <vector>
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-TEST(StatsdStatsTest, TestValidConfigAdd) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- const int metricsCount = 10;
- const int conditionsCount = 20;
- const int matchersCount = 30;
- const int alertsCount = 10;
- stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
- true /*valid config*/);
- vector<uint8_t> output;
- stats.dumpStats(&output, false /*reset stats*/);
-
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- EXPECT_EQ(0, configReport.uid());
- EXPECT_EQ(12345, configReport.id());
- EXPECT_EQ(metricsCount, configReport.metric_count());
- EXPECT_EQ(conditionsCount, configReport.condition_count());
- EXPECT_EQ(matchersCount, configReport.matcher_count());
- EXPECT_EQ(alertsCount, configReport.alert_count());
- EXPECT_EQ(true, configReport.is_valid());
- EXPECT_FALSE(configReport.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestInvalidConfigAdd) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- const int metricsCount = 10;
- const int conditionsCount = 20;
- const int matchersCount = 30;
- const int alertsCount = 10;
- stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
- false /*bad config*/);
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
-
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- // The invalid config should be put into icebox with a deletion time.
- EXPECT_TRUE(configReport.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestConfigRemove) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- const int metricsCount = 10;
- const int conditionsCount = 20;
- const int matchersCount = 30;
- const int alertsCount = 10;
- stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
- true);
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- EXPECT_FALSE(configReport.has_deletion_time_sec());
-
- stats.noteConfigRemoved(key);
- stats.dumpStats(&output, false);
- good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport2 = report.config_stats(0);
- EXPECT_TRUE(configReport2.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestSubStats) {
- StatsdStats stats;
- ConfigKey key(0, 12345);
- stats.noteConfigReceived(key, 2, 3, 4, 5, {std::make_pair(123, 456)}, true);
-
- stats.noteMatcherMatched(key, StringToId("matcher1"));
- stats.noteMatcherMatched(key, StringToId("matcher1"));
- stats.noteMatcherMatched(key, StringToId("matcher2"));
-
- stats.noteConditionDimensionSize(key, StringToId("condition1"), 250);
- stats.noteConditionDimensionSize(key, StringToId("condition1"), 240);
-
- stats.noteMetricDimensionSize(key, StringToId("metric1"), 201);
- stats.noteMetricDimensionSize(key, StringToId("metric1"), 202);
-
- stats.noteAnomalyDeclared(key, StringToId("alert1"));
- stats.noteAnomalyDeclared(key, StringToId("alert1"));
- stats.noteAnomalyDeclared(key, StringToId("alert2"));
-
- // broadcast-> 2
- stats.noteBroadcastSent(key);
- stats.noteBroadcastSent(key);
-
- // data drop -> 1
- stats.noteDataDropped(key, 123);
-
- // dump report -> 3
- stats.noteMetricsReportSent(key, 0);
- stats.noteMetricsReportSent(key, 0);
- stats.noteMetricsReportSent(key, 0);
-
- // activation_time_sec -> 2
- stats.noteActiveStatusChanged(key, true);
- stats.noteActiveStatusChanged(key, true);
-
- // deactivation_time_sec -> 1
- stats.noteActiveStatusChanged(key, false);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, true); // Dump and reset stats
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport = report.config_stats(0);
- ASSERT_EQ(2, configReport.broadcast_sent_time_sec_size());
- ASSERT_EQ(1, configReport.data_drop_time_sec_size());
- ASSERT_EQ(1, configReport.data_drop_bytes_size());
- EXPECT_EQ(123, configReport.data_drop_bytes(0));
- ASSERT_EQ(3, configReport.dump_report_time_sec_size());
- ASSERT_EQ(3, configReport.dump_report_data_size_size());
- ASSERT_EQ(2, configReport.activation_time_sec_size());
- ASSERT_EQ(1, configReport.deactivation_time_sec_size());
- ASSERT_EQ(1, configReport.annotation_size());
- EXPECT_EQ(123, configReport.annotation(0).field_int64());
- EXPECT_EQ(456, configReport.annotation(0).field_int32());
-
- ASSERT_EQ(2, configReport.matcher_stats_size());
- // matcher1 is the first in the list
- if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
- EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
- EXPECT_EQ(1, configReport.matcher_stats(1).matched_times());
- EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(1).id());
- } else {
- // matcher1 is the second in the list.
- EXPECT_EQ(1, configReport.matcher_stats(0).matched_times());
- EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(0).id());
-
- EXPECT_EQ(2, configReport.matcher_stats(1).matched_times());
- EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
- }
-
- ASSERT_EQ(2, configReport.alert_stats_size());
- bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
- EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
- EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
- EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
- EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
-
- ASSERT_EQ(1, configReport.condition_stats_size());
- EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
- EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
-
- ASSERT_EQ(1, configReport.metric_stats_size());
- EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
- EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
-
- // after resetting the stats, some new events come
- stats.noteMatcherMatched(key, StringToId("matcher99"));
- stats.noteConditionDimensionSize(key, StringToId("condition99"), 300);
- stats.noteMetricDimensionSize(key, StringToId("metric99tion99"), 270);
- stats.noteAnomalyDeclared(key, StringToId("alert99"));
-
- // now the config stats should only contain the stats about the new event.
- stats.dumpStats(&output, false);
- good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
- ASSERT_EQ(1, report.config_stats_size());
- const auto& configReport2 = report.config_stats(0);
- ASSERT_EQ(1, configReport2.matcher_stats_size());
- EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
- EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
-
- ASSERT_EQ(1, configReport2.condition_stats_size());
- EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
- EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
-
- ASSERT_EQ(1, configReport2.metric_stats_size());
- EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
- EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
-
- ASSERT_EQ(1, configReport2.alert_stats_size());
- EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
- EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
-}
-
-TEST(StatsdStatsTest, TestAtomLog) {
- StatsdStats stats;
- time_t now = time(nullptr);
- // old event, we get it from the stats buffer. should be ignored.
- stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, 1000);
-
- stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 1);
- stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 2);
- stats.noteAtomLogged(util::APP_CRASH_OCCURRED, now + 3);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(2, report.atom_stats_size());
- bool sensorAtomGood = false;
- bool dropboxAtomGood = false;
-
- for (const auto& atomStats : report.atom_stats()) {
- if (atomStats.tag() == util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
- sensorAtomGood = true;
- }
- if (atomStats.tag() == util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
- dropboxAtomGood = true;
- }
- }
-
- EXPECT_TRUE(dropboxAtomGood);
- EXPECT_TRUE(sensorAtomGood);
-}
-
-TEST(StatsdStatsTest, TestNonPlatformAtomLog) {
- StatsdStats stats;
- time_t now = time(nullptr);
- int newAtom1 = StatsdStats::kMaxPushedAtomId + 1;
- int newAtom2 = StatsdStats::kMaxPushedAtomId + 2;
-
- stats.noteAtomLogged(newAtom1, now + 1);
- stats.noteAtomLogged(newAtom1, now + 2);
- stats.noteAtomLogged(newAtom2, now + 3);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(2, report.atom_stats_size());
- bool newAtom1Good = false;
- bool newAtom2Good = false;
-
- for (const auto& atomStats : report.atom_stats()) {
- if (atomStats.tag() == newAtom1 && atomStats.count() == 2) {
- newAtom1Good = true;
- }
- if (atomStats.tag() == newAtom2 && atomStats.count() == 1) {
- newAtom2Good = true;
- }
- }
-
- EXPECT_TRUE(newAtom1Good);
- EXPECT_TRUE(newAtom2Good);
-}
-
-TEST(StatsdStatsTest, TestPullAtomStats) {
- StatsdStats stats;
-
- stats.updateMinPullIntervalSec(util::DISK_SPACE, 3333L);
- stats.updateMinPullIntervalSec(util::DISK_SPACE, 2222L);
- stats.updateMinPullIntervalSec(util::DISK_SPACE, 4444L);
-
- stats.notePull(util::DISK_SPACE);
- stats.notePullTime(util::DISK_SPACE, 1111L);
- stats.notePullDelay(util::DISK_SPACE, 1111L);
- stats.notePull(util::DISK_SPACE);
- stats.notePullTime(util::DISK_SPACE, 3333L);
- stats.notePullDelay(util::DISK_SPACE, 3335L);
- stats.notePull(util::DISK_SPACE);
- stats.notePullFromCache(util::DISK_SPACE);
- stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
- stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, false);
- stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
- stats.notePullBinderCallFailed(util::DISK_SPACE);
- stats.notePullUidProviderNotFound(util::DISK_SPACE);
- stats.notePullerNotFound(util::DISK_SPACE);
- stats.notePullerNotFound(util::DISK_SPACE);
- stats.notePullTimeout(util::DISK_SPACE, 3000L, 6000L);
- stats.notePullTimeout(util::DISK_SPACE, 4000L, 7000L);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(1, report.pulled_atom_stats_size());
-
- EXPECT_EQ(util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
- EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
- EXPECT_EQ(1, report.pulled_atom_stats(0).total_pull_from_cache());
- EXPECT_EQ(2222L, report.pulled_atom_stats(0).min_pull_interval_sec());
- EXPECT_EQ(2222L, report.pulled_atom_stats(0).average_pull_time_nanos());
- EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
- EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
- EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
- EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
- EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
- EXPECT_EQ(1L, report.pulled_atom_stats(0).binder_call_failed());
- EXPECT_EQ(1L, report.pulled_atom_stats(0).failed_uid_provider_not_found());
- EXPECT_EQ(2L, report.pulled_atom_stats(0).puller_not_found());
- ASSERT_EQ(2, report.pulled_atom_stats(0).pull_atom_metadata_size());
- EXPECT_EQ(3000L, report.pulled_atom_stats(0).pull_atom_metadata(0).pull_timeout_uptime_millis());
- EXPECT_EQ(4000L, report.pulled_atom_stats(0).pull_atom_metadata(1).pull_timeout_uptime_millis());
- EXPECT_EQ(6000L, report.pulled_atom_stats(0).pull_atom_metadata(0)
- .pull_timeout_elapsed_millis());
- EXPECT_EQ(7000L, report.pulled_atom_stats(0).pull_atom_metadata(1)
- .pull_timeout_elapsed_millis());
-}
-
-TEST(StatsdStatsTest, TestAtomMetricsStats) {
- StatsdStats stats;
- time_t now = time(nullptr);
- // old event, we get it from the stats buffer. should be ignored.
- stats.noteBucketDropped(1000L);
-
- stats.noteBucketBoundaryDelayNs(1000L, -1L);
- stats.noteBucketBoundaryDelayNs(1000L, -10L);
- stats.noteBucketBoundaryDelayNs(1000L, 2L);
-
- stats.noteBucketBoundaryDelayNs(1001L, 1L);
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- ASSERT_EQ(2, report.atom_metric_stats().size());
-
- auto atomStats = report.atom_metric_stats(0);
- EXPECT_EQ(1000L, atomStats.metric_id());
- EXPECT_EQ(1L, atomStats.bucket_dropped());
- EXPECT_EQ(-10L, atomStats.min_bucket_boundary_delay_ns());
- EXPECT_EQ(2L, atomStats.max_bucket_boundary_delay_ns());
-
- auto atomStats2 = report.atom_metric_stats(1);
- EXPECT_EQ(1001L, atomStats2.metric_id());
- EXPECT_EQ(0L, atomStats2.bucket_dropped());
- EXPECT_EQ(0L, atomStats2.min_bucket_boundary_delay_ns());
- EXPECT_EQ(1L, atomStats2.max_bucket_boundary_delay_ns());
-}
-
-TEST(StatsdStatsTest, TestAnomalyMonitor) {
- StatsdStats stats;
- stats.noteRegisteredAnomalyAlarmChanged();
- stats.noteRegisteredAnomalyAlarmChanged();
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- bool good = report.ParseFromArray(&output[0], output.size());
- EXPECT_TRUE(good);
-
- EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
-}
-
-TEST(StatsdStatsTest, TestTimestampThreshold) {
- StatsdStats stats;
- vector<int32_t> timestamps;
- for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
- timestamps.push_back(i);
- }
- ConfigKey key(0, 12345);
- stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
-
- for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
- stats.noteDataDropped(key, timestamps[i]);
- stats.noteBroadcastSent(key, timestamps[i]);
- stats.noteMetricsReportSent(key, 0, timestamps[i]);
- stats.noteActiveStatusChanged(key, true, timestamps[i]);
- stats.noteActiveStatusChanged(key, false, timestamps[i]);
- }
-
- int32_t newTimestamp = 10000;
-
- // now it should trigger removing oldest timestamp
- stats.noteDataDropped(key, 123, 10000);
- stats.noteBroadcastSent(key, 10000);
- stats.noteMetricsReportSent(key, 0, 10000);
- stats.noteActiveStatusChanged(key, true, 10000);
- stats.noteActiveStatusChanged(key, false, 10000);
-
- EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end());
- const auto& configStats = stats.mConfigStats[key];
-
- size_t maxCount = StatsdStats::kMaxTimestampCount;
- ASSERT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
- ASSERT_EQ(maxCount, configStats->data_drop_time_sec.size());
- ASSERT_EQ(maxCount, configStats->dump_report_stats.size());
- ASSERT_EQ(maxCount, configStats->activation_time_sec.size());
- ASSERT_EQ(maxCount, configStats->deactivation_time_sec.size());
-
- // the oldest timestamp is the second timestamp in history
- EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
- EXPECT_EQ(1, configStats->data_drop_bytes.front());
- EXPECT_EQ(1, configStats->dump_report_stats.front().first);
- EXPECT_EQ(1, configStats->activation_time_sec.front());
- EXPECT_EQ(1, configStats->deactivation_time_sec.front());
-
- // the last timestamp is the newest timestamp.
- EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back());
- EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back());
- EXPECT_EQ(123, configStats->data_drop_bytes.back());
- EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
- EXPECT_EQ(newTimestamp, configStats->activation_time_sec.back());
- EXPECT_EQ(newTimestamp, configStats->deactivation_time_sec.back());
-}
-
-TEST(StatsdStatsTest, TestSystemServerCrash) {
- StatsdStats stats;
- vector<int32_t> timestamps;
- for (int i = 0; i < StatsdStats::kMaxSystemServerRestarts; i++) {
- timestamps.push_back(i);
- stats.noteSystemServerRestart(timestamps[i]);
- }
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
- const int maxCount = StatsdStats::kMaxSystemServerRestarts;
- ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
-
- stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
- output.clear();
- stats.dumpStats(&output, false);
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
- ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
- EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
-}
-
-TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit) {
- StatsdStats stats;
- int uid1 = 1;
- int uid2 = 2;
- stats.noteActivationBroadcastGuardrailHit(uid1, 10);
- stats.noteActivationBroadcastGuardrailHit(uid1, 20);
-
- // Test that we only keep 20 timestamps.
- for (int i = 0; i < 100; i++) {
- stats.noteActivationBroadcastGuardrailHit(uid2, i);
- }
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-
- ASSERT_EQ(2, report.activation_guardrail_stats_size());
- bool uid1Good = false;
- bool uid2Good = false;
- for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
- if (uid1 == guardrailTimes.uid()) {
- uid1Good = true;
- ASSERT_EQ(2, guardrailTimes.guardrail_met_sec_size());
- EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
- EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
- } else if (uid2 == guardrailTimes.uid()) {
- int maxCount = StatsdStats::kMaxTimestampCount;
- uid2Good = true;
- ASSERT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
- for (int i = 0; i < maxCount; i++) {
- EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
- }
- } else {
- FAIL() << "Unexpected uid.";
- }
- }
- EXPECT_TRUE(uid1Good);
- EXPECT_TRUE(uid2Good);
-}
-
-TEST(StatsdStatsTest, TestAtomErrorStats) {
- StatsdStats stats;
-
- int pushAtomTag = 100;
- int pullAtomTag = 1000;
- int numErrors = 10;
-
- for (int i = 0; i < numErrors; i++) {
- // We must call noteAtomLogged as well because only those pushed atoms
- // that have been logged will have stats printed about them in the
- // proto.
- stats.noteAtomLogged(pushAtomTag, /*timeSec=*/0);
- stats.noteAtomError(pushAtomTag, /*pull=*/false);
-
- stats.noteAtomError(pullAtomTag, /*pull=*/true);
- }
-
- vector<uint8_t> output;
- stats.dumpStats(&output, false);
- StatsdStatsReport report;
- EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-
- // Check error count = numErrors for push atom
- ASSERT_EQ(1, report.atom_stats_size());
- const auto& pushedAtomStats = report.atom_stats(0);
- EXPECT_EQ(pushAtomTag, pushedAtomStats.tag());
- EXPECT_EQ(numErrors, pushedAtomStats.error_count());
-
- // Check error count = numErrors for pull atom
- ASSERT_EQ(1, report.pulled_atom_stats_size());
- const auto& pulledAtomStats = report.pulled_atom_stats(0);
- EXPECT_EQ(pullAtomTag, pulledAtomStats.atom_id());
- EXPECT_EQ(numErrors, pulledAtomStats.atom_error_count());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/indexed_priority_queue_test.cpp b/cmds/statsd/tests/indexed_priority_queue_test.cpp
deleted file mode 100644
index 3a654565b4aa..000000000000
--- a/cmds/statsd/tests/indexed_priority_queue_test.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/anomaly/indexed_priority_queue.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-
-/** struct for template in indexed_priority_queue */
-struct AATest : public RefBase {
- AATest(uint32_t val, std::string a, std::string b) : val(val), a(a), b(b) {
- }
-
- const int val;
- const std::string a;
- const std::string b;
-
- struct Smaller {
- bool operator()(const sp<const AATest> a, const sp<const AATest> b) const {
- return (a->val < b->val);
- }
- };
-};
-
-#ifdef __ANDROID__
-TEST(indexed_priority_queue, empty_and_size) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
-
- ASSERT_EQ(0u, ipq.size());
- EXPECT_TRUE(ipq.empty());
-
- ipq.push(aa4);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_FALSE(ipq.empty());
-
- ipq.push(aa8);
- ASSERT_EQ(2u, ipq.size());
- EXPECT_FALSE(ipq.empty());
-
- ipq.remove(aa4);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_FALSE(ipq.empty());
-
- ipq.remove(aa8);
- ASSERT_EQ(0u, ipq.size());
- EXPECT_TRUE(ipq.empty());
-}
-
-TEST(indexed_priority_queue, top) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa2 = new AATest{2, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa12 = new AATest{12, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa16 = new AATest{16, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa20 = new AATest{20, emptyMetricId, emptyDimensionId};
-
- EXPECT_EQ(ipq.top(), nullptr);
-
- // add 8, 4, 12
- ipq.push(aa8);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.push(aa12);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.push(aa4);
- EXPECT_EQ(ipq.top(), aa4);
-
- // remove 12, 4
- ipq.remove(aa12);
- EXPECT_EQ(ipq.top(), aa4);
-
- ipq.remove(aa4);
- EXPECT_EQ(ipq.top(), aa8);
-
- // add 16, 2, 20
- ipq.push(aa16);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.push(aa2);
- EXPECT_EQ(ipq.top(), aa2);
-
- ipq.push(aa20);
- EXPECT_EQ(ipq.top(), aa2);
-
- // remove 2, 20, 16, 8
- ipq.remove(aa2);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.remove(aa20);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.remove(aa16);
- EXPECT_EQ(ipq.top(), aa8);
-
- ipq.remove(aa8);
- EXPECT_EQ(ipq.top(), nullptr);
-}
-
-TEST(indexed_priority_queue, push_same_aa) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa4_a = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
-
- ipq.push(aa4_a);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-
- ipq.push(aa4_a);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-
- ipq.push(aa4_b);
- ASSERT_EQ(2u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_TRUE(ipq.contains(aa4_b));
-}
-
-TEST(indexed_priority_queue, remove_nonexistant) {
- std::string emptyMetricId;
- std::string emptyDimensionId;
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa5 = new AATest{5, emptyMetricId, emptyDimensionId};
-
- ipq.push(aa4);
- ipq.remove(aa5);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4));
- EXPECT_FALSE(ipq.contains(aa5));
-}
-
-TEST(indexed_priority_queue, remove_same_aa) {
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- std::string emptyMetricId;
- std::string emptyDimensionId;
- sp<const AATest> aa4_a = new AATest{4, emptyMetricId, emptyDimensionId};
- sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
-
- ipq.push(aa4_a);
- ipq.push(aa4_b);
- ASSERT_EQ(2u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_TRUE(ipq.contains(aa4_b));
-
- ipq.remove(aa4_b);
- ASSERT_EQ(1u, ipq.size());
- EXPECT_TRUE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-
- ipq.remove(aa4_a);
- ASSERT_EQ(0u, ipq.size());
- EXPECT_FALSE(ipq.contains(aa4_a));
- EXPECT_FALSE(ipq.contains(aa4_b));
-}
-
-TEST(indexed_priority_queue, nulls) {
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
-
- EXPECT_TRUE(ipq.empty());
- EXPECT_FALSE(ipq.contains(nullptr));
-
- ipq.push(nullptr);
- EXPECT_TRUE(ipq.empty());
- EXPECT_FALSE(ipq.contains(nullptr));
-
- ipq.remove(nullptr);
- EXPECT_TRUE(ipq.empty());
- EXPECT_FALSE(ipq.contains(nullptr));
-}
-
-TEST(indexed_priority_queue, pop) {
- indexed_priority_queue<AATest, AATest::Smaller> ipq;
- std::string emptyMetricId;
- std::string emptyDimensionId;
- sp<const AATest> a = new AATest{1, emptyMetricId, emptyDimensionId};
- sp<const AATest> b = new AATest{2, emptyMetricId, emptyDimensionId};
- sp<const AATest> c = new AATest{3, emptyMetricId, emptyDimensionId};
-
- ipq.push(c);
- ipq.push(b);
- ipq.push(a);
- ASSERT_EQ(3u, ipq.size());
-
- ipq.pop();
- ASSERT_EQ(2u, ipq.size());
- EXPECT_FALSE(ipq.contains(a));
- EXPECT_TRUE(ipq.contains(b));
- EXPECT_TRUE(ipq.contains(c));
-
- ipq.pop();
- ASSERT_EQ(1u, ipq.size());
- EXPECT_FALSE(ipq.contains(a));
- EXPECT_FALSE(ipq.contains(b));
- EXPECT_TRUE(ipq.contains(c));
-
- ipq.pop();
- ASSERT_EQ(0u, ipq.size());
- EXPECT_FALSE(ipq.contains(a));
- EXPECT_FALSE(ipq.contains(b));
- EXPECT_FALSE(ipq.contains(c));
- EXPECT_TRUE(ipq.empty());
-
- ipq.pop(); // pop an empty queue
- EXPECT_TRUE(ipq.empty());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
deleted file mode 100644
index a15f95bef358..000000000000
--- a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "logd/LogEventQueue.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <thread>
-
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace android;
-using namespace testing;
-
-using std::unique_ptr;
-
-namespace {
-
-std::unique_ptr<LogEvent> makeLogEvent(uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 10);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-} // anonymous namespace
-
-#ifdef __ANDROID__
-TEST(LogEventQueue_test, TestGoodConsumer) {
- LogEventQueue queue(50);
- int64_t timeBaseNs = 100;
- std::thread writer([&queue, timeBaseNs] {
- for (int i = 0; i < 100; i++) {
- int64_t oldestEventNs;
- bool success = queue.push(makeLogEvent(timeBaseNs + i * 1000), &oldestEventNs);
- EXPECT_TRUE(success);
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
- });
-
- std::thread reader([&queue, timeBaseNs] {
- for (int i = 0; i < 100; i++) {
- auto event = queue.waitPop();
- EXPECT_TRUE(event != nullptr);
- // All events are in right order.
- EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
- }
- });
-
- reader.join();
- writer.join();
-}
-
-TEST(LogEventQueue_test, TestSlowConsumer) {
- LogEventQueue queue(50);
- int64_t timeBaseNs = 100;
- std::thread writer([&queue, timeBaseNs] {
- int failure_count = 0;
- int64_t oldestEventNs;
- for (int i = 0; i < 100; i++) {
- bool success = queue.push(makeLogEvent(timeBaseNs + i * 1000), &oldestEventNs);
- if (!success) failure_count++;
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
-
- // There is some remote chance that reader thread not get chance to run before writer thread
- // ends. That's why the following comparison is not "==".
- // There will be at least 45 events lost due to overflow.
- EXPECT_TRUE(failure_count >= 45);
- // The oldest event must be at least the 6th event.
- EXPECT_TRUE(oldestEventNs <= (100 + 5 * 1000));
- });
-
- std::thread reader([&queue, timeBaseNs] {
- // The consumer quickly processed 5 events, then it got stuck (not reading anymore).
- for (int i = 0; i < 5; i++) {
- auto event = queue.waitPop();
- EXPECT_TRUE(event != nullptr);
- // All events are in right order.
- EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
- }
- });
-
- reader.join();
- writer.join();
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/metadata_util_test.cpp b/cmds/statsd/tests/metadata_util_test.cpp
deleted file mode 100644
index 7707890cbd0c..000000000000
--- a/cmds/statsd/tests/metadata_util_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <gtest/gtest.h>
-
-#include "metadata_util.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TEST(MetadataUtilTest, TestWriteAndReadMetricDimensionKey) {
- HashableDimensionKey dim;
- HashableDimensionKey dim2;
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int32_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- dim2.addValue(FieldValue(field1, value1));
- dim2.addValue(FieldValue(field2, value2));
-
- MetricDimensionKey dimKey(dim, dim2);
-
- metadata::MetricDimensionKey metadataDimKey;
- writeMetricDimensionKeyToMetadataDimensionKey(dimKey, &metadataDimKey);
-
- MetricDimensionKey loadedDimKey = loadMetricDimensionKeyFromProto(metadataDimKey);
-
- ASSERT_EQ(loadedDimKey, dimKey);
- ASSERT_EQ(std::hash<MetricDimensionKey>{}(loadedDimKey),
- std::hash<MetricDimensionKey>{}(dimKey));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
deleted file mode 100644
index bb8e7bfd90f4..000000000000
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ /dev/null
@@ -1,476 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/CountMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId, string uid) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeString(statsEvent, uid.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // namespace
-
-// Setup for parameterized tests.
-class CountMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(CountMetricProducerTest_PartialBucket,
- CountMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-TEST(CountMetricProducerTest, TestFirstBucket) {
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
- EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, countProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(CountMetricProducerTest, TestNonDimensionalEvents) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
- int tagId = 1;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, bucketStartTimeNs, bucketStartTimeNs);
-
- // 2 events in bucket 1.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // Flushes at event #2.
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 2);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- // Flushes.
- countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(2LL, buckets[0].mCount);
-
- // 1 matched event happens in bucket 2.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 2, tagId);
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- const auto& bucketInfo2 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1];
- EXPECT_EQ(bucket2StartTimeNs, bucketInfo2.mBucketStartNs);
- EXPECT_EQ(bucket2StartTimeNs + bucketSizeNs, bucketInfo2.mBucketEndNs);
- EXPECT_EQ(1LL, bucketInfo2.mCount);
-
- // nothing happens in bucket 3. we should not record anything for bucket 3.
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- const auto& buckets3 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(2UL, buckets3.size());
-}
-
-TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
- bucketStartTimeNs, bucketStartTimeNs);
-
- countProducer.onConditionChanged(true, bucketStartTimeNs);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, /*atomId=*/1);
- countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- countProducer.onConditionChanged(false /*new condition*/, bucketStartTimeNs + 2);
-
- // Upon this match event, the matched event1 is flushed.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 10, /*atomId=*/1);
- countProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
-
- const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- const auto& bucketInfo = buckets[0];
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
- EXPECT_EQ(1LL, bucketInfo.mCount);
-}
-
-TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
- MetricConditionLink* link = metric.add_links();
- link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
- buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 10, tagId, /*uid=*/"222");
-
- ConditionKey key1;
- key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "111")};
-
- ConditionKey key2;
- key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "222")};
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
-
- EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
-
- CountMetricProducer countProducer(kConfigKey, metric, 0 /*condition tracker index*/,
- {ConditionState::kUnknown}, wizard, bucketStartTimeNs,
- bucketStartTimeNs);
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
- EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- countProducer.mPastBuckets.end());
- const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- const auto& bucketInfo = buckets[0];
- EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
- EXPECT_EQ(1LL, bucketInfo.mCount);
-}
-
-TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket) {
- sp<AlarmMonitor> alarmMonitor;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t eventTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_trigger_if_sum_gt(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
- bucketStartTimeNs, bucketStartTimeNs);
-
- sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
- EXPECT_TRUE(anomalyTracker != nullptr);
-
- // Bucket is not flushed yet.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // App upgrade or boot complete forces bucket flush.
- // Check that there's a past bucket and the bucket end is not adjusted.
- switch (GetParam()) {
- case APP_UPGRADE:
- countProducer.notifyAppUpgrade(eventTimeNs);
- break;
- case BOOT_COMPLETE:
- countProducer.onStatsdInitCompleted(eventTimeNs);
- break;
- }
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(eventTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(0, countProducer.getCurrentBucketNum());
- EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
- // Anomaly tracker only contains full buckets.
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- int64_t lastEndTimeNs = countProducer.getCurrentBucketEndTimeNs();
- // Next event occurs in same bucket as partial bucket created.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 59 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, countProducer.getCurrentBucketNum());
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Third event in following bucket.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + 62 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, countProducer.getCurrentBucketNum());
- EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t eventTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
- bucketStartTimeNs, bucketStartTimeNs);
-
- // Bucket is flushed yet.
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
- // App upgrade or boot complete forces bucket flush.
- // Check that there's a past bucket and the bucket end is not adjusted since the upgrade
- // occurred after the bucket end time.
- switch (GetParam()) {
- case APP_UPGRADE:
- countProducer.notifyAppUpgrade(eventTimeNs);
- break;
- case BOOT_COMPLETE:
- countProducer.onStatsdInitCompleted(eventTimeNs);
- break;
- }
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
-
- // Next event occurs in same bucket as partial bucket created.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 70 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-
- // Third event in following bucket.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + 121 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ((int64_t)eventTimeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
- countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketEndNs);
-}
-
-TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced) {
- sp<AlarmMonitor> alarmMonitor;
- Alert alert;
- alert.set_id(11);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(2);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 1;
- alert.set_refractory_period_secs(refPeriodSec);
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, bucketStartTimeNs, bucketStartTimeNs);
-
- sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + 2 * bucketSizeNs + 1, tagId);
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event4, bucketStartTimeNs + 3 * bucketSizeNs + 1, tagId);
- LogEvent event5(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event5, bucketStartTimeNs + 3 * bucketSizeNs + 2, tagId);
- LogEvent event6(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event6, bucketStartTimeNs + 3 * bucketSizeNs + 3, tagId);
- LogEvent event7(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event7, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, tagId);
-
- // Two events in bucket #0.
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(2L, countProducer.mCurrentSlicedCounter->begin()->second);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // One event in bucket #2. No alarm as bucket #0 is trashed out.
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(1L, countProducer.mCurrentSlicedCounter->begin()->second);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // Two events in bucket #3.
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(3L, countProducer.mCurrentSlicedCounter->begin()->second);
- // Anomaly at event 6 is within refractory period. The alarm is at event 5 timestamp not event 6
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event5.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
- countProducer.onMatchedLogEvent(1 /*log matcher index*/, event7);
- ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
- EXPECT_EQ(4L, countProducer.mCurrentSlicedCounter->begin()->second);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event7.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(CountMetricProducerTest, TestOneWeekTimeUnit) {
- CountMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_WEEK);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- int64_t oneDayNs = 24 * 60 * 60 * 1e9;
- int64_t fiveWeeksNs = 5 * 7 * oneDayNs;
-
- CountMetricProducer countProducer(kConfigKey, metric, -1 /* meaning no condition */, {}, wizard,
- oneDayNs, fiveWeeksNs);
-
- int64_t fiveWeeksOneDayNs = fiveWeeksNs + oneDayNs;
-
- EXPECT_EQ(fiveWeeksNs, countProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(4, countProducer.mCurrentBucketNum);
- EXPECT_EQ(fiveWeeksOneDayNs, countProducer.getCurrentBucketEndTimeNs());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
deleted file mode 100644
index 05cfa37b0ee1..000000000000
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/DurationMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/condition/ConditionWizard.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android::os::statsd;
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // namespace
-
-// Setup for parameterized tests.
-class DurationMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(DurationMetricProducerTest_PartialBucket,
- DurationMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-TEST(DurationMetricTrackerTest, TestFirstBucket) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
-
- EXPECT_EQ(600500000000, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, durationProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, durationProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(DurationMetricTrackerTest, TestNoCondition) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + bucketSizeNs + 2, tagId);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /*no condition*/, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
- EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- durationProducer.mPastBuckets.end());
- const auto& buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(2UL, buckets.size());
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(bucketSizeNs - 1LL, buckets[0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[1].mBucketEndNs);
- EXPECT_EQ(2LL, buckets[1].mDuration);
-}
-
-TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(
- kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
- 1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
- wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
- durationProducer.mCondition = ConditionState::kFalse;
-
- EXPECT_FALSE(durationProducer.mCondition);
- EXPECT_FALSE(durationProducer.isConditionSliced());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
- durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
- EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
- durationProducer.mPastBuckets.end());
- const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets2.size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
- EXPECT_EQ(1LL, buckets2[0].mDuration);
-}
-
-TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
- int tagId = 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
-
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(
- kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
- 1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
- wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
- EXPECT_FALSE(durationProducer.isConditionSliced());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-
- durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
- durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
- const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets2.size());
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
- EXPECT_EQ(1LL, buckets2[0].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDuration) {
- /**
- * The duration starts from the first bucket, through the two partial buckets (10-70sec),
- * another bucket, and ends at the beginning of the next full bucket.
- * Expected buckets:
- * - [10,25]: 14 secs
- * - [25,70]: All 45 secs
- * - [70,130]: All 60 secs
- * - [130, 210]: Only 5 secs (event ended at 135sec)
- */
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(partialBucketSplitTimeNs - startTimeNs, buckets[0].mDuration);
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(3UL, buckets.size());
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - partialBucketSplitTimeNs, buckets[1].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[2].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
- EXPECT_EQ(bucketSizeNs, buckets[2].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationWithSplitInFollowingBucket) {
- /**
- * Expected buckets (start at 11s, upgrade at 75s, end at 135s):
- * - [10,70]: 59 secs
- * - [70,75]: 5 sec
- * - [75,130]: 55 secs
- */
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, buckets[0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketEndNs);
- EXPECT_EQ(partialBucketSplitTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration);
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(3UL, buckets.size());
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[2].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - partialBucketSplitTimeNs,
- buckets[2].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationAnomaly) {
- sp<AlarmMonitor> alarmMonitor;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- // Setup metric with alert.
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
- Alert alert;
- alert.set_num_buckets(3);
- alert.set_trigger_if_sum_gt(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
- EXPECT_TRUE(anomalyTracker != nullptr);
-
- int64_t startTimeNs = bucketStartTimeNs + 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs,
- anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDuration) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
-
- // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
- int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
- int tagId = 1;
-
- DurationMetric metric;
- metric.set_id(1);
- metric.set_bucket(ONE_MINUTE);
- metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- FieldMatcher dimensions;
-
- DurationMetricProducer durationProducer(kConfigKey, metric, -1 /* no condition */, {},
- 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard,
- dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
- int64_t startTimeNs = bucketStartTimeNs + 1;
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, startTimeNs, tagId);
- durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
- EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
- switch (GetParam()) {
- case APP_UPGRADE:
- durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
-
- // Stop occurs in the same partial bucket as created for the app upgrade.
- int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC;
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, endTimeNs, tagId);
- durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
- ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
- durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
- std::vector<DurationBucket> buckets =
- durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
- ASSERT_EQ(1UL, buckets.size());
- EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs);
- EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
deleted file mode 100644
index dfbb9da568b0..000000000000
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/EventMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-namespace {
-void makeLogEvent(LogEvent* logEvent, int32_t atomId, int64_t timestampNs, string str) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeString(statsEvent, str.c_str());
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-} // anonymous namespace
-
-TEST(EventMetricProducerTest, TestNoCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
- EventMetric metric;
- metric.set_id(1);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, bucketStartTimeNs);
-
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
- // Check dump report content.
- ProtoOutputStream output;
- std::set<string> strSet;
- eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
- true /*erase data*/, FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_event_metrics());
- ASSERT_EQ(2, report.event_metrics().data_size());
- EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
- EXPECT_EQ(bucketStartTimeNs + 2, report.event_metrics().data(1).elapsed_timestamp_nanos());
-}
-
-TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
- EventMetric metric;
- metric.set_id(1);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, bucketStartTimeNs);
-
- eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs);
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-
- eventProducer.onConditionChanged(false /*condition*/, bucketStartTimeNs + 2);
-
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
- // Check dump report content.
- ProtoOutputStream output;
- std::set<string> strSet;
- eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
- true /*erase data*/, FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_event_metrics());
- ASSERT_EQ(1, report.event_metrics().data_size());
- EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
-}
-
-TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
- int tagId = 1;
- int conditionTagId = 2;
-
- EventMetric metric;
- metric.set_id(1);
- metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
- MetricConditionLink* link = metric.add_links();
- link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
- buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1, "111");
- ConditionKey key1;
- key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "111")};
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- makeLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10, "222");
- ConditionKey key2;
- key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
- getMockedDimensionKey(conditionTagId, 2, "222")};
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- // Condition is false for first event.
- EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
- // Condition is true for second event.
- EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
-
- EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, bucketStartTimeNs);
-
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
- eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
- // Check dump report content.
- ProtoOutputStream output;
- std::set<string> strSet;
- eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
- true /*erase data*/, FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_event_metrics());
- ASSERT_EQ(1, report.event_metrics().data_size());
- EXPECT_EQ(bucketStartTimeNs + 10, report.event_metrics().data(0).elapsed_timestamp_nanos());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
deleted file mode 100644
index caea42dfe032..000000000000
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/GaugeMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "logd/LogEvent.h"
-#include "metrics_test_helper.h"
-#include "src/matchers/SimpleLogMatchingTracker.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-using std::make_shared;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const int tagId = 1;
-const int64_t metricId = 123;
-const int64_t atomMatcherId = 678;
-const int logEventMatcherIndex = 0;
-const int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-
-shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t value1, string str1,
- int32_t value2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, value1);
- AStatsEvent_writeString(statsEvent, str1.c_str());
- AStatsEvent_writeInt32(statsEvent, value2);
-
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-} // anonymous namespace
-
-// Setup for parameterized tests.
-class GaugeMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(GaugeMetricProducerTest_PartialBucket,
- GaugeMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(GaugeMetricProducerTest, TestFirstBucket) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(false);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(1);
- gaugeFieldMatcher->add_child()->set_field(3);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- // statsd started long ago.
- // The metric starts in the middle of the bucket
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, -1, -1,
- tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, gaugeProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(false);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(1);
- gaugeFieldMatcher->add_child()->set_field(3);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(makeLogEvent(tagId, eventTimeNs + 10, 3, "some value", 11));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(makeLogEvent(tagId, bucket2StartTimeNs + 1, 10, "some value", 11));
-
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(10, it->mValue.int_value);
- it++;
- EXPECT_EQ(11, it->mValue.int_value);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms.front()
- .mFields->begin()
- ->mValue.int_value);
-
- allData.clear();
- allData.push_back(makeLogEvent(tagId, bucket3StartTimeNs + 10, 24, "some value", 25));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(24, it->mValue.int_value);
- it++;
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(25, it->mValue.int_value);
- // One dimension.
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
- it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(10L, it->mValue.int_value);
- it++;
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(11L, it->mValue.int_value);
-
- gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
- ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
- // One dimension.
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
- it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(24L, it->mValue.int_value);
- it++;
- EXPECT_EQ(INT, it->mValue.getType());
- EXPECT_EQ(25L, it->mValue.int_value);
-}
-
-TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) {
- sp<AlarmMonitor> alarmMonitor;
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(true);
-
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(25);
- alert.set_num_buckets(100);
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard,
- -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
- EXPECT_TRUE(anomalyTracker != nullptr);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- EXPECT_EQ(1UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
-
- switch (GetParam()) {
- case APP_UPGRADE:
- gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- // Partial buckets are not sent to anomaly tracker.
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Create an event in the same partial bucket.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ((int64_t)partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- // Partial buckets are not sent to anomaly tracker.
- EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Next event should trigger creation of new bucket and send previous full bucket to anomaly
- // tracker.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- EXPECT_EQ(1L, gaugeProducer.mCurrentBucketNum);
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ((int64_t)bucketStartTimeNs + bucketSizeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
- // Next event should trigger creation of new bucket.
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 125 * NS_PER_SEC, 1, 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- EXPECT_EQ(2L, gaugeProducer.mCurrentBucketNum);
- ASSERT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Return(false))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 2));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-
- switch (GetParam()) {
- case APP_UPGRADE:
- gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(partialBucketSplitTimeNs,
- gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 1, 3));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- metric.set_split_bucket_for_app_upgrade(false);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Return(false));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-
- gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- ASSERT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
- EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- int64_t conditionChangeNs = bucketStartTimeNs + 8;
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs + 10, 100));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- gaugeProducer.onConditionChanged(true, conditionChangeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms.front()
- .mFields->begin()
- ->mValue.int_value);
-
- gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
- gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms.front()
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
- const int conditionTag = 65;
- GaugeMetric metric;
- metric.set_id(1111111);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_gauge_fields_filter()->set_include_all(true);
- metric.set_condition(StringToId("APP_DIED"));
- metric.set_max_pull_delay_sec(INT_MAX);
- auto dim = metric.mutable_dimensions_in_what();
- dim->set_field(tagId);
- dim->add_child()->set_field(1);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, _, _))
- .WillRepeatedly(
- Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
- const bool isPartialLink) {
- int pos[] = {1, 0, 0};
- Field f(conditionTag, pos, 0);
- HashableDimensionKey key;
- key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
-
- return ConditionState::kTrue;
- }));
-
- int64_t sliceConditionChangeNs = bucketStartTimeNs + 8;
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs + 10, 1000, 100));
- return true;
- }));
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
- {ConditionState::kUnknown}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, -1, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- gaugeProducer.onSlicedConditionMayChange(true, sliceConditionChangeNs);
-
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
- ASSERT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-
- ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1000, 110));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
- sp<AlarmMonitor> alarmMonitor;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Return(false));
-
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(2);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(25);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 60;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
-
- int tagId = 1;
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 13));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- std::shared_ptr<LogEvent> event2 =
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 20, 15);
-
- allData.clear();
- allData.push_back(event2);
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec);
-
- allData.clear();
- allData.push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10, 26));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
- ->second.front()
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
- // This event does not have the gauge field. Thus the current bucket value is 0.
- allData.clear();
- allData.push_back(CreateNoValuesLogEvent(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10));
- gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
-}
-
-TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
- metric.mutable_gauge_fields_filter()->set_include_all(false);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(tagId);
- gaugeFieldMatcher->add_child()->set_field(1);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 4));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 5));
- return true;
- }))
- .WillOnce(Return(true));
-
- int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
-
- LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
- ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
- EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms[0]
- .mFields->begin()
- ->mValue.int_value);
- EXPECT_EQ(5, gaugeProducer.mPastBuckets.begin()
- ->second.back()
- .mGaugeAtoms[1]
- .mFields->begin()
- ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
- metric.mutable_gauge_fields_filter()->set_include_all(true);
- metric.set_max_pull_delay_sec(INT_MAX);
- auto dimensionMatcher = metric.mutable_dimensions_in_what();
- // use field 1 as dimension.
- dimensionMatcher->set_field(tagId);
- dimensionMatcher->add_child()->set_field(1);
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 3, 4));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 5));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 6));
- return true;
- }))
- .WillOnce(Return(true));
-
- int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 10);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
- ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
- ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
- triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
- ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.size());
- auto bucketIt = gaugeProducer.mPastBuckets.begin();
- ASSERT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
- EXPECT_EQ(3, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
- EXPECT_EQ(4, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
- bucketIt++;
- ASSERT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
- EXPECT_EQ(4, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
- EXPECT_EQ(5, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
- EXPECT_EQ(6, bucketIt->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
-}
-
-/*
- * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
- * is smaller than the "min_bucket_size_nanos" specified in the metric config.
- */
-TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
- GaugeMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(FIVE_MINUTES);
- metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
- metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _))
- // Bucket start.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 10));
- return true;
- }));
-
- int triggerId = 5;
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- gaugeProducer.prepareFirstBucket();
-
- LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
- gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- gaugeProducer.onDumpReport(bucketStartTimeNs + 9000000, true /* include recent buckets */, true,
- FAST /* dump_latency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_gauge_metrics());
- ASSERT_EQ(0, report.gauge_metrics().data_size());
- ASSERT_EQ(1, report.gauge_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.gauge_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000),
- report.gauge_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.gauge_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), dropEvent.drop_time_millis());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
deleted file mode 100644
index fda3daaa56aa..000000000000
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/duration_helper/MaxDurationTracker.h"
-#include "src/condition/ConditionWizard.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-using namespace android::os::statsd;
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-const int TagId = 1;
-
-const HashableDimensionKey eventKey = getMockedDimensionKey(TagId, 0, "1");
-const HashableDimensionKey conditionKey = getMockedDimensionKey(TagId, 4, "1");
-const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-const int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
-TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(key1, true, bucketStartTimeNs, ConditionKey());
- // Event starts again. This would not change anything as it already starts.
- tracker.noteStart(key1, true, bucketStartTimeNs + 3, ConditionKey());
- // Stopped.
- tracker.noteStop(key1, bucketStartTimeNs + 10, false);
-
- // Another event starts in this bucket.
- tracker.noteStart(key2, true, bucketStartTimeNs + 20, ConditionKey());
- tracker.noteStop(key2, bucketStartTimeNs + 40, false /*stop all*/);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(20LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestStopAll) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(key1, true, bucketStartTimeNs + 1, ConditionKey());
-
- // Another event starts in this bucket.
- tracker.noteStart(key2, true, bucketStartTimeNs + 20, ConditionKey());
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 40, &buckets);
- tracker.noteStopAll(bucketStartTimeNs + bucketSizeNs + 40);
- EXPECT_TRUE(tracker.mInfos.empty());
- EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
- tracker.flushIfNeeded(bucketStartTimeNs + 3 * bucketSizeNs + 40, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(bucketSizeNs + 40 - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
-}
-
-TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- // The event starts.
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 1, ConditionKey());
-
- // Starts again. Does not DEFAULT_DIMENSION_KEY anything.
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + bucketSizeNs + 1,
- ConditionKey());
-
- // The event stops at early 4th bucket.
- // Notestop is called from DurationMetricProducer's onMatchedLogEvent, which calls
- // flushIfneeded.
- tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 20, &buckets);
- tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + (3 * bucketSizeNs) + 20,
- false /*stop all*/);
- EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
- tracker.flushIfNeeded(bucketStartTimeNs + 4 * bucketSizeNs, &buckets);
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ((3 * bucketSizeNs) + 20 - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
- EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
-}
-
-TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
- const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
- const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- // 2 starts
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 1, ConditionKey());
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 10, ConditionKey());
- // one stop
- tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + 20, false /*stop all*/);
-
- tracker.flushIfNeeded(bucketStartTimeNs + (2 * bucketSizeNs) + 1, &buckets);
- // Because of nesting, still not stopped.
- EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
- // real stop now.
- tracker.noteStop(DEFAULT_DIMENSION_KEY,
- bucketStartTimeNs + (2 * bucketSizeNs) + 5, false);
- tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 1, &buckets);
-
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(2 * bucketSizeNs + 5 - 1, buckets[eventKey][0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
- const HashableDimensionKey conditionDimKey = key1;
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 1, "1");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionDimKey;
-
- /**
- Start in first bucket, stop in second bucket. Condition turns on and off in the first bucket
- and again turns on and off in the second bucket.
- */
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
- int64_t conditionStarts1 = bucketStartTimeNs + 11 * NS_PER_SEC;
- int64_t conditionStops1 = bucketStartTimeNs + 14 * NS_PER_SEC;
- int64_t conditionStarts2 = bucketStartTimeNs + bucketSizeNs + 5 * NS_PER_SEC;
- int64_t conditionStops2 = conditionStarts2 + 10 * NS_PER_SEC;
- int64_t eventStopTimeNs = conditionStops2 + 8 * NS_PER_SEC;
-
- int64_t metricId = 1;
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- 0, bucketStartTimeNs, bucketSizeNs, true, false, {});
- EXPECT_TRUE(tracker.mAnomalyTrackers.empty());
-
- tracker.noteStart(key1, false, eventStartTimeNs, conditionKey1);
- tracker.noteConditionChanged(key1, true, conditionStarts1);
- tracker.noteConditionChanged(key1, false, conditionStops1);
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- ASSERT_EQ(0U, buckets.size());
-
- tracker.noteConditionChanged(key1, true, conditionStarts2);
- tracker.noteConditionChanged(key1, false, conditionStops2);
- tracker.noteStop(key1, eventStopTimeNs, false);
- tracker.flushIfNeeded(bucketStartTimeNs + 2 * bucketSizeNs + 1, &buckets);
- ASSERT_EQ(1U, buckets.size());
- vector<DurationBucket> item = buckets.begin()->second;
- ASSERT_EQ(1UL, item.size());
- EXPECT_EQ((int64_t)(13LL * NS_PER_SEC), item[0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = 13000000000;
- int64_t durationTimeNs = 2 * 1000;
-
- int64_t metricId = 1;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- tracker.noteStart(key1, true, eventStartTimeNs, conditionKey1);
- sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(53ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-
- // Remove the anomaly alarm when the duration is no longer fully met.
- tracker.noteConditionChanged(key1, false, eventStartTimeNs + 15 * NS_PER_SEC);
- ASSERT_EQ(0U, anomalyTracker->mAlarms.size());
-
- // Since the condition was off for 10 seconds, the anomaly should trigger 10 sec later.
- tracker.noteConditionChanged(key1, true, eventStartTimeNs + 25 * NS_PER_SEC);
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(63ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-// This tests that we correctly compute the predicted time of an anomaly assuming that the current
-// state continues forward as-is.
-TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
- ConditionKey conditionKey2;
- conditionKey2[StringToId("APP_BACKGROUND")] = getMockedDimensionKey(TagId, 4, "2");
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- /**
- * Suppose we have two sub-dimensions that we're taking the MAX over. In the first of these
- * nested dimensions, we enter the pause state after 3 seconds. When we resume, the second
- * dimension has already been running for 4 seconds. Thus, we have 40-4=36 seconds remaining
- * before we trigger the anomaly.
- */
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC; // Condition is off at start.
- int64_t conditionStarts1 = bucketStartTimeNs + 11 * NS_PER_SEC;
- int64_t conditionStops1 = bucketStartTimeNs + 14 * NS_PER_SEC;
- int64_t conditionStarts2 = bucketStartTimeNs + 20 * NS_PER_SEC;
- int64_t eventStartTimeNs2 = conditionStarts2 - 4 * NS_PER_SEC;
-
- int64_t metricId = 1;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- tracker.noteStart(key1, false, eventStartTimeNs, conditionKey1);
- tracker.noteConditionChanged(key1, true, conditionStarts1);
- tracker.noteConditionChanged(key1, false, conditionStops1);
- tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2); // Condition is on already.
- tracker.noteConditionChanged(key1, true, conditionStarts2);
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- auto alarm = anomalyTracker->mAlarms.begin()->second;
- int64_t anomalyFireTimeSec = alarm->timestampSec;
- EXPECT_EQ(conditionStarts2 + 36 * NS_PER_SEC,
- (long long)anomalyFireTimeSec * NS_PER_SEC);
-
- // Now we test the calculation now that there's a refractory period.
- // At the correct time, declare the anomaly. This will set a refractory period. Make sure it
- // gets correctly taken into account in future predictAnomalyTimestampNs calculations.
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
- anomalyTracker->informAlarmsFired(anomalyFireTimeSec * NS_PER_SEC, firedAlarms);
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- int64_t refractoryPeriodEndsSec = anomalyFireTimeSec + refPeriodSec;
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), refractoryPeriodEndsSec);
-
- // Now stop and start again. Make sure the new predictAnomalyTimestampNs takes into account
- // the refractory period correctly.
- int64_t eventStopTimeNs = anomalyFireTimeSec * NS_PER_SEC + 10;
- tracker.noteStop(key1, eventStopTimeNs, false);
- tracker.noteStop(key2, eventStopTimeNs, false);
- tracker.noteStart(key1, true, eventStopTimeNs + 1000000, conditionKey1);
- // Anomaly is ongoing, but we're still in the refractory period.
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ(refractoryPeriodEndsSec, (long long)(alarm->timestampSec));
-
- // Makes sure it is correct after the refractory period is over.
- tracker.noteStop(key1, eventStopTimeNs + 2000000, false);
- int64_t justBeforeRefPeriodNs = (refractoryPeriodEndsSec - 2) * NS_PER_SEC;
- tracker.noteStart(key1, true, justBeforeRefPeriodNs, conditionKey1);
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ(justBeforeRefPeriodNs + 40 * NS_PER_SEC,
- (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-// Suppose that within one tracker there are two dimensions A and B.
-// Suppose A starts, then B starts, and then A stops. We still need to set an anomaly based on the
-// elapsed duration of B.
-TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) {
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey conditionKey1;
- MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
- conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
- ConditionKey conditionKey2;
- conditionKey2[StringToId("APP_BACKGROUND")] = getMockedDimensionKey(TagId, 4, "2");
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- /**
- * Suppose we have two sub-dimensions that we're taking the MAX over. In the first of these
- * nested dimensions, are started for 8 seconds. When we stop, the other nested dimension has
- * been started for 5 seconds. So we can only allow 35 more seconds from now.
- */
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs1 = bucketStartTimeNs + 5 * NS_PER_SEC; // Condition is off at start.
- int64_t eventStopTimeNs1 = bucketStartTimeNs + 13 * NS_PER_SEC;
- int64_t eventStartTimeNs2 = bucketStartTimeNs + 8 * NS_PER_SEC;
-
- int64_t metricId = 1;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- tracker.noteStart(key1, true, eventStartTimeNs1, conditionKey1);
- tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2);
- tracker.noteStop(key1, eventStopTimeNs1, false);
- ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
- auto alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ(eventStopTimeNs1 + 35 * NS_PER_SEC,
- (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
deleted file mode 100644
index 1d6f7de5e7e3..000000000000
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/duration_helper/OringDurationTracker.h"
-#include "src/condition/ConditionWizard.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-const int TagId = 1;
-const int64_t metricId = 123;
-const HashableDimensionKey eventKey = getMockedDimensionKey(TagId, 0, "event");
-
-const HashableDimensionKey kConditionKey1 = getMockedDimensionKey(TagId, 1, "maps");
-const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-const int64_t bucketSizeNs = 30 * NS_PER_SEC;
-
-TEST(OringDurationTrackerTest, TestDurationOverlap) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 10, ConditionKey()); // overlapping wl
- EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
- tracker.flushIfNeeded(eventStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(durationTimeNs, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationNested) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 10, ConditionKey()); // overlapping wl
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2000, false);
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestStopAll) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const std::vector<HashableDimensionKey> kConditionKey1 =
- {getMockedDimensionKey(TagId, 1, "maps")};
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- tracker.noteStart(kEventKey2, true, eventStartTimeNs + 10, ConditionKey()); // overlapping wl
-
- tracker.noteStopAll(eventStartTimeNs + 2003);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs, &buckets);
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2 * bucketSizeNs, ConditionKey());
- EXPECT_EQ((long long)(bucketStartTimeNs + 2 * bucketSizeNs), tracker.mLastStartTime);
-
- ASSERT_EQ(2u, buckets[eventKey].size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 10, false);
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 12, false);
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 12, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(2u, buckets[eventKey].size());
- EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
- EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChange) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey key1;
- key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
- EXPECT_CALL(*wizard, query(_, key1, _)) // #4
- .WillOnce(Return(ConditionState::kFalse));
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- true, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
-
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(5LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey key1;
- key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
- EXPECT_CALL(*wizard, query(_, key1, _))
- .Times(2)
- .WillOnce(Return(ConditionState::kFalse))
- .WillOnce(Return(ConditionState::kTrue));
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
- int64_t durationTimeNs = 2 * 1000;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- true, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
- // condition to false; record duration 5n
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
- // condition to true.
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 1000);
- // 2nd duration: 1000ns
- tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(1005LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- ConditionKey key1;
- key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
- EXPECT_CALL(*wizard, query(_, key1, _)) // #4
- .WillOnce(Return(ConditionState::kFalse));
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
- int64_t bucketStartTimeNs = 10000000000;
- int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2, key1);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 3, false);
-
- tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 15);
-
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
-
- tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(15LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- alert.set_refractory_period_secs(1);
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
-
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
- bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
- {anomalyTracker});
-
- // Nothing in the past bucket.
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(alert.trigger_if_sum_gt() + eventStartTimeNs),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-
- tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStartTimeNs + 3, false);
- ASSERT_EQ(0u, buckets[eventKey].size());
-
- int64_t event1StartTimeNs = eventStartTimeNs + 10;
- tracker.noteStart(kEventKey1, true, event1StartTimeNs, ConditionKey());
- // No past buckets. The anomaly will happen in bucket #0.
- EXPECT_EQ((long long)(event1StartTimeNs + alert.trigger_if_sum_gt() - 3),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event1StartTimeNs));
-
- int64_t event1StopTimeNs = eventStartTimeNs + bucketSizeNs + 10;
- tracker.flushIfNeeded(event1StopTimeNs, &buckets);
- tracker.noteStop(kEventKey1, event1StopTimeNs, false);
-
- EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
- ASSERT_EQ(1u, buckets[eventKey].size());
- EXPECT_EQ(3LL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10,
- buckets[eventKey][0].mDuration);
-
- const int64_t bucket0Duration = 3ULL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10;
- const int64_t bucket1Duration = eventStartTimeNs + 10 - bucketStartTimeNs;
-
- // One past buckets. The anomaly will happen in bucket #1.
- int64_t event2StartTimeNs = eventStartTimeNs + bucketSizeNs + 15;
- tracker.noteStart(kEventKey1, true, event2StartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(event2StartTimeNs + alert.trigger_if_sum_gt() - bucket0Duration -
- bucket1Duration),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event2StartTimeNs));
- tracker.noteStop(kEventKey1, event2StartTimeNs + 1, false);
-
- // Only one past buckets is applicable. Bucket +0 should be trashed. The anomaly will happen in
- // bucket #2.
- int64_t event3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs - 9 * NS_PER_SEC;
- tracker.noteStart(kEventKey1, true, event3StartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(event3StartTimeNs + alert.trigger_if_sum_gt() - bucket1Duration - 1LL),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event3StartTimeNs));
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) {
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(5 * NS_PER_SEC);
- alert.set_num_buckets(1);
- alert.set_refractory_period_secs(20);
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 0;
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard, 1,
-
- true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
- bucketSizeNs, true, false, {anomalyTracker});
-
- int64_t eventStartTimeNs = bucketStartTimeNs + 9 * NS_PER_SEC;
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
- // Anomaly happens in the bucket #1.
- EXPECT_EQ((long long)(bucketStartTimeNs + 14 * NS_PER_SEC),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-
- tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + 14 * NS_PER_SEC, false);
-
- EXPECT_EQ((long long)(bucketStartTimeNs + 34 * NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY));
-
- int64_t event2StartTimeNs = bucketStartTimeNs + 22 * NS_PER_SEC;
- EXPECT_EQ((long long)(bucketStartTimeNs + 34 * NS_PER_SEC) / NS_PER_SEC,
- anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY));
- EXPECT_EQ((long long)(bucketStartTimeNs + 35 * NS_PER_SEC),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event2StartTimeNs));
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) {
- // Test the cases where the refractory period is smaller than the bucket size, longer than
- // the bucket size, and longer than 2x of the anomaly detection window.
- for (int j = 0; j < 3; j++) {
- int64_t thresholdNs = j * bucketSizeNs + 5 * NS_PER_SEC;
- for (int i = 0; i <= 7; ++i) {
-
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(thresholdNs);
- alert.set_num_buckets(3);
- alert.set_refractory_period_secs(
- bucketSizeNs / NS_PER_SEC / 2 + i * bucketSizeNs / NS_PER_SEC);
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 101;
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard,
- 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
- bucketSizeNs, true, false, {anomalyTracker});
-
- int64_t eventStartTimeNs = bucketStartTimeNs + 9 * NS_PER_SEC;
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
- EXPECT_EQ((long long)(eventStartTimeNs + thresholdNs),
- tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
- int64_t eventStopTimeNs = eventStartTimeNs + thresholdNs + NS_PER_SEC;
- tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStopTimeNs, false);
-
- int64_t refractoryPeriodEndSec =
- anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY);
- EXPECT_EQ(eventStopTimeNs / (int64_t)NS_PER_SEC + alert.refractory_period_secs(),
- refractoryPeriodEndSec);
-
- // Acquire and release a wakelock in the next bucket.
- int64_t event2StartTimeNs = eventStopTimeNs + bucketSizeNs;
- tracker.noteStart(DEFAULT_DIMENSION_KEY, true, event2StartTimeNs, ConditionKey());
- int64_t event2StopTimeNs = event2StartTimeNs + 4 * NS_PER_SEC;
- tracker.noteStop(DEFAULT_DIMENSION_KEY, event2StopTimeNs, false);
-
- // Test the alarm prediction works well when seeing another wakelock start event.
- for (int k = 0; k <= 2; ++k) {
- int64_t event3StartTimeNs = event2StopTimeNs + NS_PER_SEC + k * bucketSizeNs;
- int64_t alarmTimestampNs =
- tracker.predictAnomalyTimestampNs(*anomalyTracker, event3StartTimeNs);
- EXPECT_GT(alarmTimestampNs, 0u);
- EXPECT_GE(alarmTimestampNs, event3StartTimeNs);
- EXPECT_GE(alarmTimestampNs, refractoryPeriodEndSec *(int64_t) NS_PER_SEC);
- }
- }
- }
-}
-
-TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketNum = 0;
- int64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
-
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/,
- bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
- false, false, {anomalyTracker});
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
- tracker.noteStop(kEventKey1, eventStartTimeNs + 10, false);
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
- EXPECT_TRUE(tracker.mStarted.empty());
- EXPECT_EQ(10LL, tracker.mStateKeyDurationMap[DEFAULT_DIMENSION_KEY].mDuration); // 10ns
-
- ASSERT_EQ(0u, tracker.mStarted.size());
-
- tracker.noteStart(kEventKey1, true, eventStartTimeNs + 20, ConditionKey());
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- EXPECT_EQ((long long)(52ULL * NS_PER_SEC), // (10s + 1s + 1ns + 20ns) - 10ns + 40s, rounded up
- (long long)(anomalyTracker->mAlarms.begin()->second->timestampSec * NS_PER_SEC));
- // The alarm is set to fire at 52s, and when it does, an anomaly would be declared. However,
- // because this is a unit test, the alarm won't actually fire at all. Since the alarm fails
- // to fire in time, the anomaly is instead caught when noteStop is called, at around 71s.
- tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 25, &buckets);
- tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 25, false);
- EXPECT_EQ(anomalyTracker->getSumOverPastBuckets(eventKey), (long long)(bucketSizeNs));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey),
- std::ceil((eventStartTimeNs + 2 * bucketSizeNs + 25.0) / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) {
- const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
- const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
- const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(1);
- alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 45;
- alert.set_refractory_period_secs(refPeriodSec);
-
- unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- ConditionKey conkey;
- conkey[StringToId("APP_BACKGROUND")] = kConditionKey1;
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs = 30 * NS_PER_SEC;
-
- sp<AlarmMonitor> alarmMonitor;
- sp<DurationAnomalyTracker> anomalyTracker =
- new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
- OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/,
- bucketStartTimeNs, 0, bucketStartTimeNs, bucketSizeNs, false,
- false, {anomalyTracker});
-
- tracker.noteStart(kEventKey1, true, 15 * NS_PER_SEC, conkey); // start key1
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(55ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStop(kEventKey1, 17 * NS_PER_SEC, false); // stop key1 (2 seconds later)
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStart(kEventKey1, true, 22 * NS_PER_SEC, conkey); // start key1 again
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStart(kEventKey2, true, 32 * NS_PER_SEC, conkey); // start key2
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- tracker.noteStop(kEventKey1, 47 * NS_PER_SEC, false); // stop key1
- ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
- alarm = anomalyTracker->mAlarms.begin()->second;
- EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
- // Now, at 60s, which is 38s after key1 started again, we have reached 40s of 'on' time.
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
- anomalyTracker->informAlarmsFired(62 * NS_PER_SEC, firedAlarms);
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
-
- tracker.noteStop(kEventKey2, 69 * NS_PER_SEC, false); // stop key2
- ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
deleted file mode 100644
index 98892507e78d..000000000000
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ /dev/null
@@ -1,5104 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/metrics/ValueMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/matchers/SimpleLogMatchingTracker.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::make_shared;
-using std::set;
-using std::shared_ptr;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const int tagId = 1;
-const int64_t metricId = 123;
-const int64_t atomMatcherId = 678;
-const int logEventMatcherIndex = 0;
-const int64_t bucketStartTimeNs = 10000000000;
-const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
-const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
-double epsilon = 0.001;
-
-static void assertPastBucketValuesSingleKey(
- const std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>>& mPastBuckets,
- const std::initializer_list<int>& expectedValuesList,
- const std::initializer_list<int64_t>& expectedDurationNsList,
- const std::initializer_list<int64_t>& expectedStartTimeNsList,
- const std::initializer_list<int64_t>& expectedEndTimeNsList) {
- vector<int> expectedValues(expectedValuesList);
- vector<int64_t> expectedDurationNs(expectedDurationNsList);
- vector<int64_t> expectedStartTimeNs(expectedStartTimeNsList);
- vector<int64_t> expectedEndTimeNs(expectedEndTimeNsList);
-
- ASSERT_EQ(expectedValues.size(), expectedDurationNs.size());
- ASSERT_EQ(expectedValues.size(), expectedStartTimeNs.size());
- ASSERT_EQ(expectedValues.size(), expectedEndTimeNs.size());
-
- if (expectedValues.size() == 0) {
- ASSERT_EQ(0, mPastBuckets.size());
- return;
- }
-
- ASSERT_EQ(1, mPastBuckets.size());
- ASSERT_EQ(expectedValues.size(), mPastBuckets.begin()->second.size());
-
- const vector<ValueBucket>& buckets = mPastBuckets.begin()->second;
- for (int i = 0; i < expectedValues.size(); i++) {
- EXPECT_EQ(expectedValues[i], buckets[i].values[0].long_value)
- << "Values differ at index " << i;
- EXPECT_EQ(expectedDurationNs[i], buckets[i].mConditionTrueNs)
- << "Condition duration value differ at index " << i;
- EXPECT_EQ(expectedStartTimeNs[i], buckets[i].mBucketStartNs)
- << "Start time differs at index " << i;
- EXPECT_EQ(expectedEndTimeNs[i], buckets[i].mBucketEndNs)
- << "End time differs at index " << i;
- }
-}
-
-} // anonymous namespace
-
-class ValueMetricProducerTestHelper {
-public:
- static sp<ValueMetricProducer> createValueProducerNoConditions(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer =
- new ValueMetricProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer->prepareFirstBucket();
- return valueProducer;
- }
-
- static sp<ValueMetricProducer> createValueProducerWithCondition(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
- ConditionState conditionAfterFirstBucketPrepared) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, 0 /*condition index*/, {ConditionState::kUnknown}, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer->prepareFirstBucket();
- valueProducer->mCondition = conditionAfterFirstBucketPrepared;
- return valueProducer;
- }
-
- static sp<ValueMetricProducer> createValueProducerWithState(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
- vector<int32_t> slicedStateAtoms,
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, -1 /* no condition */, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
- {}, slicedStateAtoms, stateGroupMap);
- valueProducer->prepareFirstBucket();
- return valueProducer;
- }
-
- static sp<ValueMetricProducer> createValueProducerWithConditionAndState(
- sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
- vector<int32_t> slicedStateAtoms,
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
- ConditionState conditionAfterFirstBucketPrepared) {
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
- .WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
- .WillRepeatedly(Return());
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, 0 /* condition tracker index */, {ConditionState::kUnknown},
- wizard, logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager, {}, {}, slicedStateAtoms, stateGroupMap);
- valueProducer->prepareFirstBucket();
- valueProducer->mCondition = conditionAfterFirstBucketPrepared;
- return valueProducer;
- }
-
- static ValueMetric createMetric() {
- ValueMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_value_field()->set_field(tagId);
- metric.mutable_value_field()->add_child()->set_field(2);
- metric.set_max_pull_delay_sec(INT_MAX);
- return metric;
- }
-
- static ValueMetric createMetricWithCondition() {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_condition(StringToId("SCREEN_ON"));
- return metric;
- }
-
- static ValueMetric createMetricWithState(string state) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.add_slice_by_state(StringToId(state));
- return metric;
- }
-
- static ValueMetric createMetricWithConditionAndState(string state) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_condition(StringToId("SCREEN_ON"));
- metric.add_slice_by_state(StringToId(state));
- return metric;
- }
-};
-
-// Setup for parameterized tests.
-class ValueMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(ValueMetricProducerTest_PartialBucket,
- ValueMetricProducerTest_PartialBucket,
- testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- int64_t startTimeBase = 11;
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- // statsd started long ago.
- // The metric starts in the middle of the bucket
- ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, -1,
- startTimeBase, 22, pullerManager);
- valueProducer.prepareFirstBucket();
-
- EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
- EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
- EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
- valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
- EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
- valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
-}
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(ValueMetricProducerTest, TestFirstBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- // statsd started long ago.
- // The metric starts in the middle of the bucket
- ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard, -1, 5,
- 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
- valueProducer.prepareFirstBucket();
-
- EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
- EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
-}
-
-/*
- * Tests pulled atoms with no conditions
- */
-TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(8, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(23, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(12, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(13, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
- EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Initialize bucket.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
- return true;
- }))
- // Partial bucket.
- .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
- const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs + 8, 5));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- // First bucket ends.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 2));
- valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
-
- // Partial buckets created in 2nd bucket.
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, valueProducer->getCurrentBucketNum());
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1, 3},
- {bucketSizeNs, partialBucketSplitTimeNs - bucket2StartTimeNs},
- {bucketStartTimeNs, bucket2StartTimeNs},
- {bucket2StartTimeNs, partialBucketSplitTimeNs});
-}
-
-/*
- * Tests pulled atoms with filtering
- */
-TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- auto keyValue = atomMatcher.add_field_value_matcher();
- keyValue->set_field(1);
- keyValue->set_eq_int(3);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
- kConfigKey, metric, -1 /*-1 meaning no condition*/, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer->prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 3, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(8, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket3StartTimeNs + 1, 4, 23));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // No new data seen, so data has been cleared.
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(8, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 3, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- // the base was reset
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-}
-
-/*
- * Tests pulled atoms with no conditions and take absolute value after reset
- */
-TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_use_absolute_value_on_reset(true);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Return(true));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(10, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(26, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-}
-
-/*
- * Tests pulled atoms with no conditions and take zero value after reset
- */
-TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Return(false));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(26, curInterval.value.long_value);
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-}
-
-/*
- * Test pulled event with non sliced condition.
- */
-TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // First condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1); // Second condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 130));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 1); // Third condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 180));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // startUpdated:false sum:0 start:100
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(110, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(10, curInterval.value.long_value);
-
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(20, curInterval.value.long_value);
- EXPECT_EQ(false, curBaseInfo.hasBase);
-
- valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1},
- {bucketStartTimeNs, bucket2StartTimeNs},
- {bucket2StartTimeNs, bucket3StartTimeNs});
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 150;
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer.getCurrentBucketNum());
-
- // Event arrives after the bucket split.
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 20);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer.getCurrentBucketNum());
-
- // Next value should create a new bucket.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 5 * NS_PER_SEC, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10, 20},
- {partialBucketSplitTimeNs - bucketStartTimeNs,
- bucket2StartTimeNs - partialBucketSplitTimeNs},
- {bucketStartTimeNs, partialBucketSplitTimeNs},
- {partialBucketSplitTimeNs, bucket2StartTimeNs});
- EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, valueProducer.getCurrentBucketNum());
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValue) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150;
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Return(true))
- .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
- const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
-
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(1, valueProducer.getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150}, {bucket2StartTimeNs},
- {partialBucketSplitTimeNs});
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 150));
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(2, valueProducer.getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30}, {150, bucketSizeNs - 150},
- {bucket2StartTimeNs, partialBucketSplitTimeNs},
- {partialBucketSplitTimeNs, bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_split_bucket_for_app_upgrade(false);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Return(true));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
-
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
- valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150);
- ASSERT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to true time.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs,
- bucket2StartTimeNs - 100); // Condition change to false time.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 120));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-
- valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
- EXPECT_FALSE(valueProducer->mCondition);
-
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs - 50;
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- // Expect one full buckets already done and starting a partial bucket.
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer->getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20},
- {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- EXPECT_FALSE(valueProducer->mCondition);
-}
-
-TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(30, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
- logEventMatcherIndex, eventMatcherWizard, -1,
- bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
- valueProducer.mCondition = ConditionState::kFalse;
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has 1 slice
- ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-
- valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(20, curInterval.value.long_value);
-
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId, bucketStartTimeNs + 30, 30);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(50, curInterval.value.long_value);
-
- valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event4, tagId, bucketStartTimeNs + 40, 40);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(50, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20}, {bucketStartTimeNs},
- {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestAnomalyDetection) {
- sp<AlarmMonitor> alarmMonitor;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(130);
- alert.set_num_buckets(2);
- const int32_t refPeriodSec = 3;
- alert.set_refractory_period_secs(refPeriodSec);
-
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
- wizard, logEventMatcherIndex, eventMatcherWizard,
- -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 1 * NS_PER_SEC, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 2 + NS_PER_SEC, 20);
-
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId,
- bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, 130);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event4, tagId,
- bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC, 1);
-
- LogEvent event5(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event5, tagId,
- bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, 150);
-
- LogEvent event6(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event6, tagId,
- bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC, 160);
-
- // Two events in bucket #0.
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
- // Value sum == 30 <= 130.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // One event in bucket #2. No alarm as bucket #0 is trashed out.
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- // Value sum == 130 <= 130.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
- // Three events in bucket #3.
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- // Anomaly at event 4 since Value sum == 131 > 130!
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
- // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
- // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
- std::ceil(1.0 * event6.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(ValueMetricProducerTest, TestAnomalyDetectionMultipleBucketsSkipped) {
- sp<AlarmMonitor> alarmMonitor;
- Alert alert;
- alert.set_id(101);
- alert.set_metric_id(metricId);
- alert.set_trigger_if_sum_gt(100);
- alert.set_num_buckets(1);
- const int32_t refPeriodSec = 3;
- alert.set_refractory_period_secs(refPeriodSec);
-
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to true time.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 0));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs,
- bucket3StartTimeNs + 100); // Condition changed to false time.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 100, 120));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
- sp<AnomalyTracker> anomalyTracker = valueProducer->addAnomalyTracker(alert, alarmMonitor);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-
- // multiple buckets should be skipped here.
- valueProducer->onConditionChanged(false, bucket3StartTimeNs + 100);
-
- // No alert is fired when multiple buckets are skipped.
- EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-}
-
-// Test value metric no condition, the pull on bucket boundary come in time and too late
-TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Return(true));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- // pull 1
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-
- // startUpdated:true sum:0 start:11
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(11, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- // pull 2 at correct time
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // tartUpdated:false sum:12
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(23, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs},
- {bucket2StartTimeNs}, {bucket3StartTimeNs});
-
- // pull 3 come late.
- // The previous bucket gets closed with error. (Has start value 23, no ending)
- // Another bucket gets closed with error. (No start, but ending with 36)
- // The new bucket is back to normal.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket6StartTimeNs + 1, 36));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // startUpdated:false sum:12
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(36, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs},
- {bucket2StartTimeNs}, {bucket3StartTimeNs});
- // The 1st bucket is dropped because of no data
- // The 3rd bucket is dropped due to multiple buckets being skipped.
- ASSERT_EQ(2, valueProducer->mSkippedBuckets.size());
-
- EXPECT_EQ(bucketStartTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs);
- EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs);
- ASSERT_EQ(1, valueProducer->mSkippedBuckets[0].dropEvents.size());
- EXPECT_EQ(NO_DATA, valueProducer->mSkippedBuckets[0].dropEvents[0].reason);
- EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].dropEvents[0].dropTimeNs);
-
- EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[1].bucketStartTimeNs);
- EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[1].bucketEndTimeNs);
- ASSERT_EQ(1, valueProducer->mSkippedBuckets[1].dropEvents.size());
- EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[1].dropEvents[0].reason);
- EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[1].dropEvents[0].dropTimeNs);
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
- * was delivered late.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // First condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1); // Second condition change.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- // pull on bucket boundary come late, condition change happens before it
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- EXPECT_EQ(false, curBaseInfo.hasBase);
-
- // Now the alarm is delivered.
- // since the condition turned to off before this pull finish, it has no effect
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
- * change to false, and then true again. This is due to alarm delivered late.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
- return true;
- }))
- // condition becomes true again
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 25);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 25, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // startUpdated:false sum:0 start:100
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- // pull on bucket boundary come late, condition change happens before it
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-
- // condition changed to true again, before the pull alarm is delivered
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(130, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- // Now the alarm is delivered, but it is considered late, the data will be used
- // for the new bucket since it was just pulled.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 50, 140));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 50);
-
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(140, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(10, curInterval.value.long_value);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 160));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- assertPastBucketValuesSingleKey(
- valueProducer->mPastBuckets, {20, 30}, {bucketSizeNs - 8, bucketSizeNs - 24},
- {bucketStartTimeNs, bucket2StartTimeNs}, {bucket2StartTimeNs, bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::MIN);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::MAX);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(20, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::AVG);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval;
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(1, curInterval.sampleSize);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(25, curInterval.value.long_value);
- EXPECT_EQ(2, curInterval.sampleSize);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-
- EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
- 12.5) < epsilon);
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::SUM);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(25, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_aggregation_type(ValueMetric::MIN);
- metric.set_use_diff(true);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(5, curInterval.value.long_value);
-
- // no change in data.
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(0, curInterval.value.long_value);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 15);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(0, curInterval.value.long_value);
-
- valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
- assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_value_field()->add_child()->set_field(3);
- metric.set_aggregation_type(ValueMetric::MIN);
- metric.set_use_diff(true);
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
- valueProducer.prepareFirstBucket();
-
- LogEvent event1(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10, 20);
-
- LogEvent event2(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 1, 15, 22);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer.mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(10, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(20, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(5, curInterval.value.long_value);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(2, curInterval.value.long_value);
-
- // no change in first value field
- LogEvent event3(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15, 25);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(25, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- LogEvent event4(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15, 29);
-
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
- ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(15, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
- curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(29, curBaseInfo.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
-
- valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
- ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
- ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
-
- EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
- EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
- EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].valueIndex[0]);
- EXPECT_EQ(2, valueProducer.mPastBuckets.begin()->second[0].values[1].long_value);
- EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].valueIndex[1]);
-
- EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[1].mConditionTrueNs);
- EXPECT_EQ(3, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
- EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[1].valueIndex[0]);
-}
-
-/*
- * Tests zero default base.
- */
-TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_use_zero_default_base(true);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto iter = valueProducer->mCurrentSlicedBucket.begin();
- auto& interval1 = iter->second[0];
- auto iterBase = valueProducer->mCurrentBaseInfo.begin();
- auto& baseInfo1 = iterBase->second[0];
- EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(3, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- vector<shared_ptr<LogEvent>> allData;
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(11, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
-
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
- if (it != iter) {
- break;
- }
- }
- auto itBase = valueProducer->mCurrentBaseInfo.begin();
- for (; itBase != valueProducer->mCurrentBaseInfo.end(); it++) {
- if (itBase != iterBase) {
- break;
- }
- }
- EXPECT_TRUE(it != iter);
- EXPECT_TRUE(itBase != iterBase);
- auto& interval2 = it->second[0];
- auto& baseInfo2 = itBase->second[0];
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(4, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(4, interval2.value.long_value);
-
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
- auto iterator = valueProducer->mPastBuckets.begin();
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
- EXPECT_EQ(8, iterator->second[0].values[0].long_value);
- iterator++;
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
- EXPECT_EQ(4, iterator->second[0].values[0].long_value);
-}
-
-/*
- * Tests using zero default base with failed pull.
- */
-TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_use_zero_default_base(true);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- const auto& it = valueProducer->mCurrentSlicedBucket.begin();
- ValueMetricProducer::Interval& interval1 = it->second[0];
- ValueMetricProducer::BaseInfo& baseInfo1 =
- valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())->second[0];
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(3, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- vector<shared_ptr<LogEvent>> allData;
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(11, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
-
- auto it2 = valueProducer->mCurrentSlicedBucket.begin();
- for (; it2 != valueProducer->mCurrentSlicedBucket.end(); it2++) {
- if (it2 != it) {
- break;
- }
- }
- EXPECT_TRUE(it2 != it);
- ValueMetricProducer::Interval& interval2 = it2->second[0];
- ValueMetricProducer::BaseInfo& baseInfo2 =
- valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())->second[0];
- EXPECT_EQ(2, it2->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(4, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(4, interval2.value.long_value);
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-
- // next pull somehow did not happen, skip to end of bucket 3
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(5, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 13));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 1, 5));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
-
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Get new references now that entries have been deleted from the map
- const auto& it3 = valueProducer->mCurrentSlicedBucket.begin();
- const auto& it4 = std::next(valueProducer->mCurrentSlicedBucket.begin());
- ASSERT_EQ(it3->second.size(), 1);
- ASSERT_EQ(it4->second.size(), 1);
- ValueMetricProducer::Interval& interval3 = it3->second[0];
- ValueMetricProducer::Interval& interval4 = it4->second[0];
- ValueMetricProducer::BaseInfo& baseInfo3 =
- valueProducer->mCurrentBaseInfo.find(it3->first.getDimensionKeyInWhat())->second[0];
- ValueMetricProducer::BaseInfo& baseInfo4 =
- valueProducer->mCurrentBaseInfo.find(it4->first.getDimensionKeyInWhat())->second[0];
-
- EXPECT_EQ(true, baseInfo3.hasBase);
- EXPECT_EQ(5, baseInfo3.base.long_value);
- EXPECT_EQ(false, interval3.hasValue);
- EXPECT_EQ(5, interval3.value.long_value);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- EXPECT_EQ(true, baseInfo4.hasBase);
- EXPECT_EQ(13, baseInfo4.base.long_value);
- EXPECT_EQ(false, interval4.hasValue);
- EXPECT_EQ(8, interval4.value.long_value);
-
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-}
-
-/*
- * Tests trim unused dimension key if no new data is seen in an entire bucket.
- */
-TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto iter = valueProducer->mCurrentSlicedBucket.begin();
- auto& interval1 = iter->second[0];
- auto iterBase = valueProducer->mCurrentBaseInfo.begin();
- auto& baseInfo1 = iterBase->second[0];
- EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(3, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(true, baseInfo1.hasBase);
- EXPECT_EQ(11, baseInfo1.base.long_value);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
- EXPECT_FALSE(interval1.seenNewData);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
- if (it != iter) {
- break;
- }
- }
- auto itBase = valueProducer->mCurrentBaseInfo.begin();
- for (; itBase != valueProducer->mCurrentBaseInfo.end(); it++) {
- if (itBase != iterBase) {
- break;
- }
- }
- EXPECT_TRUE(it != iter);
- EXPECT_TRUE(itBase != iterBase);
- auto interval2 = it->second[0];
- auto baseInfo2 = itBase->second[0];
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(4, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_FALSE(interval2.seenNewData);
-
- // next pull somehow did not happen, skip to end of bucket 3
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
- // Only one interval left. One was trimmed.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(5, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_FALSE(interval2.seenNewData);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 14));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
-
- interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, baseInfo2.hasBase);
- EXPECT_EQ(14, baseInfo2.base.long_value);
- EXPECT_EQ(false, interval2.hasValue);
- EXPECT_FALSE(interval2.seenNewData);
- ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
- auto iterator = valueProducer->mPastBuckets.begin();
- EXPECT_EQ(bucket4StartTimeNs, iterator->second[0].mBucketStartNs);
- EXPECT_EQ(bucket5StartTimeNs, iterator->second[0].mBucketEndNs);
- EXPECT_EQ(9, iterator->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
- iterator++;
- EXPECT_EQ(bucketStartTimeNs, iterator->second[0].mBucketStartNs);
- EXPECT_EQ(bucket2StartTimeNs, iterator->second[0].mBucketEndNs);
- EXPECT_EQ(8, iterator->second[0].values[0].long_value);
- EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- // Used by onConditionChanged.
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- vector<shared_ptr<LogEvent>> allData;
- valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8); // Condition change to true.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }))
- .WillOnce(Return(false));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 20);
-
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 50));
- return false;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1); // Condition change to false.
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Don't directly set mCondition; the real code never does that. Go through regular code path
- // to avoid unexpected behaviors.
- // valueProducer->mCondition = ConditionState::kTrue;
- valueProducer->onConditionChanged(true, bucketStartTimeNs);
-
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 1);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_condition(StringToId("SCREEN_ON"));
- metric.set_max_pull_delay_sec(0);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 120));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Max delay is set to 0 so pull will exceed max delay.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
- logEventMatcherIndex, eventMatcherWizard, tagId,
- bucket2StartTimeNs, bucket2StartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
- valueProducer.mCondition = ConditionState::kFalse;
-
- // Event should be skipped since it is from previous bucket.
- // Pull should not be called.
- valueProducer.onConditionChanged(true, bucketStartTimeNs);
- ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
- valueProducer->mHasGlobalBase = false;
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
- valueProducer->mHasGlobalBase = true;
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(100, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-}
-
-/*
- * Tests that a bucket is marked invalid when a condition change pull fails.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First onConditionChanged
- .WillOnce(Return(false))
- // Second onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kTrue);
-
- // Bucket start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-
- // This will fail and should invalidate the whole bucket since we do not have all the data
- // needed to compute the metric value when the screen was on.
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
- // Bucket end.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- // Contains base from last pull which was successful.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(140, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10, false /* include partial bucket */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the guardrail is hit.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 2, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- for (int i = 0; i < 2000; i++) {
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
- }
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
- EXPECT_EQ(true, valueProducer->mCurrentBucketIsSkipped);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(0UL, valueProducer->mSkippedBuckets.size());
-
- // Bucket 2 start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // First bucket added to mSkippedBuckets after flush.
- ASSERT_EQ(1UL, valueProducer->mSkippedBuckets.size());
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
- true, FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::DIMENSION_GUARDRAIL_REACHED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the bucket's initial pull fails.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
- return true;
- }))
- // Second onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kTrue);
-
- // Bucket start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs);
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
- // Bucket end.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- // Contains base from last pull which was successful.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(140, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
- true, FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the bucket's final pull fails
- * (i.e. failed pull on bucket boundary).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
- return true;
- }))
- // Second onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kTrue);
-
- // Bucket start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
- // Bucket end.
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-
- valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
- ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
- // Last pull failed so base has been reset.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
- true, FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- // Start bucket.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- // Bucket 2 start.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-
- // Bucket 3 empty.
- allData.clear();
- allData.push_back(CreateNoValuesLogEvent(tagId, bucket3StartTimeNs + 1));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
- // Data has been trimmed.
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // Empty pull.
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 11);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 12);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval& curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- // End of bucket
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- // Data is empty, base should be reset.
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(5, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
- ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _))
- // First onConditionChanged
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-
- // End of bucket
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 2));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Key 1 should be reset since in not present in the most pull.
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- auto iterator = valueProducer->mCurrentSlicedBucket.begin();
- auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin();
- EXPECT_EQ(true, baseInfoIter->second[0].hasBase);
- EXPECT_EQ(2, baseInfoIter->second[0].base.long_value);
- EXPECT_EQ(false, iterator->second[0].hasValue);
- iterator++;
- baseInfoIter++;
- EXPECT_EQ(false, baseInfoIter->second[0].hasBase);
- EXPECT_EQ(1, baseInfoIter->second[0].base.long_value);
- EXPECT_EQ(false, iterator->second[0].hasValue);
-
- EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- int64_t partialBucketSplitTimeNs = bucketStartTimeNs + bucketSizeNs / 2;
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Initialization.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // notifyAppUpgrade.
- .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
- const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
- ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
- EXPECT_EQ(0, valueProducer->getCurrentBucketNum());
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size());
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 4));
- // Pull fails and arrives late.
- valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1);
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9},
- {partialBucketSplitTimeNs - bucketStartTimeNs},
- {bucketStartTimeNs}, {partialBucketSplitTimeNs});
- ASSERT_EQ(1, valueProducer->mSkippedBuckets.size());
- ASSERT_EQ(2, valueProducer->mSkippedBuckets[0].dropEvents.size());
- EXPECT_EQ(PULL_FAILED, valueProducer->mSkippedBuckets[0].dropEvents[0].reason);
- EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[0].dropEvents[1].reason);
- EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs);
- EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs);
- ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Second onConditionChanged.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
- return true;
- }))
- // Third onConditionChanged.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- valueProducer->onConditionChanged(false, bucketStartTimeNs);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- // End of first bucket
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 4));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
- ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curBaseInfo.hasBase);
- EXPECT_EQ(5, curBaseInfo.base.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
-
- valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10},
- {bucket2StartTimeNs}, {bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- // Initialization.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Initialization.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // notifyAppUpgrade.
- .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
- const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- switch (GetParam()) {
- case APP_UPGRADE:
- valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
- break;
- case BOOT_COMPLETE:
- valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
- break;
- }
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First on condition changed.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // Second on condition changed.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 12);
-
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(2, curInterval.value.long_value);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}, {bucketStartTimeNs},
- {bucket2StartTimeNs});
-}
-
-// TODO: b/145705635 fix or delete this test
-TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First condition change.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
- return true;
- }))
- // 2nd condition change.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
- return true;
- }))
- // 3rd condition change.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 3, 10));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
- valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8);
- valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // There was not global base available so all buckets are invalid.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- // Initial pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
- FAST, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- // Bucket is invalid since we did not pull when dump report was called.
- ASSERT_EQ(0, report.value_metrics().data_size());
-}
-
-TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
- // Initial pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, tagId, 2, 2));
- valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST,
- &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- // Previous bucket is part of the report.
- ASSERT_EQ(1, report.value_metrics().data_size());
- EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
-}
-
-TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
- UidMap uidMap;
- SimpleAtomMatcher atomMatcher;
- atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard =
- new EventMatcherWizard({new SimpleLogMatchingTracker(
- atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Initial pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
- return true;
- }))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(
- CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10, tagId, 3, 3));
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, logEventMatcherIndex,
- eventMatcherWizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.prepareFirstBucket();
-
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 10));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30);
-
- // Bucket should have been completed.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
- // has one slice
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(20, curInterval.value.long_value);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
- curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- return true;
- }));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8},
- {bucketStartTimeNs}, {bucket2StartTimeNs});
- ValueMetricProducer::Interval curInterval =
- valueProducer->mCurrentSlicedBucket.begin()->second[0];
- ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
- EXPECT_EQ(false, curBaseInfo.hasBase);
- EXPECT_EQ(false, curInterval.hasValue);
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // Condition was always false.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_use_diff(false);
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
- return true;
- }))
- .WillOnce(Return(false));
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
-
- // Now the alarm is delivered. Condition is off though.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // No buckets, we had a failure.
- assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-/*
- * Test that DUMP_REPORT_REQUESTED dump reason is logged.
- *
- * For the bucket to be marked invalid during a dump report requested,
- * three things must be true:
- * - we want to include the current partial bucket
- * - we need a pull (metric is pulled and condition is true)
- * - the dump latency must be FAST
- */
-
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 20, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition
- * change event (i.e. the condition change occurs in the wrong bucket).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 50, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Bucket boundary pull.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
- valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
- // Late condition change event.
- valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(1);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate
- * event (i.e. the accumulate events call occurs in the wrong bucket).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 100);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Bucket boundary pull.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
- valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 20));
-
- // Late accumulateEvents event.
- valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition
- * when a metric is initialized.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10000);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that PULL_FAILED dump reason is logged due to a pull failure in
- * #pullAndMatchEventsLocked.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
- return true;
- }))
- // Dump report requested, pull fails.
- .WillOnce(Return(false));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that MULTIPLE_BUCKETS_SKIPPED dump reason is logged when a log event
- * skips over more than one bucket.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket4StartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1000, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // Condition change event that skips forward by three buckets.
- valueProducer->onConditionChanged(false, bucket4StartTimeNs + 10);
-
- int64_t dumpTimeNs = bucket4StartTimeNs + 1000;
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(dumpTimeNs, true /* include current buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(2, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket4StartTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::MULTIPLE_BUCKETS_SKIPPED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket4StartTimeNs + 10), dropEvent.drop_time_millis());
-
- // This bucket is skipped because a dumpReport with include current buckets is called.
- // This creates a new bucket from bucket4StartTimeNs to dumpTimeNs in which we have no data
- // since the condition is false for the entire bucket interval.
- EXPECT_EQ(NanoToMillis(bucket4StartTimeNs),
- report.value_metrics().skipped(1).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpTimeNs),
- report.value_metrics().skipped(1).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
-
- dropEvent = report.value_metrics().skipped(1).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
- * is smaller than the "min_bucket_size_nanos" specified in the metric config.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
- metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 9000000);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 9000000, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 9000000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that NO_DATA dump reason is logged when a flushed bucket contains no data.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenDataUnavailable) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kFalse);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that all buckets are dropped due to condition unknown until the first onConditionChanged.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestConditionUnknownMultipleBuckets) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(
- tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 10));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 15 * NS_PER_SEC);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(
- tagId, bucket2StartTimeNs + 15 * NS_PER_SEC, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // Bucket should be dropped because of condition unknown.
- int64_t appUpgradeTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC;
- valueProducer->notifyAppUpgrade(appUpgradeTimeNs);
-
- // Bucket also dropped due to condition unknown
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 3));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- // This bucket is also dropped due to condition unknown.
- int64_t conditionChangeTimeNs = bucket2StartTimeNs + 10 * NS_PER_SEC;
- valueProducer->onConditionChanged(true, conditionChangeTimeNs);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucket2StartTimeNs + 15 * NS_PER_SEC; // 15 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(3, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(appUpgradeTimeNs), dropEvent.drop_time_millis());
-
- EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
- report.value_metrics().skipped(1).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(1).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
-
- dropEvent = report.value_metrics().skipped(1).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(2).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(2).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(2).drop_event_size());
-
- dropEvent = report.value_metrics().skipped(2).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(conditionChangeTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that a skipped bucket is logged when a forced bucket split occurs when the previous bucket
- * was not flushed in time.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenForceBucketSplitBeforeBucketFlush) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }))
- // App Update.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1000);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1000, 15));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
- ConditionState::kFalse);
-
- // Condition changed event
- int64_t conditionChangeTimeNs = bucketStartTimeNs + 10;
- valueProducer->onConditionChanged(true, conditionChangeTimeNs);
-
- // App update event.
- int64_t appUpdateTimeNs = bucket2StartTimeNs + 1000;
- valueProducer->notifyAppUpgrade(appUpdateTimeNs);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucket2StartTimeNs + 10000000000; // 10 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(1, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(0, data.bucket_info(0).bucket_num());
- EXPECT_EQ(5, data.bucket_info(0).values(0).value_long());
-
- EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test multiple bucket drop events in the same bucket.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _))
- // Condition change to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // Condition change event.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 1000;
- valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 10), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(1);
- EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that the number of logged bucket drop events is capped at the maximum.
- * The maximum is currently 10 and is set in MetricProducer::maxDropEventsReached().
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // First condition change event.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- for (int i = 0; i < 2000; i++) {
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
- }
- return true;
- }))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 220);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 220, 10));
- return true;
- }));
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
-
- // First condition change event causes guardrail to be reached.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
- // 2-10 condition change events result in failed pulls.
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 30);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 70);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 90);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 100);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 150);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 170);
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 190);
- valueProducer->onConditionChanged(false, bucketStartTimeNs + 200);
-
- // Condition change event 11
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 220);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 1000;
- // Because we already have 10 dump events in the current bucket,
- // this case should not be added to the list of dump events.
- valueProducer->onDumpReport(bucketStartTimeNs + 1000, true /* include recent buckets */, true,
- FAST /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(10, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 10), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(1);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 30), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(2);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 50), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(3);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 70), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(4);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 90), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(5);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 100), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(6);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 150), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(7);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 170), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(8);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 190), dropEvent.drop_time_millis());
-
- dropEvent = report.value_metrics().skipped(0).drop_event(9);
- EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 200), dropEvent.drop_time_millis());
-}
-
-/*
- * Test metric with a simple sliced state
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedState) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // ValueMetricProducer initialized.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }))
- // Screen state change to ON.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
- return true;
- }))
- // Screen state change to OFF.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 9));
- return true;
- }))
- // Screen state change to ON.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
- return true;
- }));
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithState(
- pullerManager, metric, {util::SCREEN_STATE_CHANGED}, {});
- EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(SCREEN_STATE_ATOM_ID, valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Bucket status after metric initialized.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after screen state change kStateUnknown->ON.
- auto screenEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 5, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change ON->OFF.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(9, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, ON}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change OFF->ON.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(21, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, OFF}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(12, it->second[0].value.long_value);
- // Value for dimension, state key {{}, ON}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucketStartTimeNs + 50, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(3, report.value_metrics().data_size());
-
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(1);
- ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
- EXPECT_EQ(13, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(2);
- ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
- EXPECT_EQ(12, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-}
-
-/*
- * Test metric with sliced state with map
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // ValueMetricProducer initialized.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
- return true;
- }))
- // Screen state change to ON.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
- return true;
- }))
- // Screen state change to VR has no pull because it is in the same
- // state group as ON.
-
- // Screen state change to ON has no pull because it is in the same
- // state group as VR.
-
- // Screen state change to OFF.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
- return true;
- }))
- // Dump report requested.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
- return true;
- }));
-
- const StateMap& stateMap =
- CreateScreenStateOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
- const StateMap_StateGroup screenOnGroup = stateMap.group(0);
- const StateMap_StateGroup screenOffGroup = stateMap.group(1);
-
- unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
- for (auto group : stateMap.group()) {
- for (auto value : group.value()) {
- stateGroupMap[SCREEN_STATE_ATOM_ID][value] = group.group_id();
- }
- }
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithState(
- pullerManager, metric, {util::SCREEN_STATE_CHANGED}, stateGroupMap);
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(SCREEN_STATE_ATOM_ID, valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
- // Bucket status after metric initialized.
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, {kStateUnknown}}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after screen state change kStateUnknown->ON.
- auto screenEvent = CreateScreenStateChangedEvent(
- bucketStartTimeNs + 5, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change ON->VR.
- // Both ON and VR are in the same state group, so the base should not change.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10,
- android::view::DisplayStateEnum::DISPLAY_STATE_VR);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change VR->ON.
- // Both ON and VR are in the same state group, so the base should not change.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 12,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, kStateUnknown}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Bucket status after screen state change VR->OFF.
- screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15,
- android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- StateManager::getInstance().onLogEvent(*screenEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(21, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(screenOffGroup.group_id(),
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{}, ON GROUP}
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(screenOnGroup.group_id(),
- it->first.getStateValuesKey().getValues()[0].mValue.long_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(16, it->second[0].value.long_value);
- // Value for dimension, state key {{}, kStateUnknown}
- it++;
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucketStartTimeNs + 50, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(3, report.value_metrics().data_size());
-
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(1);
- ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
- EXPECT_EQ(16, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOnGroup.group_id(), data.slice_by_state(0).group_id());
-
- data = report.value_metrics().data(2);
- ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
- EXPECT_EQ(9, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
- EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_group_id());
- EXPECT_EQ(screenOffGroup.group_id(), data.slice_by_state(0).group_id());
-}
-
-/*
- * Test metric that slices by state with a primary field and has dimensions
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
- metric.mutable_dimensions_in_what()->set_field(tagId);
- metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-
- MetricStateLink* stateLink = metric.add_state_link();
- stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
- auto fieldsInWhat = stateLink->mutable_fields_in_what();
- *fieldsInWhat = CreateDimensions(tagId, {1 /* uid */});
- auto fieldsInState = stateLink->mutable_fields_in_state();
- *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // ValueMetricProducer initialized.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
- data->clear();
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 2 /*uid*/, 7));
- data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1 /*uid*/, 3));
- return true;
- }))
- // Uid 1 process state change from kStateUnknown -> Foreground
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20, 1 /*uid*/, 6));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20, 2 /*uid*/, 8));
- return true;
- }))
- // Uid 2 process state change from kStateUnknown -> Background
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40, 2 /*uid*/, 9));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40, 1 /*uid*/, 12));
- return true;
- }))
- // Uid 1 process state change from Foreground -> Background
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 20);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20, 1 /*uid*/, 13));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20, 2 /*uid*/, 11));
- return true;
- }))
- // Uid 1 process state change from Background -> Foreground
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 40);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40, 1 /*uid*/, 17));
-
- // This event should be skipped.
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40, 2 /*uid */, 15));
- return true;
- }))
- // Dump report pull.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50);
- data->clear();
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50, 2 /*uid*/, 20));
- data->push_back(
- CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50, 1 /*uid*/, 21));
- return true;
- }));
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithState(
- pullerManager, metric, {UID_PROCESS_STATE_ATOM_ID}, {});
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(UID_PROCESS_STATE_ATOM_ID, valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
- // Bucket status after metric initialized.
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {uid 1}.
- auto it = valueProducer->mCurrentSlicedBucket.begin();
- auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{uid 1}, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
- // Base for dimension key {uid 2}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(7, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for dimension, state key {{uid 2}, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 1 process state change kStateUnknown -> Foreground.
- auto uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 20, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {uid 1}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(6, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
-
- // Base for dimension key {uid 2}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(7, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 2 process state change kStateUnknown -> Background.
- uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucketStartTimeNs + 40, 2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {uid 1}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(6, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
-
- // Base for dimension key {uid 2}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(9, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Pull at end of first bucket.
- vector<shared_ptr<LogEvent>> allData;
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs, 1 /*uid*/, 10));
- allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs, 2 /*uid*/, 15));
- valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
- // Buckets flushed after end of first bucket.
- // None of the buckets should have a value.
- ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
- // Base for dimension key {uid 2}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(15, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, BACKGROUND}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Base for dimension key {uid 1}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(10, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* kStateTracker::kUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Value for key {uid 1, FOREGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Value for key {uid 2, kStateUnknown}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* kStateTracker::kUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 1 process state change from Foreground -> Background.
- uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucket2StartTimeNs + 20, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
- ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
- ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
- // Base for dimension key {uid 2}.
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(15, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, BACKGROUND}.
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
- // Base for dimension key {uid 1}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(13, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
- // Value for key {uid 1, FOREGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
- // Value for key {uid 2, kStateUnknown}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after uid 1 process state change Background->Foreground.
- uidProcessEvent = CreateUidProcessStateChangedEvent(
- bucket2StartTimeNs + 40, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
- StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
- ASSERT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
- ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
- // Base for dimension key {uid 2}
- it = valueProducer->mCurrentSlicedBucket.begin();
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(15, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 2, BACKGROUND}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Base for dimension key {uid 1}
- it++;
- itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(17, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {uid 1, kStateUnknown}
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Value for key {uid 1, BACKGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
-
- // Value for key {uid 1, FOREGROUND}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(3, it->second[0].value.long_value);
-
- // Value for key {uid 2, kStateUnknown}
- it++;
- ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
- EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 50, true /* include recent buckets */, true,
- NO_TIME_CONSTRAINTS, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(5, report.value_metrics().data_size());
-
- auto data = report.value_metrics().data(0);
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(4, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
-
- data = report.value_metrics().data(1);
- ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
- EXPECT_EQ(2, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(2);
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, report.value_metrics().data(2).bucket_info_size());
- EXPECT_EQ(4, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
- EXPECT_EQ(7, report.value_metrics().data(2).bucket_info(1).values(0).value_long());
-
- data = report.value_metrics().data(3);
- ASSERT_EQ(1, report.value_metrics().data(3).bucket_info_size());
- EXPECT_EQ(3, report.value_metrics().data(3).bucket_info(0).values(0).value_long());
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-
- data = report.value_metrics().data(4);
- EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
- data.slice_by_state(0).value());
- ASSERT_EQ(2, report.value_metrics().data(4).bucket_info_size());
- EXPECT_EQ(6, report.value_metrics().data(4).bucket_info(0).values(0).value_long());
- EXPECT_EQ(5, report.value_metrics().data(4).bucket_info(1).values(0).value_long());
-}
-
-TEST(ValueMetricProducerTest, TestSlicedStateWithCondition) {
- // Set up ValueMetricProducer.
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithConditionAndState(
- "BATTERY_SAVER_MODE_STATE");
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
- // Condition changed to true.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC, 3));
- return true;
- }))
- // Battery saver mode state changed to OFF.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 30 * NS_PER_SEC);
- data->clear();
- data->push_back(
- CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30 * NS_PER_SEC, 5));
- return true;
- }))
- // Condition changed to false.
- .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
- data->clear();
- data->push_back(CreateRepeatedValueLogEvent(
- tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 15));
- return true;
- }));
-
- StateManager::getInstance().clear();
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithConditionAndState(
- pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {},
- ConditionState::kFalse);
- EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
- // Set up StateManager and check that StateTrackers are initialized.
- StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
- valueProducer);
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
- util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
- // Bucket status after battery saver mode ON event.
- // Condition is false so we do nothing.
- unique_ptr<LogEvent> batterySaverOnEvent =
- CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
- StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
- EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
- EXPECT_EQ(0UL, valueProducer->mCurrentBaseInfo.size());
-
- // Bucket status after condition change to true.
- valueProducer->onConditionChanged(true, bucketStartTimeNs + 20 * NS_PER_SEC);
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- std::unordered_map<HashableDimensionKey, std::vector<ValueMetricProducer::BaseInfo>>::iterator
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(3, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::ON,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {{}, -1}
- ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
- std::unordered_map<MetricDimensionKey, std::vector<ValueMetricProducer::Interval>>::iterator
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_FALSE(it->second[0].hasValue);
-
- // Bucket status after battery saver mode OFF event.
- unique_ptr<LogEvent> batterySaverOffEvent =
- CreateBatterySaverOffEvent(/*timestamp=*/bucketStartTimeNs + 30 * NS_PER_SEC);
- StateManager::getInstance().onLogEvent(*batterySaverOffEvent);
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(5, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {{}, ON}
- ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::ON,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(2, it->second[0].value.long_value);
-
- // Pull at end of first bucket.
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 11));
- valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
- EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
- EXPECT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_TRUE(itBase->second[0].hasBase);
- EXPECT_EQ(11, itBase->second[0].base.long_value);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
-
- // Bucket 2 status after condition change to false.
- valueProducer->onConditionChanged(false, bucket2StartTimeNs + 10 * NS_PER_SEC);
- // Base for dimension key {}
- ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
- itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
- EXPECT_FALSE(itBase->second[0].hasBase);
- EXPECT_TRUE(itBase->second[0].hasCurrentState);
- ASSERT_EQ(1, itBase->second[0].currentState.getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- itBase->second[0].currentState.getValues()[0].mValue.int_value);
- // Value for key {{}, OFF}
- ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
- it = valueProducer->mCurrentSlicedBucket.begin();
- EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
- ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF,
- it->first.getStateValuesKey().getValues()[0].mValue.int_value);
- EXPECT_TRUE(it->second[0].hasValue);
- EXPECT_EQ(4, it->second[0].value.long_value);
-
- // Start dump report and check output.
- ProtoOutputStream output;
- std::set<string> strSet;
- valueProducer->onDumpReport(bucket2StartTimeNs + 50 * NS_PER_SEC,
- true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
- &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(2, report.value_metrics().data_size());
-
- ValueMetricData data = report.value_metrics().data(0);
- EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(BatterySaverModeStateChanged::ON, data.slice_by_state(0).value());
- ASSERT_EQ(1, data.bucket_info_size());
- EXPECT_EQ(2, data.bucket_info(0).values(0).value_long());
-
- data = report.value_metrics().data(1);
- EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
- EXPECT_TRUE(data.slice_by_state(0).has_value());
- EXPECT_EQ(BatterySaverModeStateChanged::OFF, data.slice_by_state(0).value());
- ASSERT_EQ(2, data.bucket_info_size());
- EXPECT_EQ(6, data.bucket_info(0).values(0).value_long());
- EXPECT_EQ(4, data.bucket_info(1).values(0).value_long());
-}
-
-/*
- * Test bucket splits when condition is unknown.
- */
-TEST(ValueMetricProducerTest, TestForcedBucketSplitWhenConditionUnknownSkipsBucket) {
- ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
- sp<ValueMetricProducer> valueProducer =
- ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric,
- ConditionState::kUnknown);
-
- // App update event.
- int64_t appUpdateTimeNs = bucketStartTimeNs + 1000;
- valueProducer->notifyAppUpgrade(appUpdateTimeNs);
-
- // Check dump report.
- ProtoOutputStream output;
- std::set<string> strSet;
- int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
- valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
- NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
- StatsLogReport report = outputStreamToProto(&output);
- EXPECT_TRUE(report.has_value_metrics());
- ASSERT_EQ(0, report.value_metrics().data_size());
- ASSERT_EQ(1, report.value_metrics().skipped_size());
-
- EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
- report.value_metrics().skipped(0).start_bucket_elapsed_millis());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
- report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
- auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
- EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.cpp b/cmds/statsd/tests/metrics/metrics_test_helper.cpp
deleted file mode 100644
index 108df04b45cb..000000000000
--- a/cmds/statsd/tests/metrics/metrics_test_helper.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "metrics_test_helper.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-HashableDimensionKey getMockedDimensionKey(int tagId, int key, string value) {
- HashableDimensionKey dimension;
- int pos[] = {key, 0, 0};
- dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
-
- return dimension;
-}
-
-HashableDimensionKey getMockedDimensionKeyLongValue(int tagId, int key, int64_t value) {
- HashableDimensionKey dimension;
- int pos[] = {key, 0, 0};
- dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
-
- return dimension;
-}
-
-MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, string value) {
- return MetricDimensionKey(getMockedDimensionKey(tagId, key, value), DEFAULT_DIMENSION_KEY);
-}
-
-MetricDimensionKey getMockedStateDimensionKey(int tagId, int key, int64_t value) {
- return MetricDimensionKey(DEFAULT_DIMENSION_KEY,
- getMockedDimensionKeyLongValue(tagId, key, value));
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
- matcher->set_field(tagId);
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
- matcher->set_field(tagId);
- matcher->add_child()->set_field(fieldNum);
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
deleted file mode 100644
index 39232c194ada..000000000000
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#pragma once
-
-#include "src/condition/ConditionWizard.h"
-#include "src/external/StatsPullerManager.h"
-#include "src/packages/UidMap.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class MockConditionWizard : public ConditionWizard {
-public:
- MOCK_METHOD3(query,
- ConditionState(const int conditionIndex, const ConditionKey& conditionParameters,
- const bool isPartialLink));
-};
-
-class MockStatsPullerManager : public StatsPullerManager {
-public:
- MOCK_METHOD5(RegisterReceiver,
- void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver,
- int64_t nextPulltimeNs, int64_t intervalNs));
- MOCK_METHOD3(UnRegisterReceiver,
- void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver));
- MOCK_METHOD4(Pull, bool(const int pullCode, const ConfigKey& key, const int64_t eventTimeNs,
- vector<std::shared_ptr<LogEvent>>* data));
- MOCK_METHOD4(Pull, bool(const int pullCode, const vector<int32_t>& uids,
- const int64_t eventTimeNs, vector<std::shared_ptr<LogEvent>>* data));
- MOCK_METHOD2(RegisterPullUidProvider,
- void(const ConfigKey& configKey, wp<PullUidProvider> provider));
- MOCK_METHOD2(UnregisterPullUidProvider,
- void(const ConfigKey& configKey, wp<PullUidProvider> provider));
-};
-
-HashableDimensionKey getMockedDimensionKey(int tagId, int key, std::string value);
-MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, std::string value);
-
-HashableDimensionKey getMockedDimensionKeyLongValue(int tagId, int key, int64_t value);
-MetricDimensionKey getMockedStateDimensionKey(int tagId, int key, int64_t value);
-
-// Utils to build FieldMatcher proto for simple one-depth atoms.
-void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
deleted file mode 100644
index 4fa4135e983f..000000000000
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/shell/ShellSubscriber.h"
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h"
-#include "stats_event.h"
-#include "tests/metrics/metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android::os::statsd;
-using android::sp;
-using std::vector;
-using testing::_;
-using testing::Invoke;
-using testing::NaggyMock;
-using testing::StrictMock;
-
-#ifdef __ANDROID__
-
-void runShellTest(ShellSubscription config, sp<MockUidMap> uidMap,
- sp<MockStatsPullerManager> pullerManager,
- const vector<std::shared_ptr<LogEvent>>& pushedEvents,
- const ShellData& expectedData) {
- // set up 2 pipes for read/write config and data
- int fds_config[2];
- ASSERT_EQ(0, pipe(fds_config));
-
- int fds_data[2];
- ASSERT_EQ(0, pipe(fds_data));
-
- size_t bufferSize = config.ByteSize();
- // write the config to pipe, first write size of the config
- write(fds_config[1], &bufferSize, sizeof(bufferSize));
- // then write config itself
- vector<uint8_t> buffer(bufferSize);
- config.SerializeToArray(&buffer[0], bufferSize);
- write(fds_config[1], buffer.data(), bufferSize);
- close(fds_config[1]);
-
- sp<ShellSubscriber> shellClient = new ShellSubscriber(uidMap, pullerManager);
-
- // mimic a binder thread that a shell subscriber runs on. it would block.
- std::thread reader([&shellClient, &fds_config, &fds_data] {
- shellClient->startNewSubscription(fds_config[0], fds_data[1], /*timeoutSec=*/-1);
- });
- reader.detach();
-
- // let the shell subscriber to receive the config from pipe.
- std::this_thread::sleep_for(100ms);
-
- if (pushedEvents.size() > 0) {
- // send a log event that matches the config.
- std::thread log_reader([&shellClient, &pushedEvents] {
- for (const auto& event : pushedEvents) {
- shellClient->onLogEvent(*event);
- }
- });
-
- log_reader.detach();
-
- if (log_reader.joinable()) {
- log_reader.join();
- }
- }
-
- // wait for the data to be written.
- std::this_thread::sleep_for(100ms);
-
- // Because we might receive heartbeats from statsd, consisting of data sizes
- // of 0, encapsulate reads within a while loop.
- bool readAtom = false;
- while (!readAtom) {
- // Read the atom size.
- size_t dataSize = 0;
- read(fds_data[0], &dataSize, sizeof(dataSize));
- if (dataSize == 0) continue;
- EXPECT_EQ(expectedData.ByteSize(), int(dataSize));
-
- // Read that much data in proto binary format.
- vector<uint8_t> dataBuffer(dataSize);
- EXPECT_EQ((int)dataSize, read(fds_data[0], dataBuffer.data(), dataSize));
-
- // Make sure the received bytes can be parsed to an atom.
- ShellData receivedAtom;
- EXPECT_TRUE(receivedAtom.ParseFromArray(dataBuffer.data(), dataSize) != 0);
-
- // Serialize the expected atom to byte array and compare to make sure
- // they are the same.
- vector<uint8_t> expectedAtomBuffer(expectedData.ByteSize());
- expectedData.SerializeToArray(expectedAtomBuffer.data(), expectedData.ByteSize());
- EXPECT_EQ(expectedAtomBuffer, dataBuffer);
-
- readAtom = true;
- }
-
- close(fds_data[0]);
- if (reader.joinable()) {
- reader.join();
- }
-}
-
-TEST(ShellSubscriberTest, testPushedSubscription) {
- sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- vector<std::shared_ptr<LogEvent>> pushedList;
-
- // Create the LogEvent from an AStatsEvent
- std::unique_ptr<LogEvent> logEvent = CreateScreenStateChangedEvent(
- 1000 /*timestamp*/, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- pushedList.push_back(std::move(logEvent));
-
- // create a simple config to get screen events
- ShellSubscription config;
- config.add_pushed()->set_atom_id(29);
-
- // this is the expected screen event atom.
- ShellData shellData;
- shellData.add_atom()->mutable_screen_state_changed()->set_state(
- ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
- runShellTest(config, uidMap, pullerManager, pushedList, shellData);
-}
-
-namespace {
-
-int kUid1 = 1000;
-int kUid2 = 2000;
-
-int kCpuTime1 = 100;
-int kCpuTime2 = 200;
-
-ShellData getExpectedShellData() {
- ShellData shellData;
- auto* atom1 = shellData.add_atom()->mutable_cpu_active_time();
- atom1->set_uid(kUid1);
- atom1->set_time_millis(kCpuTime1);
-
- auto* atom2 = shellData.add_atom()->mutable_cpu_active_time();
- atom2->set_uid(kUid2);
- atom2->set_time_millis(kCpuTime2);
-
- return shellData;
-}
-
-ShellSubscription getPulledConfig() {
- ShellSubscription config;
- auto* pull_config = config.add_pulled();
- pull_config->mutable_matcher()->set_atom_id(10016);
- pull_config->set_freq_millis(2000);
- return config;
-}
-
-shared_ptr<LogEvent> makeCpuActiveTimeAtom(int32_t uid, int64_t timeMillis) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, 10016);
- AStatsEvent_overwriteTimestamp(statsEvent, 1111L);
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeInt64(statsEvent, timeMillis);
-
- std::shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-} // namespace
-
-TEST(ShellSubscriberTest, testPulledSubscription) {
- sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- const vector<int32_t> uids = {AID_SYSTEM};
- EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _))
- .WillRepeatedly(Invoke([](int tagId, const vector<int32_t>&, const int64_t,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid1, /*timeMillis=*/kCpuTime1));
- data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid2, /*timeMillis=*/kCpuTime2));
- return true;
- }));
- runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(),
- getExpectedShellData());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
deleted file mode 100644
index 6516c1529514..000000000000
--- a/cmds/statsd/tests/state/StateTracker_test.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "state/StateTracker.h"
-
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-
-#include "state/StateListener.h"
-#include "state/StateManager.h"
-#include "state/StateTracker.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int32_t timestampNs = 1000;
-
-/**
- * Mock StateListener class for testing.
- * Stores primary key and state pairs.
- */
-class TestStateListener : public virtual StateListener {
-public:
- TestStateListener(){};
-
- virtual ~TestStateListener(){};
-
- struct Update {
- Update(const HashableDimensionKey& key, int state) : mKey(key), mState(state){};
- HashableDimensionKey mKey;
- int mState;
- };
-
- std::vector<Update> updates;
-
- void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
- const HashableDimensionKey& primaryKey, const FieldValue& oldState,
- const FieldValue& newState) {
- updates.emplace_back(primaryKey, newState.mValue.int_value);
- }
-};
-
-int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& queryKey) {
- FieldValue output;
- mgr.getStateValue(atomId, queryKey, &output);
- return output.mValue.int_value;
-}
-
-// START: build event functions.
-// Incorrect event - missing fields
-std::unique_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName,
- int state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, 1000);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, packageName.c_str());
- // Missing field 3 - using_alert_window.
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-// Incorrect event - exclusive state has wrong type
-std::unique_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, 1000);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, packageName.c_str());
- AStatsEvent_writeInt32(statsEvent, true); // using_alert_window
- AStatsEvent_writeString(statsEvent, "string"); // exclusive state: string instead of int
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-// END: build event functions.
-
-TEST(StateListenerTest, TestStateListenerWeakPointer) {
- sp<TestStateListener> listener = new TestStateListener();
- wp<TestStateListener> wListener = listener;
- listener = nullptr; // let go of listener
- EXPECT_TRUE(wListener.promote() == nullptr);
-}
-
-TEST(StateManagerTest, TestStateManagerGetInstance) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager& mgr = StateManager::getInstance();
- mgr.clear();
-
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-}
-
-TEST(StateManagerTest, TestOnLogEvent) {
- sp<MockUidMap> uidMap = makeMockUidMapForPackage("com.android.systemui", {10111});
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.updateLogSources(uidMap);
- // Add StateTracker by registering a listener.
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-
- // log event using AID_ROOT
- std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- mgr.onLogEvent(*event);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
- // log event using mocked uid
- event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF, 10111);
- mgr.onLogEvent(*event);
-
- // check StateTracker was updated by querying for state
- queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
- // log event using non-whitelisted uid
- event = CreateScreenStateChangedEvent(timestampNs,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON, 10112);
- mgr.onLogEvent(*event);
-
- // check StateTracker was NOT updated by querying for state
- queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
- // log event using AID_SYSTEM
- event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, AID_SYSTEM);
- mgr.onLogEvent(*event);
-
- // check StateTracker was updated by querying for state
- queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test registering listeners to StateTrackers
- *
- * - StateManager will create a new StateTracker if it doesn't already exist
- * and then register the listener to the StateTracker.
- * - If a listener is already registered to a StateTracker, it is not added again.
- * - StateTrackers are only created for atoms that are state atoms.
- */
-TEST(StateTrackerTest, TestRegisterListener) {
- sp<TestStateListener> listener1 = new TestStateListener();
- sp<TestStateListener> listener2 = new TestStateListener();
- StateManager mgr;
-
- // Register listener to non-existing StateTracker
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Register listener to existing StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Register already registered listener to existing StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Register listener to non-state atom
- mgr.registerListener(util::BATTERY_LEVEL_CHANGED, listener2);
- EXPECT_EQ(2, mgr.getStateTrackersCount());
-}
-
-/**
- * Test unregistering listeners from StateTrackers
- *
- * - StateManager will unregister listeners from a StateTracker only if the
- * StateTracker exists and the listener is registered to the StateTracker.
- * - Once all listeners are removed from a StateTracker, the StateTracker
- * is also removed.
- */
-TEST(StateTrackerTest, TestUnregisterListener) {
- sp<TestStateListener> listener1 = new TestStateListener();
- sp<TestStateListener> listener2 = new TestStateListener();
- StateManager mgr;
-
- // Unregister listener from non-existing StateTracker
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Unregister non-registered listener from existing StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Unregister second-to-last listener from StateTracker
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
- // Unregister last listener from StateTracker
- mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
- EXPECT_EQ(0, mgr.getStateTrackersCount());
- EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-}
-
-/**
- * Test a binary state atom with nested counting.
- *
- * To go from an "ON" state to an "OFF" state with nested counting, we must see
- * an equal number of "OFF" events as "ON" events.
- * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
- * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
- */
-TEST(StateTrackerTest, TestStateChangeNested) {
- sp<TestStateListener> listener = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener);
-
- std::vector<int> attributionUids1 = {1000};
- std::vector<string> attributionTags1 = {"tag"};
-
- std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(timestampNs, attributionUids1,
- attributionTags1, "wakelockName");
- mgr.onLogEvent(*event1);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1, listener->updates[0].mState);
- listener->updates.clear();
-
- std::unique_ptr<LogEvent> event2 = CreateAcquireWakelockEvent(
- timestampNs + 1000, attributionUids1, attributionTags1, "wakelockName");
- mgr.onLogEvent(*event2);
- ASSERT_EQ(0, listener->updates.size());
-
- std::unique_ptr<LogEvent> event3 = CreateReleaseWakelockEvent(
- timestampNs + 2000, attributionUids1, attributionTags1, "wakelockName");
- mgr.onLogEvent(*event3);
- ASSERT_EQ(0, listener->updates.size());
-
- std::unique_ptr<LogEvent> event4 = CreateReleaseWakelockEvent(
- timestampNs + 3000, attributionUids1, attributionTags1, "wakelockName");
- mgr.onLogEvent(*event4);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(0, listener->updates[0].mState);
-}
-
-/**
- * Test a state atom with a reset state.
- *
- * If the reset state value is seen, every state in the map is set to the default
- * state and every listener is notified.
- */
-TEST(StateTrackerTest, TestStateChangeReset) {
- sp<TestStateListener> listener = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener);
-
- std::vector<int> attributionUids1 = {1000};
- std::vector<string> attributionTags1 = {"tag1"};
- std::vector<int> attributionUids2 = {2000};
-
- std::unique_ptr<LogEvent> event1 =
- CreateBleScanStateChangedEvent(timestampNs, attributionUids1, attributionTags1,
- BleScanStateChanged::ON, false, false, false);
- mgr.onLogEvent(*event1);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
- FieldValue stateFieldValue;
- mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
- EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value);
- listener->updates.clear();
-
- std::unique_ptr<LogEvent> event2 =
- CreateBleScanStateChangedEvent(timestampNs + 1000, attributionUids2, attributionTags1,
- BleScanStateChanged::ON, false, false, false);
- mgr.onLogEvent(*event2);
- ASSERT_EQ(1, listener->updates.size());
- EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
- mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
- EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value);
- listener->updates.clear();
-
- std::unique_ptr<LogEvent> event3 =
- CreateBleScanStateChangedEvent(timestampNs + 2000, attributionUids2, attributionTags1,
- BleScanStateChanged::RESET, false, false, false);
- mgr.onLogEvent(*event3);
- ASSERT_EQ(2, listener->updates.size());
- for (const TestStateListener::Update& update : listener->updates) {
- EXPECT_EQ(BleScanStateChanged::OFF, update.mState);
-
- mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, update.mKey, &stateFieldValue);
- EXPECT_EQ(BleScanStateChanged::OFF, stateFieldValue.mValue.int_value);
- }
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states without primary keys.
- */
-TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-
- // log event
- std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
- timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- mgr.onLogEvent(*event);
-
- // check listener was updated
- ASSERT_EQ(1, listener1->updates.size());
- EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
- EXPECT_EQ(2, listener1->updates[0].mState);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states with one primary key.
- */
-TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1);
-
- // log event
- std::unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent(
- timestampNs, 1000 /*uid*/, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
- mgr.onLogEvent(*event);
-
- // check listener was updated
- ASSERT_EQ(1, listener1->updates.size());
- EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1002, listener1->updates[0].mState);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey;
- getUidProcessKey(1000 /* uid */, &queryKey);
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
- getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey));
-}
-
-TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1);
-
- // Log event.
- std::vector<int> attributionUids = {1001};
- std::vector<string> attributionTags = {"tag1"};
-
- std::unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timestampNs, attributionUids,
- attributionTags, "wakelockName");
- mgr.onLogEvent(*event);
- EXPECT_EQ(1, mgr.getStateTrackersCount());
- EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
-
- // Check listener was updated.
- ASSERT_EQ(1, listener1->updates.size());
- ASSERT_EQ(3, listener1->updates[0].mKey.getValues().size());
- EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
- EXPECT_EQ("wakelockName", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
- EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
-
- // Check StateTracker was updated by querying for state.
- HashableDimensionKey queryKey;
- getPartialWakelockKey(1001 /* uid */, "wakelockName", &queryKey);
- EXPECT_EQ(WakelockStateChanged::ACQUIRE,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey));
-
- // No state stored for this query key.
- HashableDimensionKey queryKey2;
- getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2));
-
- // Partial query fails.
- HashableDimensionKey queryKey3;
- getPartialWakelockKey(1001 /* uid */, &queryKey3);
- EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states with multiple primary keys.
- */
-TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
-
- // log event
- std::unique_ptr<LogEvent> event = CreateOverlayStateChangedEvent(
- timestampNs, 1000 /* uid */, "package1", true /*using_alert_window*/,
- OverlayStateChanged::ENTERED);
- mgr.onLogEvent(*event);
-
- // check listener was updated
- ASSERT_EQ(1, listener1->updates.size());
- EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
- EXPECT_EQ(1, listener1->updates[0].mState);
-
- // check StateTracker was updated by querying for state
- HashableDimensionKey queryKey;
- getOverlayKey(1000 /* uid */, "package1", &queryKey);
- EXPECT_EQ(OverlayStateChanged::ENTERED,
- getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged
- * when there is an error extracting state from log event. Listener is not
- * updated of state change.
- */
-TEST(StateTrackerTest, TestStateChangeEventError) {
- sp<TestStateListener> listener1 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
-
- // log event
- std::shared_ptr<LogEvent> event1 =
- buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
- std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
-
- // check listener was updated
- mgr.onLogEvent(*event1);
- ASSERT_EQ(0, listener1->updates.size());
- mgr.onLogEvent(*event2);
- ASSERT_EQ(0, listener1->updates.size());
-}
-
-TEST(StateTrackerTest, TestStateQuery) {
- sp<TestStateListener> listener1 = new TestStateListener();
- sp<TestStateListener> listener2 = new TestStateListener();
- sp<TestStateListener> listener3 = new TestStateListener();
- sp<TestStateListener> listener4 = new TestStateListener();
- StateManager mgr;
- mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
- mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2);
- mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3);
- mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4);
-
- std::unique_ptr<LogEvent> event1 = CreateUidProcessStateChangedEvent(
- timestampNs, 1000 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
- std::unique_ptr<LogEvent> event2 = CreateUidProcessStateChangedEvent(
- timestampNs + 1000, 1001 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value:
- // 1003
- std::unique_ptr<LogEvent> event3 = CreateUidProcessStateChangedEvent(
- timestampNs + 2000, 1002 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000
- std::unique_ptr<LogEvent> event4 = CreateUidProcessStateChangedEvent(
- timestampNs + 3000, 1001 /*uid*/,
- android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
- std::unique_ptr<LogEvent> event5 = CreateScreenStateChangedEvent(
- timestampNs + 4000, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- std::unique_ptr<LogEvent> event6 = CreateOverlayStateChangedEvent(
- timestampNs + 5000, 1000 /*uid*/, "package1", true /*using_alert_window*/,
- OverlayStateChanged::ENTERED);
- std::unique_ptr<LogEvent> event7 = CreateOverlayStateChangedEvent(
- timestampNs + 6000, 1000 /*uid*/, "package2", true /*using_alert_window*/,
- OverlayStateChanged::EXITED);
-
- std::vector<int> attributionUids = {1005};
- std::vector<string> attributionTags = {"tag"};
-
- std::unique_ptr<LogEvent> event8 = CreateAcquireWakelockEvent(
- timestampNs + 7000, attributionUids, attributionTags, "wakelock1");
- std::unique_ptr<LogEvent> event9 = CreateReleaseWakelockEvent(
- timestampNs + 8000, attributionUids, attributionTags, "wakelock2");
-
- mgr.onLogEvent(*event1);
- mgr.onLogEvent(*event2);
- mgr.onLogEvent(*event3);
- mgr.onLogEvent(*event5);
- mgr.onLogEvent(*event5);
- mgr.onLogEvent(*event6);
- mgr.onLogEvent(*event7);
- mgr.onLogEvent(*event8);
- mgr.onLogEvent(*event9);
-
- // Query for UidProcessState of uid 1001
- HashableDimensionKey queryKey1;
- getUidProcessKey(1001, &queryKey1);
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
- getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
-
- // Query for UidProcessState of uid 1004 - not in state map
- HashableDimensionKey queryKey2;
- getUidProcessKey(1004, &queryKey2);
- EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED,
- queryKey2)); // default state
-
- // Query for UidProcessState of uid 1001 - after change in state
- mgr.onLogEvent(*event4);
- EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
- getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
-
- // Query for ScreenState
- EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
- getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
-
- // Query for OverlayState of uid 1000, package name "package2"
- HashableDimensionKey queryKey3;
- getOverlayKey(1000, "package2", &queryKey3);
- EXPECT_EQ(OverlayStateChanged::EXITED,
- getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3));
-
- // Query for WakelockState of uid 1005, tag 2
- HashableDimensionKey queryKey4;
- getPartialWakelockKey(1005, "wakelock2", &queryKey4);
- EXPECT_EQ(WakelockStateChanged::RELEASE,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4));
-
- // Query for WakelockState of uid 1005, tag 1
- HashableDimensionKey queryKey5;
- getPartialWakelockKey(1005, "wakelock1", &queryKey5);
- EXPECT_EQ(WakelockStateChanged::ACQUIRE,
- getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5));
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
deleted file mode 100644
index cee83725d075..000000000000
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ /dev/null
@@ -1,1393 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "statsd_test_util.h"
-
-#include <aidl/android/util/StatsEventParcel.h>
-#include "stats_event.h"
-
-using aidl::android::util::StatsEventParcel;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsLogReport outputStreamToProto(ProtoOutputStream* proto) {
- vector<uint8_t> bytes;
- bytes.resize(proto->size());
- size_t pos = 0;
- sp<ProtoReader> reader = proto->data();
-
- while (reader->readBuffer() != NULL) {
- size_t toRead = reader->currentToRead();
- std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
- pos += toRead;
- reader->move(toRead);
- }
-
- StatsLogReport report;
- report.ParseFromArray(bytes.data(), bytes.size());
- return report;
-}
-
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(atomId);
- return atom_matcher;
-}
-
-AtomMatcher CreateTemperatureAtomMatcher() {
- return CreateSimpleAtomMatcher("TemperatureMatcher", util::TEMPERATURE);
-}
-
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
- ScheduledJobStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SCHEDULED_JOB_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateStartScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
- ScheduledJobStateChanged::STARTED);
-}
-
-AtomMatcher CreateFinishScheduledJobAtomMatcher() {
- return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
- ScheduledJobStateChanged::FINISHED);
-}
-
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SCREEN_BRIGHTNESS_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId("UidProcessStateChanged"));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::UID_PROCESS_STATE_CHANGED);
- return atom_matcher;
-}
-
-AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
- WakelockStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::WAKELOCK_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateAcquireWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
-}
-
-AtomMatcher CreateReleaseWakelockAtomMatcher() {
- return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
-}
-
-AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
- const string& name, BatterySaverModeStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
- return CreateBatterySaverModeStateChangedAtomMatcher(
- "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
-}
-
-
-AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
- return CreateBatterySaverModeStateChangedAtomMatcher(
- "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
-}
-
-AtomMatcher CreateBatteryStateChangedAtomMatcher(const string& name,
- BatteryPluggedStateEnum state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::PLUGGED_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateBatteryStateNoneMatcher() {
- return CreateBatteryStateChangedAtomMatcher("BatteryPluggedNone",
- BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
-}
-
-AtomMatcher CreateBatteryStateUsbMatcher() {
- return CreateBatteryStateChangedAtomMatcher("BatteryPluggedUsb",
- BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-}
-
-AtomMatcher CreateScreenStateChangedAtomMatcher(
- const string& name, android::view::DisplayStateEnum state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SCREEN_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(1); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateScreenTurnedOnAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-AtomMatcher CreateScreenTurnedOffAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
- ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-}
-
-AtomMatcher CreateSyncStateChangedAtomMatcher(
- const string& name, SyncStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::SYNC_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // State field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateSyncStartAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
-}
-
-AtomMatcher CreateSyncEndAtomMatcher() {
- return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
-}
-
-AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
- const string& name, ActivityForegroundStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(4); // Activity field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateMoveToBackgroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "Background", ActivityForegroundStateChanged::BACKGROUND);
-}
-
-AtomMatcher CreateMoveToForegroundAtomMatcher() {
- return CreateActivityForegroundStateChangedAtomMatcher(
- "Foreground", ActivityForegroundStateChanged::FOREGROUND);
-}
-
-AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
- const string& name, ProcessLifeCycleStateChanged::State state) {
- AtomMatcher atom_matcher;
- atom_matcher.set_id(StringToId(name));
- auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
- simple_atom_matcher->set_atom_id(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
- field_value_matcher->set_field(3); // Process state field.
- field_value_matcher->set_eq_int(state);
- return atom_matcher;
-}
-
-AtomMatcher CreateProcessCrashAtomMatcher() {
- return CreateProcessLifeCycleStateChangedAtomMatcher(
- "Crashed", ProcessLifeCycleStateChanged::CRASHED);
-}
-
-Predicate CreateScheduledJobPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
- return predicate;
-}
-
-Predicate CreateBatterySaverModePredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("BatterySaverIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
- return predicate;
-}
-
-Predicate CreateDeviceUnpluggedPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("DeviceUnplugged"));
- predicate.mutable_simple_predicate()->set_start(StringToId("BatteryPluggedNone"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("BatteryPluggedUsb"));
- return predicate;
-}
-
-Predicate CreateScreenIsOnPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("ScreenIsOn"));
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
- return predicate;
-}
-
-Predicate CreateScreenIsOffPredicate() {
- Predicate predicate;
- predicate.set_id(1111123);
- predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
- return predicate;
-}
-
-Predicate CreateHoldingWakelockPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("HoldingWakelock"));
- predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
- return predicate;
-}
-
-Predicate CreateIsSyncingPredicate() {
- Predicate predicate;
- predicate.set_id(33333333333333);
- predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
- return predicate;
-}
-
-Predicate CreateIsInBackgroundPredicate() {
- Predicate predicate;
- predicate.set_id(StringToId("IsInBackground"));
- predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
- predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
- return predicate;
-}
-
-State CreateScreenState() {
- State state;
- state.set_id(StringToId("ScreenState"));
- state.set_atom_id(util::SCREEN_STATE_CHANGED);
- return state;
-}
-
-State CreateUidProcessState() {
- State state;
- state.set_id(StringToId("UidProcessState"));
- state.set_atom_id(util::UID_PROCESS_STATE_CHANGED);
- return state;
-}
-
-State CreateOverlayState() {
- State state;
- state.set_id(StringToId("OverlayState"));
- state.set_atom_id(util::OVERLAY_STATE_CHANGED);
- return state;
-}
-
-State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- State state;
- state.set_id(StringToId("ScreenStateOnOff"));
- state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
- auto map = CreateScreenStateOnOffMap(screenOnId, screenOffId);
- *state.mutable_map() = map;
-
- return state;
-}
-
-State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- State state;
- state.set_id(StringToId("ScreenStateSimpleOnOff"));
- state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
- auto map = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
- *state.mutable_map() = map;
-
- return state;
-}
-
-StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOnId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_VR);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND);
- return group;
-}
-
-StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOffId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND);
- return group;
-}
-
-StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOnId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- return group;
-}
-
-StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId) {
- StateMap_StateGroup group;
- group.set_group_id(screenOffId);
- group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
- return group;
-}
-
-StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- StateMap map;
- *map.add_group() = CreateScreenStateOnGroup(screenOnId);
- *map.add_group() = CreateScreenStateOffGroup(screenOffId);
- return map;
-}
-
-StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
- StateMap map;
- *map.add_group() = CreateScreenStateSimpleOnGroup(screenOnId);
- *map.add_group() = CreateScreenStateSimpleOffGroup(screenOffId);
- return map;
-}
-
-void addPredicateToPredicateCombination(const Predicate& predicate,
- Predicate* combinationPredicate) {
- combinationPredicate->mutable_combination()->add_predicate(predicate.id());
-}
-
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- }
- return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const auto position : positions) {
- auto child = dimensions.add_child();
- child->set_field(1);
- child->set_position(position);
- child->add_child()->set_field(1);
- child->add_child()->set_field(2);
- }
- return dimensions;
-}
-
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
- FieldMatcher dimensions;
- dimensions.set_field(atomId);
- for (const int field : fields) {
- dimensions.add_child()->set_field(field);
- }
- return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
- const std::vector<Position>& positions,
- const std::vector<int>& fields) {
- FieldMatcher dimensions = CreateAttributionUidDimensions(atomId, positions);
-
- for (const int field : fields) {
- dimensions.add_child()->set_field(field);
- }
- return dimensions;
-}
-
-// START: get primary key functions
-void getUidProcessKey(int uid, HashableDimensionKey* key) {
- int pos1[] = {1, 0, 0};
- Field field1(27 /* atom id */, pos1, 0 /* depth */);
- Value value1((int32_t)uid);
-
- key->addValue(FieldValue(field1, value1));
-}
-
-void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
- int pos1[] = {1, 0, 0};
- int pos2[] = {2, 0, 0};
-
- Field field1(59 /* atom id */, pos1, 0 /* depth */);
- Field field2(59 /* atom id */, pos2, 0 /* depth */);
-
- Value value1((int32_t)uid);
- Value value2(packageName);
-
- key->addValue(FieldValue(field1, value1));
- key->addValue(FieldValue(field2, value2));
-}
-
-void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
- int pos1[] = {1, 1, 1};
- int pos3[] = {2, 0, 0};
- int pos4[] = {3, 0, 0};
-
- Field field1(10 /* atom id */, pos1, 2 /* depth */);
-
- Field field3(10 /* atom id */, pos3, 0 /* depth */);
- Field field4(10 /* atom id */, pos4, 0 /* depth */);
-
- Value value1((int32_t)uid);
- Value value3((int32_t)1 /*partial*/);
- Value value4(tag);
-
- key->addValue(FieldValue(field1, value1));
- key->addValue(FieldValue(field3, value3));
- key->addValue(FieldValue(field4, value4));
-}
-
-void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
- int pos1[] = {1, 1, 1};
- int pos3[] = {2, 0, 0};
-
- Field field1(10 /* atom id */, pos1, 2 /* depth */);
- Field field3(10 /* atom id */, pos3, 0 /* depth */);
-
- Value value1((int32_t)uid);
- Value value3((int32_t)1 /*partial*/);
-
- key->addValue(FieldValue(field1, value1));
- key->addValue(FieldValue(field3, value3));
-}
-// END: get primary key functions
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags) {
- vector<const char*> cTags(attributionTags.size());
- for (int i = 0; i < cTags.size(); i++) {
- cTags[i] = attributionTags[i].c_str();
- }
-
- AStatsEvent_writeAttributionChain(statsEvent,
- reinterpret_cast<const uint32_t*>(attributionUids.data()),
- cTags.data(), attributionUids.size());
-}
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
- AStatsEvent_build(statsEvent);
-
- size_t size;
- uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
- logEvent->parseBuffer(buf, size);
-
- AStatsEvent_release(statsEvent);
-}
-
-void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, value1);
- AStatsEvent_writeInt32(statsEvent, value2);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
- return logEvent;
-}
-
-void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, value1);
- AStatsEvent_writeInt32(statsEvent, value2);
- AStatsEvent_writeInt32(statsEvent, value3);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
- return logEvent;
-}
-
-void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
- int32_t value) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, value);
- AStatsEvent_writeInt32(statsEvent, value);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
- return logEvent;
-}
-
-void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
- return logEvent;
-}
-
-shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
- int data2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
- AStatsEvent_writeInt32(statsEvent, data1);
- AStatsEvent_writeInt32(statsEvent, data2);
-
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
- const vector<int>& uids, const vector<string>& tags,
- int data1, int data2) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, atomId);
- AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
- writeAttribution(statsEvent, uids, tags);
- AStatsEvent_writeInt32(statsEvent, data1);
- AStatsEvent_writeInt32(statsEvent, data2);
-
- shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids) {
- sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
- EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
- for (const int isolatedUid : isolatedUids) {
- EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
- }
-
- return uidMap;
-}
-
-sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
- sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
- EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
- EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
-
- return uidMap;
-}
-
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
- const android::view::DisplayStateEnum state,
- int loggerUid) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
- AStatsEvent_writeInt32(statsEvent, level);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
- const vector<int>& attributionUids, const vector<string>& attributionTags,
- const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, jobName.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::STARTED, timestampNs);
-}
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName) {
- return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
- ScheduledJobStateChanged::FINISHED, timestampNs);
-}
-
-std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& wakelockName,
- const WakelockStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
- AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeString(statsEvent, wakelockName.c_str());
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& wakelockName) {
- return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
- wakelockName, WakelockStateChanged::ACQUIRE);
-}
-
-std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& wakelockName) {
- return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
- wakelockName, WakelockStateChanged::RELEASE);
-}
-
-std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
- uint64_t timestampNs, const int uid, const ActivityForegroundStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, "pkg_name");
- AStatsEvent_writeString(statsEvent, "class_name");
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
- return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
- ActivityForegroundStateChanged::BACKGROUND);
-}
-
-std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
- return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
- ActivityForegroundStateChanged::FOREGROUND);
-}
-
-std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name,
- const SyncStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_writeString(statsEvent, name.c_str());
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::ON);
-}
-
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& name) {
- return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
- SyncStateChanged::OFF);
-}
-
-std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
- uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, "");
- AStatsEvent_writeInt32(statsEvent, state);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
- return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
- ProcessLifeCycleStateChanged::CRASHED);
-}
-
-std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_writeString(statsEvent, "eventType");
- AStatsEvent_writeString(statsEvent, "processName");
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
- int isolatedUid, bool is_create) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, hostUid);
- AStatsEvent_writeInt32(statsEvent, isolatedUid);
- AStatsEvent_writeInt32(statsEvent, is_create);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
- uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const BleScanStateChanged::State state,
- const bool filtered, const bool firstMatch,
- const bool opportunistic) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- writeAttribution(statsEvent, attributionUids, attributionTags);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true);
- if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
- AStatsEvent_addInt32Annotation(statsEvent, ANNOTATION_ID_TRIGGER_STATE_RESET,
- util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
- }
- AStatsEvent_writeBool(statsEvent, filtered); // filtered
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeBool(statsEvent, firstMatch); // first match
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeBool(statsEvent, opportunistic); // opportunistic
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
- const string& packageName,
- const bool usingAlertWindow,
- const OverlayStateChanged::State state) {
- AStatsEvent* statsEvent = AStatsEvent_obtain();
- AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
- AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
- AStatsEvent_writeInt32(statsEvent, uid);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeString(statsEvent, packageName.c_str());
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
- AStatsEvent_writeBool(statsEvent, usingAlertWindow);
- AStatsEvent_writeInt32(statsEvent, state);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
- AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
- std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
- parseStatsEventToLogEvent(statsEvent, logEvent.get());
- return logEvent;
-}
-
-sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
- const StatsdConfig& config, const ConfigKey& key,
- const shared_ptr<IPullAtomCallback>& puller,
- const int32_t atomTag, const sp<UidMap> uidMap) {
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- if (puller != nullptr) {
- pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
- puller);
- }
- sp<AlarmMonitor> anomalyAlarmMonitor =
- new AlarmMonitor(1,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
- sp<AlarmMonitor> periodicAlarmMonitor =
- new AlarmMonitor(1,
- [](const shared_ptr<IStatsCompanionService>&, int64_t){},
- [](const shared_ptr<IStatsCompanionService>&){});
- sp<StatsLogProcessor> processor =
- new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseNs, [](const ConfigKey&) { return true; },
- [](const int&, const vector<int64_t>&) {return true;});
- processor->OnConfigUpdated(currentTimeNs, key, config);
- return processor;
-}
-
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
- std::sort(events->begin(), events->end(),
- [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
- return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
- });
-}
-
-int64_t StringToId(const string& str) {
- return static_cast<int64_t>(std::hash<std::string>()(str));
-}
-
-void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
- const int uid, const string& tag) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
- // Attribution field.
- EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
- // Uid field.
- ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
- uid);
- // Tag field.
- EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
- EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
-}
-
-void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
- // Attribution field.
- EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
- // Uid only.
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value_size(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).value_int(), uid);
-}
-
-void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
- // Attribution field.
- EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).value_int(), uid);
-}
-
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
- // Attribution field.
- EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
- // Uid only.
- EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value_size());
- EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).field());
- EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(0).value_int());
- EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(1).field());
- EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
- .value_tuple().dimensions_value(1).value_str());
-}
-
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
- EXPECT_EQ(value.field(), atomId);
- ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
- // Attribution field.
- EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
- // Uid only.
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value_size(), 2);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).field(), 1);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(0).value_int(), uid);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(1).field(), 2);
- EXPECT_EQ(value.value_tuple().dimensions_value(0)
- .value_tuple().dimensions_value(1).value_str(), tag);
-}
-
-bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
- if (s1.field() != s2.field()) {
- return false;
- }
- if (s1.value_case() != s2.value_case()) {
- return false;
- }
- switch (s1.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return (s1.value_str() == s2.value_str());
- case DimensionsValue::ValueCase::kValueInt:
- return s1.value_int() == s2.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return s1.value_long() == s2.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return s1.value_bool() == s2.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return s1.value_float() == s2.value_float();
- case DimensionsValue::ValueCase::kValueTuple: {
- if (s1.value_tuple().dimensions_value_size() !=
- s2.value_tuple().dimensions_value_size()) {
- return false;
- }
- bool allMatched = true;
- for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
- allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
- }
- return allMatched;
- }
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- default:
- return true;
- }
-}
-
-bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
- const google::protobuf::RepeatedPtrField<StateValue>& s2) {
- if (s1.size() != s2.size()) {
- return s1.size() < s2.size();
- }
- for (int i = 0; i < s1.size(); i++) {
- const StateValue& state1 = s1[i];
- const StateValue& state2 = s2[i];
- if (state1.atom_id() != state2.atom_id()) {
- return state1.atom_id() < state2.atom_id();
- }
- if (state1.value() != state2.value()) {
- return state1.value() < state2.value();
- }
- if (state1.group_id() != state2.group_id()) {
- return state1.group_id() < state2.group_id();
- }
- }
- return false;
-}
-
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
- if (s1.field() != s2.field()) {
- return s1.field() < s2.field();
- }
- if (s1.value_case() != s2.value_case()) {
- return s1.value_case() < s2.value_case();
- }
- switch (s1.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- return s1.value_str() < s2.value_str();
- case DimensionsValue::ValueCase::kValueInt:
- return s1.value_int() < s2.value_int();
- case DimensionsValue::ValueCase::kValueLong:
- return s1.value_long() < s2.value_long();
- case DimensionsValue::ValueCase::kValueBool:
- return (int)s1.value_bool() < (int)s2.value_bool();
- case DimensionsValue::ValueCase::kValueFloat:
- return s1.value_float() < s2.value_float();
- case DimensionsValue::ValueCase::kValueTuple: {
- if (s1.value_tuple().dimensions_value_size() !=
- s2.value_tuple().dimensions_value_size()) {
- return s1.value_tuple().dimensions_value_size() <
- s2.value_tuple().dimensions_value_size();
- }
- for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
- if (EqualsTo(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i))) {
- continue;
- } else {
- return LessThan(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
- }
- }
- return false;
- }
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- default:
- return false;
- }
-}
-
-bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
- if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
- return true;
- } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
- return false;
- }
-
- return LessThan(s1.stateValues, s2.stateValues);
-}
-
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
- DimensionsValue* dimension) {
- if (dimension->has_value_str_hash()) {
- auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
- if (it != str_map.end()) {
- dimension->clear_value_str_hash();
- dimension->set_value_str(it->second);
- } else {
- ALOGE("Can not find the string hash: %llu",
- (unsigned long long)dimension->value_str_hash());
- }
- } else if (dimension->has_value_tuple()) {
- auto value_tuple = dimension->mutable_value_tuple();
- for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
- backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
- }
- }
-}
-
-void backfillStringInReport(ConfigMetricsReport *config_report) {
- std::map<uint64_t, string> str_map;
- for (const auto& str : config_report->strings()) {
- uint64_t hash = Hash64(str);
- if (str_map.find(hash) != str_map.end()) {
- ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
- }
- str_map[hash] = str;
- }
- for (int i = 0; i < config_report->metrics_size(); ++i) {
- auto metric_report = config_report->mutable_metrics(i);
- if (metric_report->has_count_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
- } else if (metric_report->has_duration_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
- } else if (metric_report->has_gauge_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
- } else if (metric_report->has_value_metrics()) {
- backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
- }
- }
- // Backfill the package names.
- for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
- auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
- for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
- auto package_info = snapshot->mutable_package_info(j);
- if (package_info->has_name_hash()) {
- auto it = str_map.find((uint64_t)(package_info->name_hash()));
- if (it != str_map.end()) {
- package_info->clear_name_hash();
- package_info->set_name(it->second);
- } else {
- ALOGE("Can not find the string package name hash: %llu",
- (unsigned long long)package_info->name_hash());
- }
-
- }
- }
- }
- // Backfill the app name in app changes.
- for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
- auto change = config_report->mutable_uid_map()->mutable_changes(i);
- if (change->has_app_hash()) {
- auto it = str_map.find((uint64_t)(change->app_hash()));
- if (it != str_map.end()) {
- change->clear_app_hash();
- change->set_app(it->second);
- } else {
- ALOGE("Can not find the string change app name hash: %llu",
- (unsigned long long)change->app_hash());
- }
- }
- }
-}
-
-void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
- for (int i = 0; i < config_report_list->reports_size(); ++i) {
- backfillStringInReport(config_report_list->mutable_reports(i));
- }
-}
-
-bool backfillDimensionPath(const DimensionsValue& path,
- const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
- int* leafIndex,
- DimensionsValue* dimension) {
- dimension->set_field(path.field());
- if (path.has_value_tuple()) {
- for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
- if (!backfillDimensionPath(
- path.value_tuple().dimensions_value(i), leafValues, leafIndex,
- dimension->mutable_value_tuple()->add_dimensions_value())) {
- return false;
- }
- }
- } else {
- if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
- return false;
- }
- dimension->MergeFrom(leafValues.Get(*leafIndex));
- (*leafIndex)++;
- }
- return true;
-}
-
-bool backfillDimensionPath(const DimensionsValue& path,
- const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
- DimensionsValue* dimension) {
- int leafIndex = 0;
- return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
-}
-
-void backfillDimensionPath(ConfigMetricsReportList *config_report_list) {
- for (int i = 0; i < config_report_list->reports_size(); ++i) {
- auto report = config_report_list->mutable_reports(i);
- for (int j = 0; j < report->metrics_size(); ++j) {
- auto metric_report = report->mutable_metrics(j);
- if (metric_report->has_dimensions_path_in_what() ||
- metric_report->has_dimensions_path_in_condition()) {
- auto whatPath = metric_report->dimensions_path_in_what();
- auto conditionPath = metric_report->dimensions_path_in_condition();
- if (metric_report->has_count_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_count_metrics());
- } else if (metric_report->has_duration_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_duration_metrics());
- } else if (metric_report->has_gauge_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_gauge_metrics());
- } else if (metric_report->has_value_metrics()) {
- backfillDimensionPath(whatPath, conditionPath,
- metric_report->mutable_value_metrics());
- }
- metric_report->clear_dimensions_path_in_what();
- metric_report->clear_dimensions_path_in_condition();
- }
- }
- }
-}
-
-void backfillStartEndTimestamp(StatsLogReport *report) {
- const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
- const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
- if (report->has_count_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
- } else if (report->has_duration_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
- } else if (report->has_gauge_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
- if (report->gauge_metrics().skipped_size() > 0) {
- backfillStartEndTimestampForSkippedBuckets(
- timeBaseNs, report->mutable_gauge_metrics());
- }
- } else if (report->has_value_metrics()) {
- backfillStartEndTimestampForMetrics(
- timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
- if (report->value_metrics().skipped_size() > 0) {
- backfillStartEndTimestampForSkippedBuckets(
- timeBaseNs, report->mutable_value_metrics());
- }
- }
-}
-
-void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
- for (int j = 0; j < config_report->metrics_size(); ++j) {
- backfillStartEndTimestamp(config_report->mutable_metrics(j));
- }
-}
-
-void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
- for (int i = 0; i < config_report_list->reports_size(); ++i) {
- backfillStartEndTimestamp(config_report_list->mutable_reports(i));
- }
-}
-
-Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
- // Convert stats_events into StatsEventParcels.
- std::vector<StatsEventParcel> parcels;
- for (int i = 1; i < 3; i++) {
- AStatsEvent* event = AStatsEvent_obtain();
- AStatsEvent_setAtomId(event, atomTag);
- std::string subsystemName = "subsystem_name_";
- subsystemName = subsystemName + std::to_string(i);
- AStatsEvent_writeString(event, subsystemName.c_str());
- AStatsEvent_writeString(event, "subsystem_subname foo");
- AStatsEvent_writeInt64(event, /*count= */ i);
- AStatsEvent_writeInt64(event, /*time_millis= */ i * 100);
- AStatsEvent_build(event);
- size_t size;
- uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
- StatsEventParcel p;
- // vector.assign() creates a copy, but this is inevitable unless
- // stats_event.h/c uses a vector as opposed to a buffer.
- p.buffer.assign(buffer, buffer + size);
- parcels.push_back(std::move(p));
- AStatsEvent_release(event);
- }
- resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
- return Status::ok();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
deleted file mode 100644
index 3dcf4ecce054..000000000000
--- a/cmds/statsd/tests/statsd_test_util.h
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/hash.h"
-#include "src/logd/LogEvent.h"
-#include "src/packages/UidMap.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "statslog_statsdtest.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using ::aidl::android::os::BnPullAtomCallback;
-using ::aidl::android::os::IPullAtomCallback;
-using ::aidl::android::os::IPullAtomResultReceiver;
-using android::util::ProtoReader;
-using google::protobuf::RepeatedPtrField;
-using Status = ::ndk::ScopedAStatus;
-
-const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED;
-const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED;
-
-enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE };
-
-class MockUidMap : public UidMap {
-public:
- MOCK_METHOD(int, getHostUidOrSelf, (int uid), (const));
- MOCK_METHOD(std::set<int32_t>, getAppUid, (const string& package), (const));
-};
-
-// Converts a ProtoOutputStream to a StatsLogReport proto.
-StatsLogReport outputStreamToProto(ProtoOutputStream* proto);
-
-// Create AtomMatcher proto to simply match a specific atom type.
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
-
-// Create AtomMatcher proto for temperature atom.
-AtomMatcher CreateTemperatureAtomMatcher();
-
-// Create AtomMatcher proto for scheduled job state changed.
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting a scheduled job.
-AtomMatcher CreateStartScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for a scheduled job is done.
-AtomMatcher CreateFinishScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for screen brightness state changed.
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting battery save mode.
-AtomMatcher CreateBatterySaverModeStartAtomMatcher();
-
-// Create AtomMatcher proto for stopping battery save mode.
-AtomMatcher CreateBatterySaverModeStopAtomMatcher();
-
-// Create AtomMatcher proto for battery state none mode.
-AtomMatcher CreateBatteryStateNoneMatcher();
-
-// Create AtomMatcher proto for battery state usb mode.
-AtomMatcher CreateBatteryStateUsbMatcher();
-
-// Create AtomMatcher proto for process state changed.
-AtomMatcher CreateUidProcessStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for acquiring wakelock.
-AtomMatcher CreateAcquireWakelockAtomMatcher();
-
-// Create AtomMatcher proto for releasing wakelock.
-AtomMatcher CreateReleaseWakelockAtomMatcher() ;
-
-// Create AtomMatcher proto for screen turned on.
-AtomMatcher CreateScreenTurnedOnAtomMatcher();
-
-// Create AtomMatcher proto for screen turned off.
-AtomMatcher CreateScreenTurnedOffAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned on.
-AtomMatcher CreateSyncStartAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned off.
-AtomMatcher CreateSyncEndAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to background.
-AtomMatcher CreateMoveToBackgroundAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to foreground.
-AtomMatcher CreateMoveToForegroundAtomMatcher();
-
-// Create AtomMatcher proto for process crashes
-AtomMatcher CreateProcessCrashAtomMatcher() ;
-
-// Create Predicate proto for screen is on.
-Predicate CreateScreenIsOnPredicate();
-
-// Create Predicate proto for screen is off.
-Predicate CreateScreenIsOffPredicate();
-
-// Create Predicate proto for a running scheduled job.
-Predicate CreateScheduledJobPredicate();
-
-// Create Predicate proto for battery saver mode.
-Predicate CreateBatterySaverModePredicate();
-
-// Create Predicate proto for device unplogged mode.
-Predicate CreateDeviceUnpluggedPredicate();
-
-// Create Predicate proto for holding wakelock.
-Predicate CreateHoldingWakelockPredicate();
-
-// Create a Predicate proto for app syncing.
-Predicate CreateIsSyncingPredicate();
-
-// Create a Predicate proto for app is in background.
-Predicate CreateIsInBackgroundPredicate();
-
-// Create State proto for screen state atom.
-State CreateScreenState();
-
-// Create State proto for uid process state atom.
-State CreateUidProcessState();
-
-// Create State proto for overlay state atom.
-State CreateOverlayState();
-
-// Create State proto for screen state atom with on/off map.
-State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create State proto for screen state atom with simple on/off map.
-State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create StateGroup proto for ScreenState ON group
-StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId);
-
-// Create StateGroup proto for ScreenState OFF group
-StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId);
-
-// Create StateGroup proto for simple ScreenState ON group
-StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId);
-
-// Create StateGroup proto for simple ScreenState OFF group
-StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId);
-
-// Create StateMap proto for ScreenState ON/OFF map
-StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create StateMap proto for simple ScreenState ON/OFF map
-StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Add a predicate to the predicate combination.
-void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
-
-// Create dimensions from primitive fields.
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
-
-// Create dimensions by attribution uid and tag.
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-// Create dimensions by attribution uid only.
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
- const std::vector<Position>& positions);
-
-FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
- const std::vector<Position>& positions,
- const std::vector<int>& fields);
-
-// START: get primary key functions
-// These functions take in atom field information and create FieldValues which are stored in the
-// given HashableDimensionKey.
-void getUidProcessKey(int uid, HashableDimensionKey* key);
-
-void getOverlayKey(int uid, string packageName, HashableDimensionKey* key);
-
-void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key);
-
-void getPartialWakelockKey(int uid, HashableDimensionKey* key);
-// END: get primary key functions
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
- const vector<string>& attributionTags);
-
-// Builds statsEvent to get buffer that is parsed into logEvent then releases statsEvent.
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
-
-shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2);
-
-void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2);
-
-shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3);
-
-void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
- int32_t value2, int32_t value3);
-
-// The repeated value log event helpers create a log event with two int fields, both
-// set to the same value. This is useful for testing metrics that are only interested
-// in the value of the second field but still need the first field to be populated.
-std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs,
- int32_t value);
-
-void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
- int32_t value);
-
-std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs);
-
-void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs);
-
-std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
- int data2);
-
-std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
- const vector<int>& uids,
- const vector<string>& tags, int data1, int data2);
-
-sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids);
-
-sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids);
-
-// Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
- const android::view::DisplayStateEnum state,
- int loggerUid = 0);
-
-// Create log event for screen brightness state changed.
-std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);
-
-// Create log event when scheduled job starts.
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const string& jobName);
-
-// Create log event when battery saver starts.
-std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
-// Create log event when battery saver stops.
-std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs);
-
-// Create log event when battery state changes.
-std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state);
-
-// Create log event for app moving to background.
-std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for app moving to foreground.
-std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid);
-
-// Create log event when the app sync starts.
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags, const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags, const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for an app crash.
-std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for acquiring wakelock.
-std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags,
- const string& wakelockName);
-
-// Create log event for releasing wakelock.
-std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
- const vector<string>& tags,
- const string& wakelockName);
-
-// Create log event for releasing wakelock.
-std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
- int isolatedUid, bool is_create);
-
-// Create log event for uid process state change.
-std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
- uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state);
-
-std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
- const vector<int>& attributionUids,
- const vector<string>& attributionTags,
- const BleScanStateChanged::State state,
- const bool filtered, const bool firstMatch,
- const bool opportunistic);
-
-std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
- const string& packageName,
- const bool usingAlertWindow,
- const OverlayStateChanged::State state);
-
-// Create a statsd log event processor upon the start time in seconds, config and key.
-sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
- const StatsdConfig& config, const ConfigKey& key,
- const shared_ptr<IPullAtomCallback>& puller = nullptr,
- const int32_t atomTag = 0 /*for puller only*/,
- const sp<UidMap> = new UidMap());
-
-// Util function to sort the log events by timestamp.
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
-
-int64_t StringToId(const string& str);
-
-void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
- const int uid, const string& tag);
-void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid);
-void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid);
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int atomId, int uid, const std::string& tag);
-void ValidateAttributionUidAndTagDimension(
- const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag);
-
-struct DimensionsPair {
- DimensionsPair(DimensionsValue m1, google::protobuf::RepeatedPtrField<StateValue> m2)
- : dimInWhat(m1), stateValues(m2){};
-
- DimensionsValue dimInWhat;
- google::protobuf::RepeatedPtrField<StateValue> stateValues;
-};
-
-bool LessThan(const StateValue& s1, const StateValue& s2);
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
-bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
-
-
-void backfillStartEndTimestamp(ConfigMetricsReport *config_report);
-void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list);
-
-void backfillStringInReport(ConfigMetricsReportList *config_report_list);
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
- DimensionsValue* dimension);
-
-template <typename T>
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
- T* metrics) {
- for (int i = 0; i < metrics->data_size(); ++i) {
- auto data = metrics->mutable_data(i);
- if (data->has_dimensions_in_what()) {
- backfillStringInDimension(str_map, data->mutable_dimensions_in_what());
- }
- if (data->has_dimensions_in_condition()) {
- backfillStringInDimension(str_map, data->mutable_dimensions_in_condition());
- }
- }
-}
-
-void backfillDimensionPath(ConfigMetricsReportList* config_report_list);
-
-bool backfillDimensionPath(const DimensionsValue& path,
- const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
- DimensionsValue* dimension);
-
-class FakeSubsystemSleepCallback : public BnPullAtomCallback {
-public:
- Status onPullAtom(int atomTag,
- const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override;
-};
-
-template <typename T>
-void backfillDimensionPath(const DimensionsValue& whatPath,
- const DimensionsValue& conditionPath,
- T* metricData) {
- for (int i = 0; i < metricData->data_size(); ++i) {
- auto data = metricData->mutable_data(i);
- if (data->dimension_leaf_values_in_what_size() > 0) {
- backfillDimensionPath(whatPath, data->dimension_leaf_values_in_what(),
- data->mutable_dimensions_in_what());
- data->clear_dimension_leaf_values_in_what();
- }
- if (data->dimension_leaf_values_in_condition_size() > 0) {
- backfillDimensionPath(conditionPath, data->dimension_leaf_values_in_condition(),
- data->mutable_dimensions_in_condition());
- data->clear_dimension_leaf_values_in_condition();
- }
- }
-}
-
-struct DimensionCompare {
- bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
- return LessThan(s1, s2);
- }
-};
-
-template <typename T>
-void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) {
- std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap;
- for (int i = 0; i < metricData.data_size(); ++i) {
- dimensionIndexMap.insert(
- std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
- metricData.data(i).slice_by_state()),
- i));
- }
- for (const auto& itr : dimensionIndexMap) {
- *sortedMetricData->add_data() = metricData.data(itr.second);
- }
-}
-
-template <typename T>
-void backfillStartEndTimestampForFullBucket(
- const int64_t timeBaseNs, const int64_t bucketSizeNs, T* bucket) {
- bucket->set_start_bucket_elapsed_nanos(timeBaseNs + bucketSizeNs * bucket->bucket_num());
- bucket->set_end_bucket_elapsed_nanos(
- timeBaseNs + bucketSizeNs * bucket->bucket_num() + bucketSizeNs);
- bucket->clear_bucket_num();
-}
-
-template <typename T>
-void backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs, T* bucket) {
- if (bucket->has_start_bucket_elapsed_millis()) {
- bucket->set_start_bucket_elapsed_nanos(
- MillisToNano(bucket->start_bucket_elapsed_millis()));
- bucket->clear_start_bucket_elapsed_millis();
- }
- if (bucket->has_end_bucket_elapsed_millis()) {
- bucket->set_end_bucket_elapsed_nanos(
- MillisToNano(bucket->end_bucket_elapsed_millis()));
- bucket->clear_end_bucket_elapsed_millis();
- }
-}
-
-template <typename T>
-void backfillStartEndTimestampForMetrics(const int64_t timeBaseNs, const int64_t bucketSizeNs,
- T* metrics) {
- for (int i = 0; i < metrics->data_size(); ++i) {
- auto data = metrics->mutable_data(i);
- for (int j = 0; j < data->bucket_info_size(); ++j) {
- auto bucket = data->mutable_bucket_info(j);
- if (bucket->has_bucket_num()) {
- backfillStartEndTimestampForFullBucket(timeBaseNs, bucketSizeNs, bucket);
- } else {
- backfillStartEndTimestampForPartialBucket(timeBaseNs, bucket);
- }
- }
- }
-}
-
-template <typename T>
-void backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs, T* metrics) {
- for (int i = 0; i < metrics->skipped_size(); ++i) {
- backfillStartEndTimestampForPartialBucket(timeBaseNs, metrics->mutable_skipped(i));
- }
-}
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
deleted file mode 100644
index 74eafbf56d66..000000000000
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <android-base/unique_fd.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include "src/storage/StorageManager.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using testing::Contains;
-
-TEST(StorageManagerTest, TrainInfoReadWriteTest) {
- InstallTrainInfo trainInfo;
- trainInfo.trainVersionCode = 12345;
- trainInfo.trainName = "This is a train name #)$(&&$";
- trainInfo.status = 1;
- const char* expIds = "test_ids";
- trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
-
- bool result;
-
- result = StorageManager::writeTrainInfo(trainInfo);
-
- EXPECT_TRUE(result);
-
- InstallTrainInfo trainInfoResult;
- result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult);
- EXPECT_TRUE(result);
-
- EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
- ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
- EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
- EXPECT_EQ(trainInfo.status, trainInfoResult.status);
- ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
- EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
-}
-
-TEST(StorageManagerTest, TrainInfoReadWriteTrainNameSizeOneTest) {
- InstallTrainInfo trainInfo;
- trainInfo.trainVersionCode = 12345;
- trainInfo.trainName = "{";
- trainInfo.status = 1;
- const char* expIds = "test_ids";
- trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
-
- bool result;
-
- result = StorageManager::writeTrainInfo(trainInfo);
-
- EXPECT_TRUE(result);
-
- InstallTrainInfo trainInfoResult;
- result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult);
- EXPECT_TRUE(result);
-
- EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
- ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
- EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
- EXPECT_EQ(trainInfo.status, trainInfoResult.status);
- ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
- EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
-}
-
-TEST(StorageManagerTest, SortFileTest) {
- vector<StorageManager::FileInfo> list;
- // assume now sec is 500
- list.emplace_back("200_5000_123454", false, 20, 300);
- list.emplace_back("300_2000_123454_history", true, 30, 200);
- list.emplace_back("400_100009_123454_history", true, 40, 100);
- list.emplace_back("100_2000_123454", false, 50, 400);
-
- StorageManager::sortFiles(&list);
- EXPECT_EQ("200_5000_123454", list[0].mFileName);
- EXPECT_EQ("100_2000_123454", list[1].mFileName);
- EXPECT_EQ("400_100009_123454_history", list[2].mFileName);
- EXPECT_EQ("300_2000_123454_history", list[3].mFileName);
-}
-
-const string testDir = "/data/misc/stats-data/";
-const string file1 = testDir + "2557169347_1066_1";
-const string file2 = testDir + "2557169349_1066_1";
-const string file1_history = file1 + "_history";
-const string file2_history = file2 + "_history";
-
-bool prepareLocalHistoryTestFiles() {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(
- open(file1.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
- if (fd != -1) {
- dprintf(fd, "content");
- } else {
- return false;
- }
-
- android::base::unique_fd fd2(TEMP_FAILURE_RETRY(
- open(file2.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
- if (fd2 != -1) {
- dprintf(fd2, "content");
- } else {
- return false;
- }
- return true;
-}
-
-void clearLocalHistoryTestFiles() {
- TEMP_FAILURE_RETRY(remove(file1.c_str()));
- TEMP_FAILURE_RETRY(remove(file2.c_str()));
- TEMP_FAILURE_RETRY(remove(file1_history.c_str()));
- TEMP_FAILURE_RETRY(remove(file2_history.c_str()));
-}
-
-bool fileExist(string name) {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(name.c_str(), O_RDONLY | O_CLOEXEC)));
- return fd != -1;
-}
-
-/* The following AppendConfigReportTests test the 4 combinations of [whether erase data] [whether
- * the caller is adb] */
-TEST(StorageManagerTest, AppendConfigReportTest1) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
- false /*isAdb?*/);
-
- EXPECT_FALSE(fileExist(file1));
- EXPECT_FALSE(fileExist(file2));
-
- EXPECT_TRUE(fileExist(file1_history));
- EXPECT_TRUE(fileExist(file2_history));
- clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest2) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
- false /*isAdb?*/);
-
- EXPECT_FALSE(fileExist(file1));
- EXPECT_FALSE(fileExist(file2));
- EXPECT_FALSE(fileExist(file1_history));
- EXPECT_FALSE(fileExist(file2_history));
-
- clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest3) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
- true /*isAdb?*/);
-
- EXPECT_TRUE(fileExist(file1));
- EXPECT_TRUE(fileExist(file2));
- EXPECT_FALSE(fileExist(file1_history));
- EXPECT_FALSE(fileExist(file2_history));
-
- clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest4) {
- EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
- ProtoOutputStream out;
- StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
- true /*isAdb?*/);
-
- EXPECT_FALSE(fileExist(file1));
- EXPECT_FALSE(fileExist(file2));
- EXPECT_FALSE(fileExist(file1_history));
- EXPECT_FALSE(fileExist(file2_history));
-
- clearLocalHistoryTestFiles();
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp b/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp
deleted file mode 100644
index 32cecd3b9dbc..000000000000
--- a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "utils/MultiConditionTrigger.h"
-
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <set>
-#include <thread>
-#include <vector>
-
-#ifdef __ANDROID__
-
-using namespace std;
-using std::this_thread::sleep_for;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TEST(MultiConditionTrigger, TestMultipleConditions) {
- int numConditions = 5;
- string t1 = "t1", t2 = "t2", t3 = "t3", t4 = "t4", t5 = "t5";
- set<string> conditionNames = {t1, t2, t3, t4, t5};
-
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
-
- // Mark done as true and notify in the done.
- MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] {
- {
- lock_guard lg(lock);
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- vector<thread> threads;
- vector<int> done(numConditions, 0);
-
- int i = 0;
- for (const string& conditionName : conditionNames) {
- threads.emplace_back([&done, &conditionName, &trigger, i] {
- sleep_for(chrono::milliseconds(3));
- done[i] = 1;
- trigger.markComplete(conditionName);
- });
- i++;
- }
-
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] {
- return triggerCalled;
- });
-
- for (i = 0; i < numConditions; i++) {
- EXPECT_EQ(done[i], 1);
- }
-
- for (i = 0; i < numConditions; i++) {
- threads[i].join();
- }
-}
-
-TEST(MultiConditionTrigger, TestNoConditions) {
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
-
- MultiConditionTrigger trigger({}, [&lock, &cv, &triggerCalled] {
- {
- lock_guard lg(lock);
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
- EXPECT_TRUE(triggerCalled);
- // Ensure that trigger occurs immediately if no events need to be completed.
-}
-
-TEST(MultiConditionTrigger, TestMarkCompleteCalledBySameCondition) {
- string t1 = "t1", t2 = "t2";
- set<string> conditionNames = {t1, t2};
-
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
-
- MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] {
- {
- lock_guard lg(lock);
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- trigger.markComplete(t1);
- trigger.markComplete(t1);
-
- // Ensure that the trigger still hasn't fired.
- {
- lock_guard lg(lock);
- EXPECT_FALSE(triggerCalled);
- }
-
- trigger.markComplete(t2);
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
- EXPECT_TRUE(triggerCalled);
-}
-
-TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) {
- string t1 = "t1";
- set<string> conditionNames = {t1};
-
- mutex lock;
- condition_variable cv;
- bool triggerCalled = false;
- int triggerCount = 0;
-
- MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled, &triggerCount] {
- {
- lock_guard lg(lock);
- triggerCount++;
- triggerCalled = true;
- }
- cv.notify_all();
- });
-
- trigger.markComplete(t1);
-
- // Ensure that the trigger fired.
- {
- unique_lock<mutex> unique_lk(lock);
- cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
- EXPECT_TRUE(triggerCalled);
- EXPECT_EQ(triggerCount, 1);
- triggerCalled = false;
- }
-
- trigger.markComplete(t1);
-
- // Ensure that the trigger does not fire again.
- {
- unique_lock<mutex> unique_lk(lock);
- cv.wait_for(unique_lk, chrono::milliseconds(5), [&triggerCalled] { return triggerCalled; });
- EXPECT_FALSE(triggerCalled);
- EXPECT_EQ(triggerCount, 1);
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tools/localtools/Android.bp b/cmds/statsd/tools/localtools/Android.bp
deleted file mode 100644
index 69a43a8f4712..000000000000
--- a/cmds/statsd/tools/localtools/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-java_binary_host {
- name: "statsd_localdrive",
- manifest: "localdrive_manifest.txt",
- srcs: [
- "src/com/android/statsd/shelltools/localdrive/*.java",
- "src/com/android/statsd/shelltools/Utils.java",
- ],
- static_libs: [
- "platformprotos",
- "guava",
- ],
-}
-
-java_library_host {
- name: "statsd_testdrive_lib",
- srcs: [
- "src/com/android/statsd/shelltools/testdrive/*.java",
- "src/com/android/statsd/shelltools/Utils.java",
- ],
- static_libs: [
- "platformprotos",
- "guava",
- ],
-}
-
-
-java_binary_host {
- name: "statsd_testdrive",
- manifest: "testdrive_manifest.txt",
- static_libs: [
- "statsd_testdrive_lib",
- ],
-}
-
-java_test_host {
- name: "statsd_testdrive_test",
- test_suites: ["general-tests"],
- srcs: ["test/com/android/statsd/shelltools/testdrive/*.java"],
- static_libs: [
- "statsd_testdrive_lib",
- "junit",
- "platformprotos",
- "guava",
- ],
-}
-
diff --git a/cmds/statsd/tools/localtools/TEST_MAPPING b/cmds/statsd/tools/localtools/TEST_MAPPING
deleted file mode 100644
index 7c8a3db5c610..000000000000
--- a/cmds/statsd/tools/localtools/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "presubmit": [
- {
- "name": "statsd_testdrive_test",
- "host": true
- }
- ]
-}
diff --git a/cmds/statsd/tools/localtools/localdrive_manifest.txt b/cmds/statsd/tools/localtools/localdrive_manifest.txt
deleted file mode 100644
index 035cea1134bc..000000000000
--- a/cmds/statsd/tools/localtools/localdrive_manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: com.android.statsd.shelltools.localdrive.LocalDrive
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
deleted file mode 100644
index 6a74480b505e..000000000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.shelltools;
-
-import com.android.os.StatsLog.ConfigMetricsReportList;
-
-import com.google.common.io.Files;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Utilities for local use of statsd.
- */
-public class Utils {
-
- public static final String CMD_DUMP_REPORT = "cmd stats dump-report";
- public static final String CMD_LOG_APP_BREADCRUMB = "cmd stats log-app-breadcrumb";
- public static final String CMD_REMOVE_CONFIG = "cmd stats config remove";
- public static final String CMD_UPDATE_CONFIG = "cmd stats config update";
-
- public static final String SHELL_UID = "2000"; // Use shell, even if rooted.
-
- /**
- * Runs adb shell command with output directed to outputFile if non-null.
- */
- public static void runCommand(File outputFile, Logger logger, String... commands)
- throws IOException, InterruptedException {
- ProcessBuilder pb = new ProcessBuilder(commands);
- if (outputFile != null && outputFile.exists() && outputFile.canWrite()) {
- pb.redirectOutput(outputFile);
- }
- Process process = pb.start();
-
- // Capture any errors
- StringBuilder err = new StringBuilder();
- BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- for (String line = br.readLine(); line != null; line = br.readLine()) {
- err.append(line).append('\n');
- }
- logger.severe(err.toString());
-
- // Check result
- if (process.waitFor() == 0) {
- logger.fine("Adb command successful.");
- } else {
- logger.severe("Abnormal adb shell termination for: " + String.join(",", commands));
- throw new RuntimeException("Error running adb command: " + err.toString());
- }
- }
-
- /**
- * Dumps the report from the device and converts it to a ConfigMetricsReportList.
- * Erases the data if clearData is true.
- * @param configId id of the config
- * @param clearData whether to erase the report data from statsd after getting the report.
- * @param useShellUid Pulls data for the {@link SHELL_UID} instead of the caller's uid.
- * @param logger Logger to log error messages
- * @return
- * @throws IOException
- * @throws InterruptedException
- */
- public static ConfigMetricsReportList getReportList(long configId, boolean clearData,
- boolean useShellUid, Logger logger, String deviceSerial)
- throws IOException, InterruptedException {
- try {
- File outputFile = File.createTempFile("statsdret", ".bin");
- outputFile.deleteOnExit();
- runCommand(
- outputFile,
- logger,
- "adb",
- "-s",
- deviceSerial,
- "shell",
- CMD_DUMP_REPORT,
- useShellUid ? SHELL_UID : "",
- String.valueOf(configId),
- clearData ? "" : "--keep_data",
- "--include_current_bucket",
- "--proto");
- ConfigMetricsReportList reportList =
- ConfigMetricsReportList.parseFrom(new FileInputStream(outputFile));
- return reportList;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- logger.severe("Failed to fetch and parse the statsd output report. "
- + "Perhaps there is not a valid statsd config for the requested "
- + (useShellUid ? ("uid=" + SHELL_UID + ", ") : "")
- + "configId=" + configId
- + ".");
- throw (e);
- }
- }
-
- /**
- * Logs an AppBreadcrumbReported atom.
- * @param label which label to log for the app breadcrumb atom.
- * @param state which state to log for the app breadcrumb atom.
- * @param logger Logger to log error messages
- *
- * @throws IOException
- * @throws InterruptedException
- */
- public static void logAppBreadcrumb(int label, int state, Logger logger, String deviceSerial)
- throws IOException, InterruptedException {
- runCommand(
- null,
- logger,
- "adb",
- "-s",
- deviceSerial,
- "shell",
- CMD_LOG_APP_BREADCRUMB,
- String.valueOf(label),
- String.valueOf(state));
- }
- public static void setUpLogger(Logger logger, boolean debug) {
- ConsoleHandler handler = new ConsoleHandler();
- handler.setFormatter(new LocalToolsFormatter());
- logger.setUseParentHandlers(false);
- if (debug) {
- handler.setLevel(Level.ALL);
- logger.setLevel(Level.ALL);
- }
- logger.addHandler(handler);
- }
-
- /**
- * Attempt to determine whether tool will work with this statsd, i.e. whether statsd is
- * minCodename or higher.
- * Algorithm: true if (sdk >= minSdk) || (sdk == minSdk-1 && codeName.startsWith(minCodeName))
- * If all else fails, assume it will work (letting future commands deal with any errors).
- */
- public static boolean isAcceptableStatsd(Logger logger, int minSdk, String minCodename,
- String deviceSerial) {
- BufferedReader in = null;
- try {
- File outFileSdk = File.createTempFile("shelltools_sdk", "tmp");
- outFileSdk.deleteOnExit();
- runCommand(outFileSdk, logger,
- "adb", "-s", deviceSerial, "shell", "getprop", "ro.build.version.sdk");
- in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileSdk)));
- // If NullPointerException/NumberFormatException/etc., just catch and return true.
- int sdk = Integer.parseInt(in.readLine().trim());
- if (sdk >= minSdk) {
- return true;
- } else if (sdk == minSdk - 1) { // Could be minSdk-1, or could be minSdk development.
- in.close();
- File outFileCode = File.createTempFile("shelltools_codename", "tmp");
- outFileCode.deleteOnExit();
- runCommand(outFileCode, logger,
- "adb", "-s", deviceSerial, "shell", "getprop", "ro.build.version.codename");
- in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileCode)));
- return in.readLine().startsWith(minCodename);
- } else {
- return false;
- }
- } catch (Exception e) {
- logger.fine("Could not determine whether statsd version is compatibile "
- + "with tool: " + e.toString());
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException e) {
- logger.fine("Could not close temporary file: " + e.toString());
- }
- }
- // Could not determine whether statsd is acceptable version.
- // Just assume it is; if it isn't, we'll just get future errors via adb and deal with them.
- return true;
- }
-
- public static class LocalToolsFormatter extends Formatter {
- public String format(LogRecord record) {
- return record.getMessage() + "\n";
- }
- }
-
- /**
- * Parse the result of "adb devices" to return the list of connected devices.
- * @param logger Logger to log error messages
- * @return List of the serial numbers of the connected devices.
- */
- public static List<String> getDeviceSerials(Logger logger) {
- try {
- ArrayList<String> devices = new ArrayList<>();
- File outFile = File.createTempFile("device_serial", "tmp");
- outFile.deleteOnExit();
- Utils.runCommand(outFile, logger, "adb", "devices");
- List<String> outputLines = Files.readLines(outFile, Charset.defaultCharset());
- Pattern regex = Pattern.compile("^(.*)\tdevice$");
- for (String line : outputLines) {
- Matcher m = regex.matcher(line);
- if (m.find()) {
- devices.add(m.group(1));
- }
- }
- return devices;
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Failed to list connected devices: " + ex.getMessage());
- }
- return null;
- }
-
- /**
- * Returns ANDROID_SERIAL environment variable, or null if that is undefined or unavailable.
- * @param logger Destination of error messages.
- * @return String value of ANDROID_SERIAL environment variable, or null.
- */
- public static String getDefaultDevice(Logger logger) {
- try {
- return System.getenv("ANDROID_SERIAL");
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Failed to check ANDROID_SERIAL environment variable.",
- ex);
- }
- return null;
- }
-
- /**
- * Returns the device to use if one can be deduced, or null.
- * @param device Command-line specified device, or null.
- * @param connectedDevices List of all connected devices.
- * @param defaultDevice Environment-variable specified device, or null.
- * @param logger Destination of error messages.
- * @return Device to use, or null.
- */
- public static String chooseDevice(String device, List<String> connectedDevices,
- String defaultDevice, Logger logger) {
- if (connectedDevices == null || connectedDevices.isEmpty()) {
- logger.severe("No connected device.");
- return null;
- }
- if (device != null) {
- if (connectedDevices.contains(device)) {
- return device;
- }
- logger.severe("Device not connected: " + device);
- return null;
- }
- if (connectedDevices.size() == 1) {
- return connectedDevices.get(0);
- }
- if (defaultDevice != null) {
- if (connectedDevices.contains(defaultDevice)) {
- return defaultDevice;
- } else {
- logger.severe("ANDROID_SERIAL device is not connected: " + defaultDevice);
- return null;
- }
- }
- logger.severe("More than one device is connected. Choose one"
- + " with -s DEVICE_SERIAL or environment variable ANDROID_SERIAL.");
- return null;
- }
-}
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
deleted file mode 100644
index ec3c7df7bfba..000000000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.shelltools.localdrive;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.statsd.shelltools.Utils;
-
-import com.google.common.io.Files;
-import com.google.protobuf.TextFormat;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * Tool for using statsd locally. Can upload a config and get the data. Handles
- * both binary and human-readable protos.
- * To make: make statsd_localdrive
- * To run: statsd_localdrive (i.e. ./out/host/linux-x86/bin/statsd_localdrive)
- */
-public class LocalDrive {
- private static final boolean DEBUG = false;
-
- public static final int MIN_SDK = 29;
- public static final String MIN_CODENAME = "Q";
-
- public static final long DEFAULT_CONFIG_ID = 56789;
-
- public static final String BINARY_FLAG = "--binary";
- public static final String CLEAR_DATA = "--clear";
- public static final String NO_UID_MAP_FLAG = "--no-uid-map";
-
- public static final String HELP_STRING =
- "Usage:\n\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] upload CONFIG_FILE [CONFIG_ID] [--binary]\n" +
- " Uploads the given statsd config file (in binary or human-readable-text format).\n" +
- " If a config with this id already exists, removes it first.\n" +
- " CONFIG_FILE Location of config file on host.\n" +
- " CONFIG_ID Long ID to associate with this config. If absent, uses "
- + DEFAULT_CONFIG_ID + ".\n" +
- " --binary Config is in binary format; otherwise, assumed human-readable text.\n" +
- // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] update CONFIG_FILE [CONFIG_ID] [--binary]\n" +
- " Same as upload, but does not remove the old config first (if it already exists).\n" +
- // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]\n" +
- " Prints the output statslog data (in binary or human-readable-text format).\n" +
- " CONFIG_ID Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
- " --binary Output should be in binary, instead of default human-readable text.\n" +
- " Binary output can be redirected as usual (e.g. > FILENAME).\n" +
- " --no-uid-map Do not include the uid-map (the very lengthy uid<-->pkgName map).\n" +
- " --clear Erase the data from statsd afterwards. Does not remove the config.\n" +
- // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID [--keep_data]
- // --include_current_bucket --proto
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] remove [CONFIG_ID]\n" +
- " Removes the config.\n" +
- " CONFIG_ID Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
- // Equivalent to: adb shell cmd stats config remove SHELL_UID CONFIG_ID
- "\n" +
-
- "statsd_localdrive [-s DEVICE_SERIAL] clear [CONFIG_ID]\n" +
- " Clears the data associated with the config.\n" +
- " CONFIG_ID Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
- // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID
- // --include_current_bucket --proto
- "";
-
-
- private static final Logger sLogger = Logger.getLogger(LocalDrive.class.getName());
-
- /** Usage: make statsd_localdrive && statsd_localdrive */
- public static void main(String[] args) {
- Utils.setUpLogger(sLogger, DEBUG);
- if (args.length == 0) {
- printHelp();
- return;
- }
-
- int remainingArgsLength = args.length;
- String deviceSerial = null;
- if (args[0].equals("-s")) {
- if (args.length == 1) {
- printHelp();
- }
- deviceSerial = args[1];
- remainingArgsLength -= 2;
- }
-
- List<String> connectedDevices = Utils.getDeviceSerials(sLogger);
- deviceSerial = Utils.chooseDevice(deviceSerial, connectedDevices,
- Utils.getDefaultDevice(sLogger), sLogger);
- if (deviceSerial == null) {
- return;
- }
-
- if (!Utils.isAcceptableStatsd(sLogger, MIN_SDK, MIN_CODENAME, deviceSerial)) {
- sLogger.severe("LocalDrive only works with statsd versions for Android "
- + MIN_CODENAME + " or higher.");
- return;
- }
-
- int idx = args.length - remainingArgsLength;
- if (remainingArgsLength > 0) {
- switch (args[idx]) {
- case "clear":
- cmdClear(args, idx, deviceSerial);
- return;
- case "get-data":
- cmdGetData(args, idx, deviceSerial);
- return;
- case "remove":
- cmdRemove(args, idx);
- return;
- case "update":
- cmdUpdate(args, idx, deviceSerial);
- return;
- case "upload":
- cmdUpload(args, idx, deviceSerial);
- return;
- }
- }
- printHelp();
- }
-
- private static void printHelp() {
- sLogger.info(HELP_STRING);
- }
-
- // upload CONFIG_FILE [CONFIG_ID] [--binary]
- private static boolean cmdUpload(String[] args, int idx, String deviceSerial) {
- return updateConfig(args, idx, true, deviceSerial);
- }
-
- // update CONFIG_FILE [CONFIG_ID] [--binary]
- private static boolean cmdUpdate(String[] args, int idx, String deviceSerial) {
- return updateConfig(args, idx, false, deviceSerial);
- }
-
- private static boolean updateConfig(String[] args, int idx, boolean removeOldConfig,
- String deviceSerial) {
- int argCount = args.length - 1 - idx; // Used up one for upload/update.
-
- // Get CONFIG_FILE
- if (argCount < 1) {
- sLogger.severe("No config file provided.");
- printHelp();
- return false;
- }
- final String origConfigLocation = args[idx + 1];
- if (!new File(origConfigLocation).exists()) {
- sLogger.severe("Error - Cannot find the provided config file: " + origConfigLocation);
- return false;
- }
- argCount--;
-
- // Get --binary
- boolean binary = contains(args, idx + 2, BINARY_FLAG);
- if (binary) argCount --;
-
- // Get CONFIG_ID
- long configId;
- try {
- configId = getConfigId(argCount < 1, args, idx + 2);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("updateConfig with %s %d %b %b",
- origConfigLocation, configId, binary, removeOldConfig));
-
- // Remove the old config.
- if (removeOldConfig) {
- try {
- Utils.runCommand(null, sLogger, "adb", "shell", Utils.CMD_REMOVE_CONFIG,
- Utils.SHELL_UID, String.valueOf(configId));
- Utils.getReportList(configId, true /* clearData */, true /* SHELL_UID */, sLogger,
- deviceSerial);
- } catch (InterruptedException | IOException e) {
- sLogger.severe("Failed to remove config: " + e.getMessage());
- return false;
- }
- }
-
- // Upload the config.
- String configLocation;
- if (binary) {
- configLocation = origConfigLocation;
- } else {
- StatsdConfig.Builder builder = StatsdConfig.newBuilder();
- try {
- TextFormat.merge(new FileReader(origConfigLocation), builder);
- } catch (IOException e) {
- sLogger.severe("Failed to read config file " + origConfigLocation + ": "
- + e.getMessage());
- return false;
- }
-
- try {
- File tempConfigFile = File.createTempFile("statsdconfig", ".config");
- tempConfigFile.deleteOnExit();
- Files.write(builder.build().toByteArray(), tempConfigFile);
- configLocation = tempConfigFile.getAbsolutePath();
- } catch (IOException e) {
- sLogger.severe("Failed to write temp config file: " + e.getMessage());
- return false;
- }
- }
- String remotePath = "/data/local/tmp/statsdconfig.config";
- try {
- Utils.runCommand(null, sLogger, "adb", "push", configLocation, remotePath);
- Utils.runCommand(null, sLogger, "adb", "shell", "cat", remotePath, "|",
- Utils.CMD_UPDATE_CONFIG, Utils.SHELL_UID, String.valueOf(configId));
- } catch (InterruptedException | IOException e) {
- sLogger.severe("Failed to update config: " + e.getMessage());
- return false;
- }
- return true;
- }
-
- // get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]
- private static boolean cmdGetData(String[] args, int idx, String deviceSerial) {
- boolean binary = contains(args, idx + 1, BINARY_FLAG);
- boolean noUidMap = contains(args, idx + 1, NO_UID_MAP_FLAG);
- boolean clearData = contains(args, idx + 1, CLEAR_DATA);
-
- // Get CONFIG_ID
- int argCount = args.length - 1 - idx; // Used up one for get-data.
- if (binary) argCount--;
- if (noUidMap) argCount--;
- if (clearData) argCount--;
- long configId;
- try {
- configId = getConfigId(argCount < 1, args, idx + 1);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("cmdGetData with %d %b %b %b",
- configId, clearData, binary, noUidMap));
-
- // Get the StatsLog
- // Even if the args request no modifications, we still parse it to make sure it's valid.
- ConfigMetricsReportList reportList;
- try {
- reportList = Utils.getReportList(configId, clearData, true /* SHELL_UID */, sLogger,
- deviceSerial);
- } catch (IOException | InterruptedException e) {
- sLogger.severe("Failed to get report list: " + e.getMessage());
- return false;
- }
- if (noUidMap) {
- ConfigMetricsReportList.Builder builder
- = ConfigMetricsReportList.newBuilder(reportList);
- // Clear the reports, then add them back without their UidMap.
- builder.clearReports();
- for (ConfigMetricsReport report : reportList.getReportsList()) {
- builder.addReports(ConfigMetricsReport.newBuilder(report).clearUidMap());
- }
- reportList = builder.build();
- }
-
- if (!binary) {
- sLogger.info(reportList.toString());
- } else {
- try {
- System.out.write(reportList.toByteArray());
- } catch (IOException e) {
- sLogger.severe("Failed to output binary statslog proto: "
- + e.getMessage());
- return false;
- }
- }
- return true;
- }
-
- // clear [CONFIG_ID]
- private static boolean cmdClear(String[] args, int idx, String deviceSerial) {
- // Get CONFIG_ID
- long configId;
- try {
- configId = getConfigId(false, args, idx + 1);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("cmdClear with %d", configId));
-
- try {
- Utils.getReportList(configId, true /* clearData */, true /* SHELL_UID */, sLogger,
- deviceSerial);
- } catch (IOException | InterruptedException e) {
- sLogger.severe("Failed to get report list: " + e.getMessage());
- return false;
- }
- return true;
- }
-
- // remove [CONFIG_ID]
- private static boolean cmdRemove(String[] args, int idx) {
- // Get CONFIG_ID
- long configId;
- try {
- configId = getConfigId(false, args, idx + 1);
- } catch (NumberFormatException e) {
- sLogger.severe("Invalid config id provided.");
- printHelp();
- return false;
- }
- sLogger.fine(String.format("cmdRemove with %d", configId));
-
- try {
- Utils.runCommand(null, sLogger, "adb", "shell", Utils.CMD_REMOVE_CONFIG,
- Utils.SHELL_UID, String.valueOf(configId));
- } catch (InterruptedException | IOException e) {
- sLogger.severe("Failed to remove config: " + e.getMessage());
- return false;
- }
- return true;
- }
-
- /**
- * Searches through the array to see if it contains (precisely) the given value, starting
- * at the given firstIdx.
- */
- private static boolean contains(String[] array, int firstIdx, String value) {
- if (value == null) return false;
- if (firstIdx < 0) return false;
- for (int i = firstIdx; i < array.length; i++) {
- if (value.equals(array[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the config id from args[idx], or returns DEFAULT_CONFIG_ID if args[idx] does not exist.
- * If justUseDefault, overrides and just uses DEFAULT_CONFIG_ID instead.
- */
- private static long getConfigId(boolean justUseDefault, String[] args, int idx)
- throws NumberFormatException {
- if (justUseDefault || args.length <= idx || idx < 0) {
- return DEFAULT_CONFIG_ID;
- }
- try {
- return Long.valueOf(args[idx]);
- } catch (NumberFormatException e) {
- sLogger.severe("Bad config id provided: " + args[idx]);
- throw e;
- }
- }
-}
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
deleted file mode 100644
index 51bcad115cc5..000000000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.shelltools.testdrive;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.PullAtomPackages;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.statsd.shelltools.Utils;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class TestDrive {
-
- private static final int METRIC_ID_BASE = 1111;
- private static final long ATOM_MATCHER_ID_BASE = 1234567;
- private static final long APP_BREADCRUMB_MATCHER_ID = 1111111;
- private static final int PULL_ATOM_START = 10000;
- private static final int MAX_PLATFORM_ATOM_TAG = 100000;
- private static final int VENDOR_PULLED_ATOM_START_TAG = 150000;
- private static final long CONFIG_ID = 54321;
- private static final String[] ALLOWED_LOG_SOURCES = {
- "AID_GRAPHICS",
- "AID_INCIDENTD",
- "AID_STATSD",
- "AID_RADIO",
- "com.android.systemui",
- "com.android.vending",
- "AID_SYSTEM",
- "AID_ROOT",
- "AID_BLUETOOTH",
- "AID_LMKD",
- "com.android.managedprovisioning",
- "AID_MEDIA",
- "AID_NETWORK_STACK",
- "com.google.android.providers.media.module",
- };
- private static final String[] DEFAULT_PULL_SOURCES = {
- "AID_SYSTEM",
- "AID_RADIO"
- };
- private static final Logger LOGGER = Logger.getLogger(TestDrive.class.getName());
-
- @VisibleForTesting
- String mDeviceSerial = null;
- @VisibleForTesting
- Dumper mDumper = new BasicDumper();
-
- public static void main(String[] args) {
- final Configuration configuration = new Configuration();
- final TestDrive testDrive = new TestDrive();
- Utils.setUpLogger(LOGGER, false);
-
- if (!testDrive.processArgs(configuration, args,
- Utils.getDeviceSerials(LOGGER), Utils.getDefaultDevice(LOGGER))) {
- return;
- }
-
- final ConfigMetricsReportList reports = testDrive.testDriveAndGetReports(
- configuration.createConfig(), configuration.hasPulledAtoms(),
- configuration.hasPushedAtoms());
- if (reports != null) {
- configuration.dumpMetrics(reports, testDrive.mDumper);
- }
- }
-
- boolean processArgs(Configuration configuration, String[] args, List<String> connectedDevices,
- String defaultDevice) {
- if (args.length < 1) {
- LOGGER.severe("Usage: ./test_drive [-one] "
- + "[-p additional_allowed_package] "
- + "[-s DEVICE_SERIAL_NUMBER] "
- + "<atomId1> <atomId2> ... <atomIdN>");
- return false;
- }
-
- int first_arg = 0;
- // Consume all flags, which must precede all atoms
- for (; first_arg < args.length; ++first_arg) {
- String arg = args[first_arg];
- int remaining_args = args.length - first_arg;
- if (remaining_args >= 2 && arg.equals("-one")) {
- LOGGER.info("Creating one event metric to catch all pushed atoms.");
- configuration.mOnePushedAtomEvent = true;
- } else if (remaining_args >= 2 && arg.equals("-terse")) {
- LOGGER.info("Terse output format.");
- mDumper = new TerseDumper();
- } else if (remaining_args >= 3 && arg.equals("-p")) {
- configuration.mAdditionalAllowedPackage = args[++first_arg];
- } else if (remaining_args >= 3 && arg.equals("-s")) {
- mDeviceSerial = args[++first_arg];
- } else {
- break; // Found the atom list
- }
- }
-
- mDeviceSerial = Utils.chooseDevice(mDeviceSerial, connectedDevices, defaultDevice, LOGGER);
- if (mDeviceSerial == null) {
- return false;
- }
-
- for ( ; first_arg < args.length; ++first_arg) {
- String atom = args[first_arg];
- try {
- configuration.addAtom(Integer.valueOf(atom));
- } catch (NumberFormatException e) {
- LOGGER.severe("Bad atom id provided: " + atom);
- }
- }
-
- return configuration.hasPulledAtoms() || configuration.hasPushedAtoms();
- }
-
- private ConfigMetricsReportList testDriveAndGetReports(StatsdConfig config,
- boolean hasPulledAtoms, boolean hasPushedAtoms) {
- if (config == null) {
- LOGGER.severe("Failed to create valid config.");
- return null;
- }
-
- String remoteConfigPath = null;
- try {
- remoteConfigPath = pushConfig(config, mDeviceSerial);
- LOGGER.info("Pushed the following config to statsd on device '" + mDeviceSerial
- + "':");
- LOGGER.info(config.toString());
- if (hasPushedAtoms) {
- LOGGER.info("Now please play with the device to trigger the event.");
- }
- if (!hasPulledAtoms) {
- LOGGER.info(
- "All events should be dumped after 1 min ...");
- Thread.sleep(60_000);
- } else {
- LOGGER.info("All events should be dumped after 1.5 minutes ...");
- Thread.sleep(15_000);
- Utils.logAppBreadcrumb(0, 0, LOGGER, mDeviceSerial);
- Thread.sleep(75_000);
- }
- return Utils.getReportList(CONFIG_ID, true, false, LOGGER,
- mDeviceSerial);
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "Failed to test drive: " + e.getMessage(), e);
- } finally {
- removeConfig(mDeviceSerial);
- if (remoteConfigPath != null) {
- try {
- Utils.runCommand(null, LOGGER,
- "adb", "-s", mDeviceSerial, "shell", "rm",
- remoteConfigPath);
- } catch (Exception e) {
- LOGGER.log(Level.WARNING,
- "Unable to remove remote config file: " + remoteConfigPath, e);
- }
- }
- }
- return null;
- }
-
- static class Configuration {
- boolean mOnePushedAtomEvent = false;
- @VisibleForTesting
- Set<Integer> mPushedAtoms = new TreeSet<>();
- @VisibleForTesting
- Set<Integer> mPulledAtoms = new TreeSet<>();
- @VisibleForTesting
- String mAdditionalAllowedPackage = null;
- private final Set<Long> mTrackedMetrics = new HashSet<>();
-
- private void dumpMetrics(ConfigMetricsReportList reportList, Dumper dumper) {
- // We may get multiple reports. Take the last one.
- ConfigMetricsReport report = reportList.getReports(reportList.getReportsCount() - 1);
- for (StatsLogReport statsLog : report.getMetricsList()) {
- if (isTrackedMetric(statsLog.getMetricId())) {
- dumper.dump(statsLog);
- }
- }
- }
-
- boolean isTrackedMetric(long metricId) {
- return mTrackedMetrics.contains(metricId);
- }
-
- static boolean isPulledAtom(int atomId) {
- return atomId >= PULL_ATOM_START && atomId <= MAX_PLATFORM_ATOM_TAG
- || atomId >= VENDOR_PULLED_ATOM_START_TAG;
- }
-
- void addAtom(Integer atom) {
- if (Atom.getDescriptor().findFieldByNumber(atom) == null) {
- LOGGER.severe("No such atom found: " + atom);
- return;
- }
- if (isPulledAtom(atom)) {
- mPulledAtoms.add(atom);
- } else {
- mPushedAtoms.add(atom);
- }
- }
-
- private boolean hasPulledAtoms() {
- return !mPulledAtoms.isEmpty();
- }
-
- private boolean hasPushedAtoms() {
- return !mPushedAtoms.isEmpty();
- }
-
- StatsdConfig createConfig() {
- long metricId = METRIC_ID_BASE;
- long atomMatcherId = ATOM_MATCHER_ID_BASE;
-
- StatsdConfig.Builder builder = baseBuilder();
-
- if (hasPulledAtoms()) {
- builder.addAtomMatcher(
- createAtomMatcher(
- Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- APP_BREADCRUMB_MATCHER_ID));
- }
-
- for (int atomId : mPulledAtoms) {
- builder.addAtomMatcher(createAtomMatcher(atomId, atomMatcherId));
- GaugeMetric.Builder gaugeMetricBuilder = GaugeMetric.newBuilder();
- gaugeMetricBuilder
- .setId(metricId)
- .setWhat(atomMatcherId)
- .setTriggerEvent(APP_BREADCRUMB_MATCHER_ID)
- .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build())
- .setBucket(TimeUnit.ONE_MINUTE)
- .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES)
- .setMaxNumGaugeAtomsPerBucket(100);
- builder.addGaugeMetric(gaugeMetricBuilder.build());
- atomMatcherId++;
- mTrackedMetrics.add(metricId++);
- }
-
- // A simple atom matcher for each pushed atom.
- List<AtomMatcher> simpleAtomMatchers = new ArrayList<>();
- for (int atomId : mPushedAtoms) {
- final AtomMatcher atomMatcher = createAtomMatcher(atomId, atomMatcherId++);
- simpleAtomMatchers.add(atomMatcher);
- builder.addAtomMatcher(atomMatcher);
- }
-
- if (mOnePushedAtomEvent) {
- // Create a union event metric, using an matcher that matches all pulled atoms.
- AtomMatcher unionAtomMatcher = createUnionMatcher(simpleAtomMatchers,
- atomMatcherId);
- builder.addAtomMatcher(unionAtomMatcher);
- EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder();
- eventMetricBuilder.setId(metricId).setWhat(unionAtomMatcher.getId());
- builder.addEventMetric(eventMetricBuilder.build());
- mTrackedMetrics.add(metricId++);
- } else {
- // Create multiple event metrics, one per pulled atom.
- for (AtomMatcher atomMatcher : simpleAtomMatchers) {
- EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder();
- eventMetricBuilder
- .setId(metricId)
- .setWhat(atomMatcher.getId());
- builder.addEventMetric(eventMetricBuilder.build());
- mTrackedMetrics.add(metricId++);
- }
- }
-
- return builder.build();
- }
-
- private static AtomMatcher createAtomMatcher(int atomId, long matcherId) {
- AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
- atomMatcherBuilder
- .setId(matcherId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder().setAtomId(atomId));
- return atomMatcherBuilder.build();
- }
-
- private AtomMatcher createUnionMatcher(List<AtomMatcher> simpleAtomMatchers,
- long atomMatcherId) {
- AtomMatcher.Combination.Builder combinationBuilder =
- AtomMatcher.Combination.newBuilder();
- combinationBuilder.setOperation(StatsdConfigProto.LogicalOperation.OR);
- for (AtomMatcher matcher : simpleAtomMatchers) {
- combinationBuilder.addMatcher(matcher.getId());
- }
- AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
- atomMatcherBuilder.setId(atomMatcherId).setCombination(combinationBuilder.build());
- return atomMatcherBuilder.build();
- }
-
- private StatsdConfig.Builder baseBuilder() {
- ArrayList<String> allowedSources = new ArrayList<>();
- Collections.addAll(allowedSources, ALLOWED_LOG_SOURCES);
- if (mAdditionalAllowedPackage != null) {
- allowedSources.add(mAdditionalAllowedPackage);
- }
- return StatsdConfig.newBuilder()
- .addAllAllowedLogSource(allowedSources)
- .addAllDefaultPullPackages(Arrays.asList(DEFAULT_PULL_SOURCES))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.GPU_STATS_GLOBAL_INFO_FIELD_NUMBER)
- .addPackages("AID_GPU_SERVICE"))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.GPU_STATS_APP_INFO_FIELD_NUMBER)
- .addPackages("AID_GPU_SERVICE"))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.TRAIN_INFO_FIELD_NUMBER)
- .addPackages("AID_STATSD"))
- .addPullAtomPackages(PullAtomPackages.newBuilder()
- .setAtomId(Atom.GENERAL_EXTERNAL_STORAGE_ACCESS_STATS_FIELD_NUMBER)
- .addPackages("com.google.android.providers.media.module"))
- .setHashStringsInMetricReport(false);
- }
- }
-
- interface Dumper {
- void dump(StatsLogReport report);
- }
-
- static class BasicDumper implements Dumper {
- @Override
- public void dump(StatsLogReport report) {
- System.out.println(report.toString());
- }
- }
-
- static class TerseDumper extends BasicDumper {
- @Override
- public void dump(StatsLogReport report) {
- if (report.hasGaugeMetrics()) {
- dumpGaugeMetrics(report);
- }
- if (report.hasEventMetrics()) {
- dumpEventMetrics(report);
- }
- }
- void dumpEventMetrics(StatsLogReport report) {
- final List<StatsLog.EventMetricData> data = report.getEventMetrics().getDataList();
- if (data.isEmpty()) {
- return;
- }
- long firstTimestampNanos = data.get(0).getElapsedTimestampNanos();
- for (StatsLog.EventMetricData event : data) {
- final double deltaSec = (event.getElapsedTimestampNanos() - firstTimestampNanos)
- / 1e9;
- System.out.println(
- String.format("+%.3fs: %s", deltaSec, event.getAtom().toString()));
- }
- }
- void dumpGaugeMetrics(StatsLogReport report) {
- final List<StatsLog.GaugeMetricData> data = report.getGaugeMetrics().getDataList();
- if (data.isEmpty()) {
- return;
- }
- for (StatsLog.GaugeMetricData gauge : data) {
- System.out.println(gauge.toString());
- }
- }
- }
-
- private static String pushConfig(StatsdConfig config, String deviceSerial)
- throws IOException, InterruptedException {
- File configFile = File.createTempFile("statsdconfig", ".config");
- configFile.deleteOnExit();
- Files.write(config.toByteArray(), configFile);
- String remotePath = "/data/local/tmp/" + configFile.getName();
- Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
- "push", configFile.getAbsolutePath(), remotePath);
- Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
- "shell", "cat", remotePath, "|", Utils.CMD_UPDATE_CONFIG,
- String.valueOf(CONFIG_ID));
- return remotePath;
- }
-
- private static void removeConfig(String deviceSerial) {
- try {
- Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
- "shell", Utils.CMD_REMOVE_CONFIG, String.valueOf(CONFIG_ID));
- } catch (Exception e) {
- LOGGER.severe("Failed to remove config: " + e.getMessage());
- }
- }
-}
diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java
deleted file mode 100644
index b1cc60f74993..000000000000
--- a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.statsd.shelltools.testdrive;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@link TestDrive}
- */
-public class ConfigurationTest {
-
- private StatsdConfigProto.AtomMatcher findAndRemoveAtomMatcherById(
- List<StatsdConfigProto.AtomMatcher> atomMatchers, long id) {
- int numMatches = 0;
- StatsdConfigProto.AtomMatcher match = null;
- for (StatsdConfigProto.AtomMatcher atomMatcher : atomMatchers) {
- if (id == atomMatcher.getId()) {
- ++numMatches;
- match = atomMatcher;
- }
- }
- if (numMatches == 1) {
- atomMatchers.remove(match);
- return match;
- }
- return null; // Too many, or not found
- }
-
- private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration();
-
- @Test
- public void testOnePushed() {
- final int atom = 90;
- assertFalse(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- StatsdConfig config = mConfiguration.createConfig();
-
- //event_metric {
- // id: 1111
- // what: 1234567
- //}
- //atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 90
- // }
- //}
-
- assertEquals(1, config.getEventMetricCount());
- assertEquals(0, config.getGaugeMetricCount());
-
- assertTrue(mConfiguration.isTrackedMetric(config.getEventMetric(0).getId()));
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
- assertEquals(atom,
- findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(0, atomMatchers.size());
- }
-
- @Test
- public void testOnePulled() {
- final int atom = 10022;
- assertTrue(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- StatsdConfig config = mConfiguration.createConfig();
-
- //gauge_metric {
- // id: 1111
- // what: 1234567
- // gauge_fields_filter {
- // include_all: true
- // }
- // bucket: ONE_MINUTE
- // sampling_type: FIRST_N_SAMPLES
- // max_num_gauge_atoms_per_bucket: 100
- // trigger_event: 1111111
- //}
- //atom_matcher {
- // id: 1111111
- // simple_atom_matcher {
- // atom_id: 47
- // }
- //}
- //atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 10022
- // }
- //}
-
- assertEquals(0, config.getEventMetricCount());
- assertEquals(1, config.getGaugeMetricCount());
-
- assertTrue(mConfiguration.isTrackedMetric(config.getGaugeMetric(0).getId()));
-
- final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
- assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
- assertEquals(atom,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(0, atomMatchers.size());
- }
-
- @Test
- public void testOnePulledTwoPushed() {
- final int pulledAtom = 10022;
- assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom));
- mConfiguration.addAtom(pulledAtom);
-
- Integer[] pushedAtoms = new Integer[]{244, 245};
- for (int atom : pushedAtoms) {
- assertFalse(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- }
- StatsdConfig config = mConfiguration.createConfig();
-
- // event_metric {
- // id: 1111
- // what: 1234567
- // }
- // event_metric {
- // id: 1112
- // what: 1234568
- // }
- // gauge_metric {
- // id: 1114
- // what: 1234570
- // gauge_fields_filter {
- // include_all: true
- // }
- // bucket: ONE_MINUTE
- // sampling_type: FIRST_N_SAMPLES
- // max_num_gauge_atoms_per_bucket: 100
- // trigger_event: 1111111
- // }
- // atom_matcher {
- // id: 1111111
- // simple_atom_matcher {
- // atom_id: 47
- // }
- // }
- // atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 244
- // }
- // }
- // atom_matcher {
- // id: 1234568
- // simple_atom_matcher {
- // atom_id: 245
- // }
- // }
- // atom_matcher {
- // id: 1234570
- // simple_atom_matcher {
- // atom_id: 10022
- // }
- // }
-
- assertEquals(2, config.getEventMetricCount());
- assertEquals(1, config.getGaugeMetricCount());
-
- final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
- assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId()));
- assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
- for (StatsdConfigProto.EventMetric eventMetric : config.getEventMetricList()) {
- assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId()));
- }
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
-
- assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
- .getSimpleAtomMatcher().getAtomId());
-
- Integer[] actualAtoms = new Integer[]{
- findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat())
- .getSimpleAtomMatcher().getAtomId(),
- findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(1).getWhat())
- .getSimpleAtomMatcher().getAtomId()};
- Arrays.sort(actualAtoms);
- assertArrayEquals(pushedAtoms, actualAtoms);
-
- assertEquals(0, atomMatchers.size());
- }
-
- @Test
- public void testOnePulledTwoPushedTogether() {
- mConfiguration.mOnePushedAtomEvent = true; // Use one event grabbing all pushed atoms
-
- final int pulledAtom = 10022;
- assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom));
- mConfiguration.addAtom(pulledAtom);
-
- Integer[] pushedAtoms = new Integer[]{244, 245};
- for (int atom : pushedAtoms) {
- assertFalse(TestDrive.Configuration.isPulledAtom(atom));
- mConfiguration.addAtom(atom);
- }
- StatsdConfig config = mConfiguration.createConfig();
-
- // event_metric {
- // id: 1112
- // what: 1234570
- // }
- // gauge_metric {
- // id: 1111
- // what: 1234567
- // gauge_fields_filter {
- // include_all: true
- // }
- // bucket: ONE_MINUTE
- // sampling_type: FIRST_N_SAMPLES
- // max_num_gauge_atoms_per_bucket: 100
- // trigger_event: 1111111
- // }
- // atom_matcher {
- // id: 1111111
- // simple_atom_matcher {
- // atom_id: 47
- // }
- // }
- // atom_matcher {
- // id: 1234567
- // simple_atom_matcher {
- // atom_id: 10022
- // }
- // }
- // atom_matcher {
- // id: 1234568
- // simple_atom_matcher {
- // atom_id: 244
- // }
- // }
- // atom_matcher {
- // id: 1234569
- // simple_atom_matcher {
- // atom_id: 245
- // }
- // }
- // atom_matcher {
- // id: 1234570
- // combination {
- // operation: OR
- // matcher: 1234568
- // matcher: 1234569
- // }
- // }
-
- assertEquals(1, config.getEventMetricCount());
- assertEquals(1, config.getGaugeMetricCount());
-
- final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
- assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId()));
- assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-
- StatsdConfigProto.EventMetric eventMetric = config.getEventMetric(0);
- assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId()));
-
- final List<StatsdConfigProto.AtomMatcher> atomMatchers =
- new ArrayList<>(config.getAtomMatcherList());
-
- assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
- .getSimpleAtomMatcher().getAtomId());
- assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
- findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
- .getSimpleAtomMatcher().getAtomId());
-
- StatsdConfigProto.AtomMatcher unionMatcher = findAndRemoveAtomMatcherById(atomMatchers,
- eventMetric.getWhat());
- assertNotNull(unionMatcher.getCombination());
- assertEquals(2, unionMatcher.getCombination().getMatcherCount());
-
- Integer[] actualAtoms = new Integer[]{
- findAndRemoveAtomMatcherById(atomMatchers,
- unionMatcher.getCombination().getMatcher(0))
- .getSimpleAtomMatcher().getAtomId(),
- findAndRemoveAtomMatcherById(atomMatchers,
- unionMatcher.getCombination().getMatcher(1))
- .getSimpleAtomMatcher().getAtomId()};
- Arrays.sort(actualAtoms);
- assertArrayEquals(pushedAtoms, actualAtoms);
-
- assertEquals(0, atomMatchers.size());
- }
-}
diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java
deleted file mode 100644
index 363fac0c78ba..000000000000
--- a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.statsd.shelltools.testdrive;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link TestDrive}
- */
-@RunWith(Parameterized.class)
-public class TestDriveTest {
- /**
- * Expected results of a single iteration of the paramerized test.
- */
- static class Expect {
- public boolean success;
- public Integer[] atoms;
- public boolean onePushedAtomEvent = false;
- public String extraPackage = null;
- public String target;
- public boolean terse = false;
-
- static Expect success(Integer... atoms) {
- return new Expect(true, atoms,
- TARGET);
- }
- Expect(boolean success, Integer[] atoms, String target) {
- this.success = success;
- this.atoms = atoms;
- this.target = target;
- }
- static final Expect FAILURE = new Expect(false, null, null);
- Expect onePushedAtomEvent() {
- this.onePushedAtomEvent = true;
- return this;
- }
- Expect extraPackage() {
- this.extraPackage = TestDriveTest.PACKAGE;
- return this;
- }
- Expect terse() {
- this.terse = true;
- return this;
- }
- }
-
- @Parameterized.Parameter(0)
- public String[] mArgs;
-
- @Parameterized.Parameter(1)
- public List<String> mConnectedDevices;
-
- @Parameterized.Parameter(2)
- public String mDefaultDevice;
-
- @Parameterized.Parameter(3)
- public Expect mExpect;
-
- private static final String TARGET = "target";
- private static final List<String> TARGET_AND_OTHER = Arrays.asList("otherDevice",
- TARGET);
- private static final List<String> TWO_OTHER_DEVICES = Arrays.asList(
- "other1", "other2");
- private static final List<String> TARGET_ONLY = Collections.singletonList(TARGET);
- private static final List<String> NOT_TARGET = Collections.singletonList("other");
- private static final List<String> NO_DEVICES = Collections.emptyList();
- private static final String PACKAGE = "extraPackage";
-
- @Parameterized.Parameters
- public static Collection<Object[]> data() {
- return Arrays.asList(
- new Object[]{new String[]{}, null, null,
- Expect.FAILURE}, // Usage explanation
- new Object[]{new String[]{"244", "245"}, null, null,
- Expect.FAILURE}, // Failure looking up connected devices
- new Object[]{new String[]{"244", "245"}, NO_DEVICES, null,
- Expect.FAILURE}, // No connected devices
- new Object[]{new String[]{"-s", TARGET, "244", "245"}, NOT_TARGET, null,
- Expect.FAILURE}, // Wrong device connected
- new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, null,
- Expect.FAILURE}, // Wrong devices connected
- new Object[]{new String[]{"244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245)}, // If only one device connected, guess that one
- new Object[]{new String[]{"244", "not_an_atom"}, TARGET_ONLY, null,
- Expect.success(244)}, // Ignore non-atoms
- new Object[]{new String[]{"not_an_atom"}, TARGET_ONLY, null,
- Expect.FAILURE}, // Require at least one atom
- new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, TARGET,
- Expect.FAILURE}, // ANDROID_SERIAL specifies non-connected target
- new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, TARGET,
- Expect.success(244, 245)}, // ANDROID_SERIAL specifies a valid target
- new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, null,
- Expect.FAILURE}, // Two connected devices, no indication of which to use
- new Object[]{new String[]{"-one", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).onePushedAtomEvent()},
- new Object[]{new String[]{"-terse", "-one", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-terse", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-p", PACKAGE, "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).extraPackage()},
- new Object[]{new String[]{"-p", PACKAGE, "-one", "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "244", "245"}, TARGET_ONLY, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-s", TARGET, "-one", "-p", PACKAGE, "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-one", "-s", TARGET, "-p", PACKAGE, "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
- new Object[]{new String[]{"-terse", "-one", "-p", PACKAGE, "-s", TARGET,
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-terse", "-p", PACKAGE, "-s", TARGET,
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "-terse", "-s", TARGET,
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
- new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "-terse",
- "244", "245"},
- TARGET_AND_OTHER, null,
- Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()}
- );
- }
-
- private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration();
- private final TestDrive mTestDrive = new TestDrive();
-
- private static Integer[] collectAtoms(TestDrive.Configuration configuration) {
- Integer[] result = new Integer[configuration.mPulledAtoms.size()
- + configuration.mPushedAtoms.size()];
- int result_index = 0;
- for (Integer atom : configuration.mPushedAtoms) {
- result[result_index++] = atom;
- }
- for (Integer atom : configuration.mPulledAtoms) {
- result[result_index++] = atom;
- }
- Arrays.sort(result);
- return result;
- }
-
- @Test
- public void testProcessArgs() {
- boolean result = mTestDrive.processArgs(mConfiguration, mArgs, mConnectedDevices,
- mDefaultDevice);
- if (mExpect.success) {
- assertTrue(result);
- assertArrayEquals(mExpect.atoms, collectAtoms(mConfiguration));
- assertEquals(mExpect.onePushedAtomEvent, mConfiguration.mOnePushedAtomEvent);
- assertEquals(mExpect.target, mTestDrive.mDeviceSerial);
- if (mExpect.terse) {
- assertEquals(TestDrive.TerseDumper.class, mTestDrive.mDumper.getClass());
- } else {
- assertEquals(TestDrive.BasicDumper.class, mTestDrive.mDumper.getClass());
- }
- } else {
- assertFalse(result);
- }
- }
-}
diff --git a/cmds/statsd/tools/localtools/testdrive_manifest.txt b/cmds/statsd/tools/localtools/testdrive_manifest.txt
deleted file mode 100644
index 625ebfa4312a..000000000000
--- a/cmds/statsd/tools/localtools/testdrive_manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: com.android.statsd.shelltools.testdrive.TestDrive
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 3772755beca1..e123af728b20 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5195,8 +5195,8 @@ public class Activity extends ContextThemeWrapper
* result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
* </p>
* <p>
- * The <a href="https://github.com/googlesamples/android-RuntimePermissions">
- * RuntimePermissions</a> sample app demonstrates how to use this method to
+ * The <a href="https://github.com/android/permissions-samples">
+ * RuntimePermissions</a> sample apps demonstrate how to use this method to
* request permissions at run time.
* </p>
*
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index d2a15357aa1f..735980beebb1 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -51,19 +51,25 @@ public final class BluetoothCodecConfig implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface SourceCodecType {}
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_SBC = 0;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_AAC = 1;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_APTX = 2;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_LDAC = 4;
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_MAX = 5;
-
+ @UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
/** @hide */
@@ -75,10 +81,13 @@ public final class BluetoothCodecConfig implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface CodecPriority {}
+ @UnsupportedAppUsage
public static final int CODEC_PRIORITY_DISABLED = -1;
+ @UnsupportedAppUsage
public static final int CODEC_PRIORITY_DEFAULT = 0;
+ @UnsupportedAppUsage
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
@@ -95,18 +104,25 @@ public final class BluetoothCodecConfig implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface SampleRate {}
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_NONE = 0;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_44100 = 0x1 << 0;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_48000 = 0x1 << 1;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_88200 = 0x1 << 2;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_96000 = 0x1 << 3;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_176400 = 0x1 << 4;
+ @UnsupportedAppUsage
public static final int SAMPLE_RATE_192000 = 0x1 << 5;
@@ -120,12 +136,16 @@ public final class BluetoothCodecConfig implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface BitsPerSample {}
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_NONE = 0;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
+ @UnsupportedAppUsage
public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
@@ -138,10 +158,13 @@ public final class BluetoothCodecConfig implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface ChannelMode {}
+ @UnsupportedAppUsage
public static final int CHANNEL_MODE_NONE = 0;
+ @UnsupportedAppUsage
public static final int CHANNEL_MODE_MONO = 0x1 << 0;
+ @UnsupportedAppUsage
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
private final @SourceCodecType int mCodecType;
@@ -154,6 +177,7 @@ public final class BluetoothCodecConfig implements Parcelable {
private final long mCodecSpecific3;
private final long mCodecSpecific4;
+ @UnsupportedAppUsage
public BluetoothCodecConfig(@SourceCodecType int codecType, @CodecPriority int codecPriority,
@SampleRate int sampleRate, @BitsPerSample int bitsPerSample,
@ChannelMode int channelMode, long codecSpecific1,
@@ -170,6 +194,7 @@ public final class BluetoothCodecConfig implements Parcelable {
mCodecSpecific4 = codecSpecific4;
}
+ @UnsupportedAppUsage
public BluetoothCodecConfig(@SourceCodecType int codecType) {
mCodecType = codecType;
mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
@@ -391,6 +416,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec type
*/
+ @UnsupportedAppUsage
public @SourceCodecType int getCodecType() {
return mCodecType;
}
@@ -411,6 +437,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec priority
*/
+ @UnsupportedAppUsage
public @CodecPriority int getCodecPriority() {
return mCodecPriority;
}
@@ -441,6 +468,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec sample rate
*/
+ @UnsupportedAppUsage
public @SampleRate int getSampleRate() {
return mSampleRate;
}
@@ -455,6 +483,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return the codec bits per sample
*/
+ @UnsupportedAppUsage
public @BitsPerSample int getBitsPerSample() {
return mBitsPerSample;
}
@@ -479,6 +508,7 @@ public final class BluetoothCodecConfig implements Parcelable {
*
* @return a codec specific value1.
*/
+ @UnsupportedAppUsage
public long getCodecSpecific1() {
return mCodecSpecific1;
}
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
index 1e394b830d51..7b567b4098e7 100644
--- a/core/java/android/bluetooth/BluetoothCodecStatus.java
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.java
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,6 +39,7 @@ public final class BluetoothCodecStatus implements Parcelable {
* This extra represents the current codec status of the A2DP
* profile.
*/
+ @UnsupportedAppUsage
public static final String EXTRA_CODEC_STATUS =
"android.bluetooth.extra.CODEC_STATUS";
@@ -196,6 +198,7 @@ public final class BluetoothCodecStatus implements Parcelable {
*
* @return the current codec configuration
*/
+ @UnsupportedAppUsage
public @Nullable BluetoothCodecConfig getCodecConfig() {
return mCodecConfig;
}
@@ -205,6 +208,7 @@ public final class BluetoothCodecStatus implements Parcelable {
*
* @return an array with the codecs local capabilities
*/
+ @UnsupportedAppUsage
public @Nullable BluetoothCodecConfig[] getCodecsLocalCapabilities() {
return mCodecsLocalCapabilities;
}
@@ -214,6 +218,7 @@ public final class BluetoothCodecStatus implements Parcelable {
*
* @return an array with the codecs selectable capabilities
*/
+ @UnsupportedAppUsage
public @Nullable BluetoothCodecConfig[] getCodecsSelectableCapabilities() {
return mCodecsSelectableCapabilities;
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6f93e51a9a86..ed7766351053 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -92,6 +92,11 @@ import java.util.Set;
* packages that are currently installed on the device.
*
* You can find this class through {@link Context#getPackageManager}.
+ *
+ * <p class="note"><strong>Note: </strong>If your app targets Android 11 (API level 30) or
+ * higher, the methods in this class each return a filtered list of apps. Learn more about how to
+ * <a href="/training/basics/intents/package-visibility">manage package visibility</a>.
+ * </p>
*/
public abstract class PackageManager {
private static final String TAG = "PackageManager";
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index cd137078818c..37e12809467d 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -234,7 +234,7 @@ public abstract class CameraDevice implements AutoCloseable {
* @see StreamConfigurationMap#getOutputFormats()
* @see StreamConfigurationMap#getOutputSizes(int)
* @see StreamConfigurationMap#getOutputSizes(Class)
- * @deprecated Please use @{link
+ * @deprecated Please use {@link
* #createCaptureSession(android.hardware.camera2.params.SessionConfiguration)} for the
* full set of configuration options available.
*/
@@ -249,7 +249,7 @@ public abstract class CameraDevice implements AutoCloseable {
*
* @see #createCaptureSession
* @see OutputConfiguration
- * @deprecated Please use @{link
+ * @deprecated Please use {@link
* #createCaptureSession(android.hardware.camera2.params.SessionConfiguration)} for the
* full set of configuration options available.
*/
@@ -285,7 +285,7 @@ public abstract class CameraDevice implements AutoCloseable {
* @see StreamConfigurationMap#getOutputSizes
* @see android.media.ImageWriter
* @see android.media.ImageReader
- * @deprecated Please use @{link
+ * @deprecated Please use {@link
* #createCaptureSession(android.hardware.camera2.params.SessionConfiguration)} for the
* full set of configuration options available.
*/
@@ -302,7 +302,7 @@ public abstract class CameraDevice implements AutoCloseable {
*
* @see #createReprocessableCaptureSession
* @see OutputConfiguration
- * @deprecated Please use @{link
+ * @deprecated Please use {@link
* #createCaptureSession(android.hardware.camera2.params.SessionConfiguration)} for the
* full set of configuration options available.
*/
@@ -340,7 +340,7 @@ public abstract class CameraDevice implements AutoCloseable {
* @see CameraCaptureSession#captureBurst
* @see CameraCaptureSession#setRepeatingBurst
* @see CameraConstrainedHighSpeedCaptureSession#createHighSpeedRequestList
- * @deprecated Please use @{link
+ * @deprecated Please use {@link
* #createCaptureSession(android.hardware.camera2.params.SessionConfiguration)} for the
* full set of configuration options available.
*/
@@ -413,7 +413,7 @@ public abstract class CameraDevice implements AutoCloseable {
* @see #createReprocessableCaptureSession
* @see CameraCaptureSession
* @see OutputConfiguration
- * @deprecated Please use @{link
+ * @deprecated Please use {@link
* #createCaptureSession(android.hardware.camera2.params.SessionConfiguration)} for the
* full set of configuration options available.
* @hide
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 616ccbe50213..9b2ef7c7f1f2 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -20,12 +20,13 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.LinkPropertiesUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import com.android.net.module.util.LinkPropertiesUtils;
+
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 0eb3c1e8ad01..51c5a50dcafb 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -20,12 +20,12 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.MacAddressUtils;
import android.net.wifi.WifiInfo;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
+import com.android.net.module.util.MacAddressUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 62aebb01805c..d53a0b151326 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -21,11 +21,12 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.NetUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.net.module.util.NetUtils;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.Inet4Address;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index bde332792e18..018bb2c9f9b2 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -135,8 +135,8 @@ public class Build {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 233231cfcfdf..fadc15912dc1 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1210,25 +1210,6 @@ public class ResolverActivity extends Activity implements
if (TextUtils.isEmpty(packageName)) {
pm.setDefaultBrowserPackageNameAsUser(ri.activityInfo.packageName, userId);
}
- } else {
- // Update Domain Verification status
- ComponentName cn = intent.getComponent();
- String packageName = cn.getPackageName();
- String dataScheme = (data != null) ? data.getScheme() : null;
-
- boolean isHttpOrHttps = (dataScheme != null) &&
- (dataScheme.equals(IntentFilter.SCHEME_HTTP) ||
- dataScheme.equals(IntentFilter.SCHEME_HTTPS));
-
- boolean isViewAction = (action != null) && action.equals(Intent.ACTION_VIEW);
- boolean hasCategoryBrowsable = (categories != null) &&
- categories.contains(Intent.CATEGORY_BROWSABLE);
-
- if (isHttpOrHttps && isViewAction && hasCategoryBrowsable) {
- pm.updateIntentVerificationStatusAsUser(packageName,
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
- userId);
- }
}
} else {
try {
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a50a52219c74..3b5fecfc600a 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -113,6 +113,14 @@ public abstract class FileSystemProvider extends DocumentsProvider {
// Default is no-op
}
+ /**
+ * Callback indicating that the given document has been deleted or moved. This gives
+ * the provider a hook to revoke the uri permissions.
+ */
+ protected void onDocIdDeleted(String docId) {
+ // Default is no-op
+ }
+
@Override
public boolean onCreate() {
throw new UnsupportedOperationException(
@@ -283,6 +291,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
final String afterDocId = getDocIdForFile(after);
onDocIdChanged(docId);
+ onDocIdDeleted(docId);
onDocIdChanged(afterDocId);
final File afterVisibleFile = getFileForDocId(afterDocId, true);
@@ -312,6 +321,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
final String docId = getDocIdForFile(after);
onDocIdChanged(sourceDocumentId);
+ onDocIdDeleted(sourceDocumentId);
onDocIdChanged(docId);
moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
@@ -343,6 +353,7 @@ public abstract class FileSystemProvider extends DocumentsProvider {
}
onDocIdChanged(docId);
+ onDocIdDeleted(docId);
removeFromMediaStore(visibleFile);
}
diff --git a/core/proto/Android.bp b/core/proto/Android.bp
deleted file mode 100644
index 3b891d6b4947..000000000000
--- a/core/proto/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// C++ library for Bluetooth platform wide protobuf definitions
-cc_library_static {
- name: "libbt-platform-protos-lite",
- host_supported: true,
- proto: {
- export_proto_headers: true,
- type: "lite",
- },
- srcs: [
- "android/bluetooth/a2dp/enums.proto",
- "android/bluetooth/enums.proto",
- "android/bluetooth/hci/enums.proto",
- "android/bluetooth/hfp/enums.proto",
- "android/bluetooth/smp/enums.proto",
- ],
-}
diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto
deleted file mode 100644
index bd5cb62f7fde..000000000000
--- a/core/proto/android/app/enums.proto
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app;
-
-option java_outer_classname = "AppProtoEnums";
-option java_multiple_files = true;
-
-// ActivityManagerInternal.java's APP_TRANSITION reasons.
-enum AppTransitionReasonEnum {
- APP_TRANSITION_REASON_UNKNOWN = 0;
- // The transition was started because we drew the splash screen.
- APP_TRANSITION_SPLASH_SCREEN = 1;
- // The transition was started because we all app windows were drawn.
- APP_TRANSITION_WINDOWS_DRAWN = 2;
- // The transition was started because of a timeout.
- APP_TRANSITION_TIMEOUT = 3;
- // The transition was started because of a we drew a task snapshot.
- APP_TRANSITION_SNAPSHOT = 4;
- // The transition was started because it was a recents animation and we only needed to wait on
- // the wallpaper.
- APP_TRANSITION_RECENTS_ANIM = 5;
-}
-
-// ActivityManager.java PROCESS_STATEs
-// Next tag: 1021
-enum ProcessStateEnum {
- // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values
- // here are completely fixed and arbitrary. Order is irrelevant.
- // No attempt need be made to keep them in sync.
- // The values here must not be modified. Any new process states can be appended to the end.
-
- // Process state that is unknown to this proto file (i.e. is not mapped
- // by ActivityManager.processStateAmToProto()). Can only happen if there's a bug in the mapping.
- PROCESS_STATE_UNKNOWN_TO_PROTO = 998;
- // Not a real process state.
- PROCESS_STATE_UNKNOWN = 999;
- // Process is a persistent system process.
- PROCESS_STATE_PERSISTENT = 1000;
- // Process is a persistent system process and is doing UI.
- PROCESS_STATE_PERSISTENT_UI = 1001;
- // Process is hosting the current top activities. Note that this covers
- // all activities that are visible to the user.
- PROCESS_STATE_TOP = 1002;
- // Process is bound to a TOP app.
- PROCESS_STATE_BOUND_TOP = 1020;
- // Process is hosting a foreground service.
- PROCESS_STATE_FOREGROUND_SERVICE = 1003;
- // Process is hosting a service bound by the system or another foreground app.
- PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004;
- // Process is important to the user, and something they are aware of.
- PROCESS_STATE_IMPORTANT_FOREGROUND = 1005;
- // Process is important to the user, but not something they are aware of.
- PROCESS_STATE_IMPORTANT_BACKGROUND = 1006;
- // Process is in the background transient so we will try to keep running.
- PROCESS_STATE_TRANSIENT_BACKGROUND = 1007;
- // Process is in the background running a backup/restore operation.
- PROCESS_STATE_BACKUP = 1008;
- // Process is in the background running a service. Unlike oom_adj, this
- // level is used for both the normal running in background state and the
- // executing operations state.
- PROCESS_STATE_SERVICE = 1009;
- // Process is in the background running a receiver. Note that from the
- // perspective of oom_adj, receivers run at a higher foreground level, but
- // for our prioritization here that is not necessary and putting them
- // below services means many fewer changes in some process states as they
- // receive broadcasts.
- PROCESS_STATE_RECEIVER = 1010;
- // Same as PROCESS_STATE_TOP but while device is sleeping.
- PROCESS_STATE_TOP_SLEEPING = 1011;
- // Process is in the background, but it can't restore its state so we want
- // to try to avoid killing it.
- PROCESS_STATE_HEAVY_WEIGHT = 1012;
- // Process is in the background but hosts the home activity.
- PROCESS_STATE_HOME = 1013;
- // Process is in the background but hosts the last shown activity.
- PROCESS_STATE_LAST_ACTIVITY = 1014;
- // Process is being cached for later use and contains activities.
- PROCESS_STATE_CACHED_ACTIVITY = 1015;
- // Process is being cached for later use and is a client of another cached
- // process that contains activities.
- PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 1016;
- // Process is being cached for later use and has an activity that corresponds
- // to an existing recent task.
- PROCESS_STATE_CACHED_RECENT = 1017;
- // Process is being cached for later use and is empty.
- PROCESS_STATE_CACHED_EMPTY = 1018;
- // Process does not exist.
- PROCESS_STATE_NONEXISTENT = 1019;
-}
-
-// AppOpsManager.java - operation ids for logging
-enum AppOpEnum {
- APP_OP_NONE = -1;
- APP_OP_COARSE_LOCATION = 0;
- APP_OP_FINE_LOCATION = 1;
- APP_OP_GPS = 2;
- APP_OP_VIBRATE = 3;
- APP_OP_READ_CONTACTS = 4;
- APP_OP_WRITE_CONTACTS = 5;
- APP_OP_READ_CALL_LOG = 6;
- APP_OP_WRITE_CALL_LOG = 7;
- APP_OP_READ_CALENDAR = 8;
- APP_OP_WRITE_CALENDAR = 9;
- APP_OP_WIFI_SCAN = 10;
- APP_OP_POST_NOTIFICATION = 11;
- APP_OP_NEIGHBORING_CELLS = 12;
- APP_OP_CALL_PHONE = 13;
- APP_OP_READ_SMS = 14;
- APP_OP_WRITE_SMS = 15;
- APP_OP_RECEIVE_SMS = 16;
- APP_OP_RECEIVE_EMERGENCY_SMS = 17;
- APP_OP_RECEIVE_MMS = 18;
- APP_OP_RECEIVE_WAP_PUSH = 19;
- APP_OP_SEND_SMS = 20;
- APP_OP_READ_ICC_SMS = 21;
- APP_OP_WRITE_ICC_SMS = 22;
- APP_OP_WRITE_SETTINGS = 23;
- APP_OP_SYSTEM_ALERT_WINDOW = 24;
- APP_OP_ACCESS_NOTIFICATIONS = 25;
- APP_OP_CAMERA = 26;
- APP_OP_RECORD_AUDIO = 27;
- APP_OP_PLAY_AUDIO = 28;
- APP_OP_READ_CLIPBOARD = 29;
- APP_OP_WRITE_CLIPBOARD = 30;
- APP_OP_TAKE_MEDIA_BUTTONS = 31;
- APP_OP_TAKE_AUDIO_FOCUS = 32;
- APP_OP_AUDIO_MASTER_VOLUME = 33;
- APP_OP_AUDIO_VOICE_VOLUME = 34;
- APP_OP_AUDIO_RING_VOLUME = 35;
- APP_OP_AUDIO_MEDIA_VOLUME = 36;
- APP_OP_AUDIO_ALARM_VOLUME = 37;
- APP_OP_AUDIO_NOTIFICATION_VOLUME = 38;
- APP_OP_AUDIO_BLUETOOTH_VOLUME = 39;
- APP_OP_WAKE_LOCK = 40;
- APP_OP_MONITOR_LOCATION = 41;
- APP_OP_MONITOR_HIGH_POWER_LOCATION = 42;
- APP_OP_GET_USAGE_STATS = 43;
- APP_OP_MUTE_MICROPHONE = 44;
- APP_OP_TOAST_WINDOW = 45;
- APP_OP_PROJECT_MEDIA = 46;
- APP_OP_ACTIVATE_VPN = 47;
- APP_OP_WRITE_WALLPAPER = 48;
- APP_OP_ASSIST_STRUCTURE = 49;
- APP_OP_ASSIST_SCREENSHOT = 50;
- APP_OP_READ_PHONE_STATE = 51;
- APP_OP_ADD_VOICEMAIL = 52;
- APP_OP_USE_SIP = 53;
- APP_OP_PROCESS_OUTGOING_CALLS = 54;
- APP_OP_USE_FINGERPRINT = 55;
- APP_OP_BODY_SENSORS = 56;
- APP_OP_READ_CELL_BROADCASTS = 57;
- APP_OP_MOCK_LOCATION = 58;
- APP_OP_READ_EXTERNAL_STORAGE = 59;
- APP_OP_WRITE_EXTERNAL_STORAGE = 60;
- APP_OP_TURN_SCREEN_ON = 61;
- APP_OP_GET_ACCOUNTS = 62;
- APP_OP_RUN_IN_BACKGROUND = 63;
- APP_OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
- APP_OP_READ_PHONE_NUMBERS = 65;
- APP_OP_REQUEST_INSTALL_PACKAGES = 66;
- APP_OP_PICTURE_IN_PICTURE = 67;
- APP_OP_INSTANT_APP_START_FOREGROUND = 68;
- APP_OP_ANSWER_PHONE_CALLS = 69;
- APP_OP_RUN_ANY_IN_BACKGROUND = 70;
- APP_OP_CHANGE_WIFI_STATE = 71;
- APP_OP_REQUEST_DELETE_PACKAGES = 72;
- APP_OP_BIND_ACCESSIBILITY_SERVICE = 73;
- APP_OP_ACCEPT_HANDOVER = 74;
- APP_OP_MANAGE_IPSEC_TUNNELS = 75;
- APP_OP_START_FOREGROUND = 76;
- APP_OP_BLUETOOTH_SCAN = 77;
- APP_OP_USE_BIOMETRIC = 78;
- APP_OP_ACTIVITY_RECOGNITION = 79;
- APP_OP_SMS_FINANCIAL_TRANSACTIONS = 80;
- APP_OP_READ_MEDIA_AUDIO = 81;
- APP_OP_WRITE_MEDIA_AUDIO = 82;
- APP_OP_READ_MEDIA_VIDEO = 83;
- APP_OP_WRITE_MEDIA_VIDEO = 84;
- APP_OP_READ_MEDIA_IMAGES = 85;
- APP_OP_WRITE_MEDIA_IMAGES = 86;
- APP_OP_LEGACY_STORAGE = 87;
- APP_OP_ACCESS_ACCESSIBILITY = 88;
- APP_OP_READ_DEVICE_IDENTIFIERS = 89;
- APP_OP_ACCESS_MEDIA_LOCATION = 90;
- APP_OP_QUERY_ALL_PACKAGES = 91;
- APP_OP_MANAGE_EXTERNAL_STORAGE = 92;
- APP_OP_INTERACT_ACROSS_PROFILES = 93;
- APP_OP_ACTIVATE_PLATFORM_VPN = 94;
- APP_OP_LOADER_USAGE_STATS = 95;
- APP_OP_DEPRECATED_1 = 96 [deprecated = true];
- APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
- APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
- APP_OP_NO_ISOLATED_STORAGE = 99;
-}
diff --git a/core/proto/android/app/job/enums.proto b/core/proto/android/app/job/enums.proto
deleted file mode 100644
index 41863bbbfbf1..000000000000
--- a/core/proto/android/app/job/enums.proto
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.job;
-
-// This file is for JobScheduler enums inside the app directory. If you're
-// adding enums for system-server-side code, use the file in
-// frameworks/base/core/proto/android/server/job.
-option java_outer_classname = "JobProtoEnums";
-option java_multiple_files = true;
-
-// Reasons a job is stopped.
-// Primarily used in android.app.job.JobParameters.java.
-enum StopReasonEnum {
- STOP_REASON_UNKNOWN = -1;
- STOP_REASON_CANCELLED = 0;
- STOP_REASON_CONSTRAINTS_NOT_SATISFIED = 1;
- STOP_REASON_PREEMPT = 2;
- STOP_REASON_TIMEOUT = 3;
- STOP_REASON_DEVICE_IDLE = 4;
- STOP_REASON_DEVICE_THERMAL = 5;
- STOP_REASON_RESTRICTED_BUCKET = 6;
-}
diff --git a/core/proto/android/app/media_output_enum.proto b/core/proto/android/app/media_output_enum.proto
deleted file mode 100644
index 0d42fb77025a..000000000000
--- a/core/proto/android/app/media_output_enum.proto
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.settings.mediaoutput;
-option java_multiple_files = true;
-
-/**
- * The medium type specified in an output switching operation.
- */
-enum MediumType {
- UNKNOWN_TYPE = 0;
- BUILTIN_SPEAKER = 1;
- WIRED_3POINT5_MM_AUDIO = 100;
- WIRED_3POINT5_MM_HEADSET = 101;
- WIRED_3POINT5_MM_HEADPHONES = 102;
- USB_C_AUDIO = 200;
- USB_C_DEVICE = 201;
- USB_C_HEADSET = 202;
- USB_C_ACCESSORY = 203;
- USB_C_DOCK = 204;
- USB_C_HDMI = 205;
- BLUETOOTH = 300;
- BLUETOOTH_HEARING_AID = 301;
- BLUETOOTH_A2DP = 302;
- REMOTE_SINGLE = 400;
- REMOTE_TV = 401;
- REMOTE_SPEAKER = 402;
- REMOTE_GROUP = 500;
- REMOTE_DYNAMIC_GROUP = 501;
-};
-
-/**
- * The result of an output switching operation.
- */
-enum SwitchResult {
- ERROR = 0;
- OK = 1;
-};
-
-/**
- * The sub result of an output switching operation.
- */
-enum SubResult {
- UNKNOWN_ERROR = 0;
- NO_ERROR = 1;
- REJECTED = 2;
- NETWORK_ERROR = 3;
- ROUTE_NOT_AVAILABLE = 4;
- INVALID_COMMAND = 5;
-}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
deleted file mode 100644
index 69b32c264d3d..000000000000
--- a/core/proto/android/app/settings_enums.proto
+++ /dev/null
@@ -1,2686 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.settings;
-option java_multiple_files = true;
-
-/**
- * The action performed in this event
- */
-enum Action {
- ACTION_UNKNOWN = 0;
- PAGE_VISIBLE = 1;
- PAGE_HIDE = 2;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network
- // SUBTYPE: true if connecting to a saved network, false if not
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_CONNECT = 135;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Forget network
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_FORGET = 137;
-
- // ACTION: Settings > Wi-Fi > Toggle off
- // SUBTYPE: true if connected to network before toggle, false if not
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_OFF = 138;
-
- // ACTION: Settings > Wi-Fi > Toggle on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_ON = 139;
-
- // ACTION: Settings > Bluetooth > Overflow > Rename this device
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_BLUETOOTH_RENAME = 161;
-
- // ACTION: Settings > Bluetooth > Overflow > Show received files
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_BLUETOOTH_FILES = 162;
-
- // ACTION: DND Settings > Priority only allows > Reminder toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_REMINDERS = 167;
-
- // ACTION: DND Settings > Priority only allows > Event toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_EVENTS = 168;
-
- // ACTION: DND Settings > Priority only allows > Messages
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_MESSAGES = 169;
-
- // ACTION: DND Settings > Priority only allows > Calls
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_CALLS = 170;
-
- // ACTION: DND Settings > Priority only allows > Repeat callers toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
-
- // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_DELETE_RULE_OK = 175;
-
- // ACTION: Settings > More > Airplane mode toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_AIRPLANE_TOGGLE = 177;
-
- // ACTION: Settings > Data usage > Cellular data toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_CELL_DATA_TOGGLE = 178;
-
- // ACTION: Settings > Display > When device is rotated
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ROTATION_LOCK = 203;
-
- // OPEN: Settings > Search > Perform search
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_SEARCH_RESULTS = 226;
-
- // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_FINGERPRINT_DELETE = 253;
-
- // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_FINGERPRINT_RENAME = 254;
-
- // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report
- // CATEGORY: SETTINGS
- // OS: N
- // Interactive bug report initiated from Settings.
- ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294;
-
- // ACTION: Settings -> Developer Options -> Take bug report -> Full report
- // CATEGORY: SETTINGS
- // OS: N
- // Interactive bug report initiated from Settings.
- ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295;
-
- // click on collapsed conditional or clicks expand button
- ACTION_SETTINGS_CONDITION_EXPAND = 373;
-
- // click main area of expanded conditional
- ACTION_SETTINGS_CONDITION_CLICK = 375;
-
- // click a direct button on expanded conditional
- ACTION_SETTINGS_CONDITION_BUTTON = 376;
-
- // Action: user enable / disabled data saver using Settings
- // OPEN: Settings -> Data Usage -> Data saver -> On/off toggle
- // VALUE: 1 for enabled, 0 for disabled
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_MODE = 394;
-
- // User whitelisted an app for Data Saver mode; action pass package name of app
- // Action: user enable / disabled data saver using Settings
- // OPEN: Settings -> Data Usage -> Data saver -> Unrestricted data access > APP toggle turned on
- // or
- // Settings -> Apps -> APP -> Data usage -> Unrestricted data usage toggle turned on
- // VALUE: package name of APP
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_WHITELIST = 395;
-
- // User blacklisted an app for Data Saver mode; action pass package name of app
- // OPEN: Settings -> Apps -> APP -> Data usage -> Background data toggle turned off
- // VALUE: package name of APP
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_BLACKLIST = 396;
-
- // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager
- // SUBTYPE: false is off, true is on
- ACTION_TOGGLE_STORAGE_MANAGER = 489;
-
- // OPEN: Settings > Display -> Ambient Display
- // CATEGORY: SETTINGS
- ACTION_AMBIENT_DISPLAY = 495;
-
- // ACTION: Allow Battery optimization for an app
- APP_SPECIAL_PERMISSION_BATTERY_ALLOW = 764;
-
- // ACTION: Deny Battery optimization for an app
- APP_SPECIAL_PERMISSION_BATTERY_DENY = 765;
-
- // ACTION: Enable Device Admin app
- APP_SPECIAL_PERMISSION_ADMIN_ALLOW = 766;
-
- // ACTION: Disable Device Admin app
- APP_SPECIAL_PERMISSION_ADMIN_DENY = 767;
-
- // ACTION: Allow "Do Not Disturb access" for an app
- APP_SPECIAL_PERMISSION_DND_ALLOW = 768;
-
- // ACTION: Deny "Do Not Disturb access" for an app
- APP_SPECIAL_PERMISSION_DND_DENY = 769;
-
- // ACTION: Allow "Draw over other apps" for an app
- APP_SPECIAL_PERMISSION_APPDRAW_ALLOW = 770;
-
- // ACTION: Deny "Display over other apps" for an app
- APP_SPECIAL_PERMISSION_APPDRAW_DENY = 771;
-
- // ACTION: Allow "VR helper services" for an app
- APP_SPECIAL_PERMISSION_VRHELPER_ALLOW = 772;
-
- // ACTION: Deny "VR helper services" for an app
- APP_SPECIAL_PERMISSION_VRHELPER_DENY = 773;
-
- // ACTION: Allow "Modify system settings" for an app
- APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_ALLOW = 774;
-
- // ACTION: Deny "Modify system settings" for an app
- APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_DENY = 775;
-
- // ACTION: Allow "Notification access" for an app
- APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW = 776;
-
- // ACTION: Deny "Notification access" for an app
- APP_SPECIAL_PERMISSION_NOTIVIEW_DENY = 777;
-
- // ACTION: "Premium SMS access" for an app - "ask user" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_ASK = 778;
-
- // ACTION: "Premium SMS access" for an app - "never allow" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_DENY = 779;
-
- // ACTION: "Premium SMS access" for an app - "always allow" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_ALWAYS_ALLOW = 780;
-
- // ACTION: Allow "Unrestricted data access" for an app
- APP_SPECIAL_PERMISSION_UNL_DATA_ALLOW = 781;
-
- // ACTION: Deny "Unrestricted data access" for an app
- APP_SPECIAL_PERMISSION_UNL_DATA_DENY = 782;
-
- // ACTION: Allow "Usage access" for an app
- APP_SPECIAL_PERMISSION_USAGE_VIEW_ALLOW = 783;
-
- // ACTION: Deny "Usage access" for an app
- APP_SPECIAL_PERMISSION_USAGE_VIEW_DENY = 784;
-
- // ACTION: "Force stop" action on an app
- ACTION_APP_FORCE_STOP = 807;
-
- // ACTION: Allow "Enable picture-in-picture" for an app
- APP_PICTURE_IN_PICTURE_ALLOW = 813;
-
- // ACTION: Create a Settings shortcut item.
- ACTION_SETTINGS_CREATE_SHORTCUT = 829;
-
- // ACTION: A tile in Settings information architecture is clicked
- ACTION_SETTINGS_TILE_CLICK = 830;
-
- // ACTION: Settings advanced button is expanded
- ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND = 834;
-
- // ACTION: Deny "Enable picture-in-picture" for an app
- APP_PICTURE_IN_PICTURE_DENY = 814;
-
- // ACTION: Settings -> Display -> Theme
- ACTION_THEME = 816;
-
- // ACTION: Settings > About device > Build number
- ACTION_SETTINGS_BUILD_NUMBER_PREF = 847;
-
- // ACTION: Settings > Battery > Menu > Optimization
- ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION = 851;
-
- // ACTION: Settings > Battery > Menu > Apps Toggle
- ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE = 852;
-
- // ACTION: Settings > Any preference is changed
- ACTION_SETTINGS_PREFERENCE_CHANGE = 853;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Available devices
- ACTION_SETTINGS_BLUETOOTH_PAIR = 866;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Paired devices
- ACTION_SETTINGS_BLUETOOTH_CONNECT = 867;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Connected device
- ACTION_SETTINGS_BLUETOOTH_DISCONNECT = 868;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Error dialog
- ACTION_SETTINGS_BLUETOOTH_CONNECT_ERROR = 869;
-
- // ACTION: Settings > Connected devices > Bluetooth master switch Toggle
- ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870;
-
- // ACTION: Settings > App detail > Uninstall
- ACTION_SETTINGS_UNINSTALL_APP = 872;
-
- // ACTION: Settings > App detail > Uninstall Device admin app
- ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN = 873;
-
- // ACTION: Settings > App detail > Disable app
- ACTION_SETTINGS_DISABLE_APP = 874;
-
- // ACTION: Settings > App detail > Enable app
- ACTION_SETTINGS_ENABLE_APP = 875;
-
- // ACTION: Settings > App detail > Clear data
- ACTION_SETTINGS_CLEAR_APP_DATA = 876;
-
- // ACTION: Settings > App detail > Clear cache
- ACTION_SETTINGS_CLEAR_APP_CACHE = 877;
-
- // ACTION: Logs pressing the "Clear app" button in the app info settings page for an instant
- // app.
- // VALUE: The package name of the app
- ACTION_SETTINGS_CLEAR_INSTANT_APP = 923;
-
- // OPEN: Assist Gesture training intro in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_INTRO = 991;
-
- // OPEN: Assist Gesture training enrolling in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_ENROLLING = 992;
-
- // OPEN: Assist Gesture training finished in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_FINISHED = 993;
-
- // ACTION: Update default app from Settings
- ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Sign in to network
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_WIFI_SIGNIN = 1008;
-
- // ACTION: Settings > Notification Settings > Open application notification
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_OPEN_APP_NOTIFICATION_SETTING = 1016;
-
- // ACTION: Settings > App Info > Open app settings
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_OPEN_APP_SETTING = 1017;
-
- // ACTION: Collect PSD Signals
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_PSD_LOADER = 1019;
-
- // OPEN: Settings > Trampoline Intent > Settings page
- // CATEGORY: SETTINGS
- // OS: O DR
- TRAMPOLINE_SETTINGS_EVENT = 1033;
-
- // ACTION: Logged when user tries to pair a Bluetooth device without name from Settings app
- // CATEGORY: SETTINGS
- // OS: O MR
- ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES = 1096;
-
- // ACTION: Settings > Network & Internet > Mobile network > Network
- // CATEGORY: SETTINGS
- ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK = 1210;
-
- // ACTION: DND Settings > Priority only allows > Alarms toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_ALARMS = 1226;
-
- // ACTION: DND Settings > Priority only allows > Media toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_MEDIA = 1227;
-
- // ACTION: A private dns mode been selected by user
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_PRIVATE_DNS_MODE = 1249;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name > OK
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK = 1267;
-
- // OPEN: Settings > Sound > Do Not Disturb > TURN ON NOW/TURN OFF NOW
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_TOGGLE_DND_BUTTON = 1268;
-
- // ACTION: DND Settings > What to block > full screen intents
- // SUBTYPE: false is allowed, true is blocked
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS = 1332;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_LIGHT = 1333;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_PEEK = 1334;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_STATUS = 1335;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_BADGE = 1336;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_AMBIENT = 1337;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_NOTIFICATION_LIST = 1338;
-
- // ACTION: DND Settings > Priority only allows > System toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_SYSTEM = 1340;
-
- // ACTION: Settings > Battery settings > Battery tip > App restriction tip
- // OS: P
- ACTION_APP_RESTRICTION_TIP = 1347;
-
- // ACTION: Settings > Battery settings > Battery tip > High usage tip
- // OS: P
- ACTION_HIGH_USAGE_TIP = 1348;
-
- // ACTION: Settings > Battery settings > Battery tip > Summary tip
- // OS: P
- ACTION_SUMMARY_TIP = 1349;
-
- // ACTION: Settings > Battery settings > Battery tip > Smart battery tip
- // OS: P
- ACTION_SMART_BATTERY_TIP = 1350;
-
- // ACTION: Settings > Battery settings > Battery tip > Early warning tip
- // OS: P
- ACTION_EARLY_WARNING_TIP = 1351;
-
- // ACTION: Settings > Battery settings > Battery tip > Low battery tip
- // OS: P
- ACTION_LOW_BATTERY_TIP = 1352;
-
- // ACTION: Settings > Battery settings > Battery tip > App restriction list shown
- // OS: P
- ACTION_APP_RESTRICTION_TIP_LIST = 1353;
-
- // ACTION: Settings > Battery settings > Battery tip > High usage list shown
- // OS: P
- ACTION_HIGH_USAGE_TIP_LIST = 1354;
-
- // ACTION: Settings > Battery settings > Battery tip > Open app restriction page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_APP_RESTRICTION_PAGE = 1361;
-
- // ACTION: Settings > Battery settings > Battery tip > Restrict app
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_RESTRICT_APP = 1362;
-
- // ACTION: Settings > Battery settings > Battery tip > Unrestrict app
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_UNRESTRICT_APP = 1363;
-
- // ACTION: Settings > Battery settings > Battery tip > Open smart battery page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_SMART_BATTERY = 1364;
-
- // ACTION: Settings > Battery settings > Battery tip > Turn on battery saver
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_TURN_ON_BATTERY_SAVER = 1365;
-
- // ACTION: Settings > Anomaly receiver > Anomaly received
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ANOMALY_TRIGGERED = 1367;
-
- // ACTION: A Settings Slice is requested
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_SETTINGS_SLICE_REQUESTED = 1371;
-
- // ACTION: A Settings Slice is updated with new value
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_SETTINGS_SLICE_CHANGED = 1372;
-
- // OPEN: DND onboarding activity > Ok button
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_OK = 1378;
-
- // OPEN: DND onboarding activity > Settings link
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_SETTINGS = 1379;
-
- // ACTION: Settings > Anomaly receiver > Anomaly ignored, don't show up in battery settings
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ANOMALY_IGNORED = 1387;
-
- // ACTION: Settings > Battery settings > Battery tip > Open battery saver page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_BATTERY_SAVER_PAGE = 1388;
-
- // ACTION: DND Settings > What to block
- // OS: P
- ACTION_ZEN_SOUND_ONLY = 1396;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_SOUND_AND_VIS_EFFECTS = 1397;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_SHOW_CUSTOM = 1398;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_CUSTOM = 1399;
-
- // OPEN: DND onboarding activity > don't update button
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS = 1406;
-
- // ACTION: Storage initialization wizard initialization choice of external/portable
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_INIT_EXTERNAL = 1407;
-
- // ACTION: Storage initialization wizard initialization choice of internal/adoptable
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_INIT_INTERNAL = 1408;
-
- // ACTION: Storage initialization wizard benchmark fast choice of continue
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_FAST_CONTINUE = 1409;
-
- // ACTION: Storage initialization wizard benchmark slow choice of continue
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_SLOW_CONTINUE = 1410;
-
- // ACTION: Storage initialization wizard benchmark slow choice of abort
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_SLOW_ABORT = 1411;
-
- // ACTION: Storage initialization wizard migration choice of now
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_MIGRATE_NOW = 1412;
-
- // ACTION: Storage initialization wizard migration choice of later
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_MIGRATE_LATER = 1413;
-
- // OPEN: Settings > Sound > Switch a2dp devices dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SWITCH_A2DP_DEVICES = 1415;
-
-
- // OPEN: Settings > Sound > Switch hfp devices dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SWITCH_HFP_DEVICES = 1416;
-
- // OPEN: QS Sensor Privacy Mode tile shown
- // ACTION: QS Sensor Privacy Mode tile tapped
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: QUICK_SETTINGS
- // OS: Q
- QS_SENSOR_PRIVACY = 1598;
-
- // ACTION: Tap & Pay -> Default Application Setting -> Use Forground
- ACTION_NFC_PAYMENT_FOREGROUND_SETTING = 1622;
-
- // ACTION: Tap & Pay -> Default Application Setting -> Use Default
- ACTION_NFC_PAYMENT_ALWAYS_SETTING = 1623;
-
- // ACTION: Settings > Search Bar > Avatar
- // CATEGORY: SETTINGS
- // OS: Q
- CLICK_ACCOUNT_AVATAR = 1643;
-
- // ACTION: Set new password (action intent android.app.action.SET_NEW_PASSWORD)
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_SET_NEW_PASSWORD = 1645;
-
- // ACTION: Set new password (action intent android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD)
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = 1646;
-
- // ACTION: An interaction with a Slice or other component in the Panel.
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_PANEL_INTERACTION = 1658;
-
- // ACTION: Show Contextual homepage. Log total loading latency.
- ACTION_CONTEXTUAL_HOME_SHOW = 1662;
-
- // ACTION: Contextual card displays
- ACTION_CONTEXTUAL_CARD_SHOW = 1663;
-
- // ACTION: Contextual cards are eligible to be shown, but don't rank high
- ACTION_CONTEXTUAL_CARD_NOT_SHOW = 1664;
-
- // ACTION: Settings > long press a card, and click dismiss
- // Contextual card is dismissed
- ACTION_CONTEXTUAL_CARD_DISMISS = 1665;
-
- // ACTION: Settings > click a card
- // Contextual card is clicked
- ACTION_CONTEXTUAL_CARD_CLICK = 1666;
-
- // Mapping: go/at-mapping
- ACTION_ATSG = 1674;
-
- ACTION_ATPG = 1675;
-
- ACTION_ATCLPB = 1676;
-
- ACTION_ATCGIB = 1677;
-
- ACTION_ATCPAB = 1678;
-
- ACTION_ATCSAUC = 1679;
-
- ACTION_ATCSCUC = 1680;
-
- ACTION_ATCHNUC = 1681;
-
- // ACTION: Individual contextual card loading time
- ACTION_CONTEXTUAL_CARD_LOAD = 1684;
-
- //ACTION: Contextual card loading timeout
- ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
-
- //ACTION: Log result for each card's eligibility check
- ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
-
- // ACTION: Display white balance setting enabled or disabled.
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_DISPLAY_WHITE_BALANCE_SETTING_CHANGED = 1703;
-
- // ACTION: Share a Wi-Fi network by generating a QR code
- ACTION_SETTINGS_SHARE_WIFI_QR_CODE = 1710;
-
- // ACTION: Connect to a Wi-Fi network by scanning a QR code
- ACTION_SETTINGS_ENROLL_WIFI_QR_CODE = 1711;
-
- // ACTION: Share Wi-Fi hotspot by generating a QR code
- ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE = 1712;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Invalid data
- ACTION_VERIFY_SLICE_ERROR_INVALID_DATA = 1725;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Parsing error
- ACTION_VERIFY_SLICE_PARSING_ERROR = 1726;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Other exception
- ACTION_VERIFY_SLICE_OTHER_EXCEPTION = 1727;
-
- // Custom tag to evaluate the consuming time of the Controller.updateState.
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONTROLLER_UPDATE_STATE = 1728;
-
- // Custom tag to evaluate the consuming time from onAttach to
- // DashboardFragment.updatePreferenceStates.
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_DASHBOARD_VISIBLE_TIME = 1729;
-
- // ACTION: Allow "Access all files" for an app
- APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_ALLOW = 1730;
-
- // ACTION: Deny "Access all files" for an app
- APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_DENY = 1731;
-
- // ACTION: Battery feature usage
- ACTION_BATTERY_OPTION_FEATURE_USAGE = 1732;
-
- // ACTION: Battery feature runtime event
- ACTION_BATTERY_OPTION_RUNTIME_EVENT = 1733;
-
- // ACTION: Settings > Developer Options > Toggle on Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_ADB_WIRELESS_ON = 1734;
-
- // ACTION: Settings > Developer Options > Toggle off Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_ADB_WIRELESS_OFF = 1735;
-
- // ACTION: Change Wi-Fi hotspot name
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_NAME = 1736;
-
- // ACTION: Change Wi-Fi hotspot password
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_PASSWORD = 1737;
-
- // ACTION: Settings > Security > Toggle on Confirm Sim deletion
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONFIRM_SIM_DELETION_ON = 1738;
-
- // ACTION: Settings > Security > Toggle off Confirm Sim deletion
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONFIRM_SIM_DELETION_OFF = 1739;
-}
-
-/**
- * Id for Settings pages. Each page must have its own unique Id.
- */
-enum PageId {
- // Unknown page. Should not be used in production code.
- PAGE_UNKNOWN = 0;
-
- // OPEN: Settings > Accessibility
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY = 2;
-
- // OPEN: Settings > Accessibility > Captions preference
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_CAPTION_PROPERTIES = 3;
-
- // OPEN: Settings > Accessibility > [Service]
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_SERVICE = 4;
-
- // OPEN: Settings > Accessibility > Color correction
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
-
- // OPEN: Settings > Accessibility > Accessibility shortcut
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
-
- // OPEN: Settings > Accessibility > Magnification gestures (Renamed in O)
- // OPEN: Settings > Accessibility > Magnification > Magnify with triple-tap
- // OPEN: Settings > Accessibility > Magnification > Magnify with button
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
-
- // OPEN: Settings > Accounts
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNT = 8;
-
- // OPEN: Settings > Accounts > [Single Account Sync Settings]
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNTS_ACCOUNT_SYNC = 9;
-
- // OPEN: Settings > Accounts > Add an account
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
-
- // OPEN: Settings > Cellular network settings > APNs
- // CATEGORY: SETTINGS
- // OS: 6.0
- APN = 12;
-
- // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APN_EDITOR = 13;
-
- // OPEN: Settings > Apps > Configure apps > App links > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_APP_LAUNCH = 17;
-
- // OPEN: Settings > Internal storage > Apps storage > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_APP_STORAGE = 19;
-
- // OPEN: Settings > Apps > [App info]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_INSTALLED_APP_DETAILS = 20;
-
- // OPEN: Settings > Memory > App usage > [App Memory usage]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_PROCESS_STATS_DETAIL = 21;
-
- // OPEN: Settings > Memory > App usage
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_PROCESS_STATS_UI = 23;
-
- // OPEN: Choose Bluetooth device (ex: when sharing)
- // CATEGORY: SETTINGS
- // OS: 6.0
- BLUETOOTH_DEVICE_PICKER = 25;
-
- // OPEN: Settings > Security > Choose screen lock
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_GENERIC = 27;
-
- // OPEN: Settings > Security > Choose screen lock > Choose your password
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_PASSWORD = 28;
-
- // OPEN: Settings > Security > Choose screen lock > Choose your pattern
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_PATTERN = 29;
-
- // OPEN: Settings > Security > Choose screen lock > Confirm your password
- // CATEGORY: SETTINGS
- // OS: 6.0
- CONFIRM_LOCK_PASSWORD = 30;
-
- // OPEN: Settings > Security > Choose screen lock > Confirm your pattern
- // CATEGORY: SETTINGS
- // OS: 6.0
- CONFIRM_LOCK_PATTERN = 31;
-
- // OPEN: Settings > Security > Encrypt phone
- // CATEGORY: SETTINGS
- // OS: 6.0
- CRYPT_KEEPER = 32;
-
- // OPEN: Settings > Security > Encrypt phone > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- CRYPT_KEEPER_CONFIRM = 33;
-
- // OPEN: Settings (Root page)
- // CATEGORY: SETTINGS
- // OS: 6.0
- DASHBOARD_SUMMARY = 35;
-
- // OPEN: Settings > Data usage
- // CATEGORY: SETTINGS
- // OS: 6.0
- DATA_USAGE_SUMMARY = 37;
-
- // OPEN: Settings > Date & time
- // CATEGORY: SETTINGS
- // OS: 6.0
- DATE_TIME = 38;
-
- // OPEN: Settings > Developer options
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVELOPMENT = 39;
-
- // OPEN: Settings > About phone
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVICEINFO = 40;
-
- // OPEN: Settings > Internal storage
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVICEINFO_STORAGE = 42;
-
- // OPEN: Settings > Display
- // CATEGORY: SETTINGS
- // OS: 6.0
- DISPLAY = 46;
-
- // OPEN: Settings > Display > Daydream
- // CATEGORY: SETTINGS
- // OS: 6.0
- DREAM = 47;
-
- // OPEN: Settings > Security > Screen lock > Secure start-up
- // CATEGORY: SETTINGS
- // OS: 6.0
- ENCRYPTION = 48;
-
- // OPEN: Settings > Security > Nexus Imprint
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT = 49;
-
- // OPEN: Settings > Battery > History details
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
-
- // OPEN: Settings > Battery > Battery saver
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_BATTERY_SAVER = 52;
-
- // OPEN: Settings > Battery > [App Use details]
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_POWER_USAGE_DETAIL = 53;
-
- // OPEN: Settings > Security > SIM card lock settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- ICC_LOCK = 56;
-
- // OPEN: Settings > Language & input > Physical keyboard
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_KEYBOARD = 58;
-
- // OPEN: Settings > Language & input > Spell checker
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_SPELL_CHECKERS = 59;
-
- // OBSOLETE
- INPUTMETHOD_SUBTYPE_ENABLER = 60;
-
- // OPEN: Settings > Language & input > Personal dictionary
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_USER_DICTIONARY = 61;
-
- // OPEN: Settings > Language & input > Add word
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
-
- // OPEN: Settings > Location
- // CATEGORY: SETTINGS
- // OS: 6.0
- LOCATION = 63;
-
- // OPEN: Settings > Apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_APPLICATIONS = 65;
-
- // OPEN: Settings > Backup & reset > Factory data reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- MASTER_CLEAR = 66;
-
- // OPEN: Settings > Backup & reset > Factory data reset > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- MASTER_CLEAR_CONFIRM = 67;
-
- // OPEN: Settings > More > Android Beam
- // CATEGORY: SETTINGS
- // OS: 6.0
- NFC_BEAM = 69;
-
- // OPEN: Settings > Tap & pay
- // CATEGORY: SETTINGS
- // OS: 6.0
- NFC_PAYMENT = 70;
-
- // OPEN: Settings > Sound & notification > App notifications > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_APP_NOTIFICATION = 72;
-
- // OBSOLETE
- NOTIFICATION_REDACTION = 74;
-
- // OPEN: Settings Widget > Notification log
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_STATION = 75;
-
- // OPEN: Settings > Sound & notification > Do not disturb
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE = 76;
-
-
- // OPEN: Print job notification > Print job settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_JOB_SETTINGS = 78;
-
- // OPEN: Settings > Printing > [Print Service]
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_SERVICE_SETTINGS = 79;
-
- // OPEN: Settings > Printing
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_SETTINGS = 80;
-
- // OPEN: Settings > Backup & reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRIVACY = 81;
-
- //OBSOLETE
- PROXY_SELECTOR = 82;
-
- // OPEN: Settings > Backup & reset > Network settings reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- RESET_NETWORK = 83;
-
- // OPEN: Settings > Backup & reset > Network settings reset > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- RESET_NETWORK_CONFIRM = 84;
-
- // OPEN: Settings > Developer Options > Running Services
- // CATEGORY: SETTINGS
- // OS: 6.0
- RUNNING_SERVICE_DETAILS = 85;
-
- // OPEN: Settings > Security > Screen pinning
- // CATEGORY: SETTINGS
- // OS: 6.0
- SCREEN_PINNING = 86;
-
- // OPEN: Settings > Security
- // CATEGORY: SETTINGS
- // OS: 6.0
- SECURITY = 87;
-
- // OPEN: Settings > SIM cards
- // CATEGORY: SETTINGS
- // OS: 6.0
- SIM = 88;
-
- // OBSOLETE
- TESTING = 89;
-
- // OPEN: Settings > More > Tethering & portable hotspot
- // CATEGORY: SETTINGS
- // OS: 6.0
- TETHER = 90;
-
- // OPEN: Settings > Security > Trust agents
- // CATEGORY: SETTINGS
- // OS: 6.0
- TRUST_AGENT = 91;
-
- // OPEN: Settings > Security > Trusted credentials
- // CATEGORY: SETTINGS
- // OS: 6.0
- TRUSTED_CREDENTIALS = 92;
-
- // OPEN: Settings > Language & input > TTS output > [Engine] > Settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- TTS_ENGINE_SETTINGS = 93;
-
- // OPEN: Settings > Language & input > Text-to-speech output
- // CATEGORY: SETTINGS
- // OS: 6.0
- TTS_TEXT_TO_SPEECH = 94;
-
- // OPEN: Settings > Security > Apps with usage access
- // CATEGORY: SETTINGS
- // OS: 6.0
- USAGE_ACCESS = 95;
-
- // OPEN: Settings > Users
- // CATEGORY: SETTINGS
- // OS: 6.0
- USER = 96;
-
- // OPEN: Settings > Users > [Restricted profile app & content access]
- // CATEGORY: SETTINGS
- // OS: 6.0
- USERS_APP_RESTRICTIONS = 97;
-
- // OPEN: Settings > Users > [User settings]
- // CATEGORY: SETTINGS
- // OS: 6.0
- USER_DETAILS = 98;
-
- // OPEN: Settings > More > VPN
- // CATEGORY: SETTINGS
- // OS: 6.0
- VPN = 100;
-
- // OPEN: Settings > Display > Choose wallpaper from
- // CATEGORY: SETTINGS
- // OS: 6.0
- WALLPAPER_TYPE = 101;
-
- // OPEN: Settings > Display > Cast
- // CATEGORY: SETTINGS
- // OS: 6.0
- WFD_WIFI_DISPLAY = 102;
-
- // OPEN: Settings > Wi-Fi
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI = 103;
-
- // OPEN: Settings > More > Wi-Fi Calling
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_CALLING = 105;
-
- // OPEN: Settings > Wi-Fi > Saved networks
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_SAVED_ACCESS_POINTS = 106;
-
- // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_P2P = 109;
-
- // OPEN: Settings > Apps > Configure apps > App permissions
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_ADVANCED = 130;
-
- // OPEN: Settings > Location > Scanning
- // CATEGORY: SETTINGS
- // OS: 6.0
- LOCATION_SCANNING = 131;
-
- // OPEN: Settings > Sound & notification > App notifications
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
-
- // OPEN: Settings > Sound & notification > DND > Priority only allows
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_PRIORITY = 141;
-
- // OPEN: Settings > Sound & notification > DND > Automatic rules
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
-
- // OPEN: Settings > Sound & notification > DND > [Time based rule]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
-
- // OPEN: Settings > Apps > Configure apps > App links
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_DOMAIN_URLS = 143;
-
- // OPEN: Settings > Sound & notification > DND > [Event rule]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
-
- // OPEN: Settings > Sound & notification > Notification access
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ACCESS = 179;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb access
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_ACCESS = 180;
-
- // OPEN: Settings > Internal storage > Apps storage
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_STORAGE_APPS = 182;
-
- // OPEN: Settings > Security > Usage access
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
-
- // OPEN: Settings > Battery > Battery optimization
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_HIGH_POWER_APPS = 184;
-
- // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_MANAGE_ASSIST = 201;
-
- // OPEN: Settings > Memory
- // CATEGORY: SETTINGS
- // OS: 6.0
- PROCESS_STATS_SUMMARY = 202;
-
- // OPEN: Settings > Apps > Configure Apps > Display over other apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- SYSTEM_ALERT_WINDOW_APPS = 221;
-
- // OPEN: Settings > About phone > Legal information
- // CATEGORY: SETTINGS
- // OS: 6.0
- ABOUT_LEGAL_SETTINGS = 225;
-
-
- // OPEN: Settings > Developer options > Inactive apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_INACTIVE_APPS = 238;
-
- // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLLING = 240;
- // OPEN: Fingerprint Enroll > Find Sensor
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_FIND_SENSOR = 241;
-
- // OPEN: Fingerprint Enroll > Fingerprint Enrolled!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_FINISH = 242;
-
- // OPEN: Fingerprint Enroll introduction
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_INTRO = 243;
-
- // OPEN: Fingerprint Enroll > Let's Start!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_SIDECAR = 245;
-
- // OPEN: Fingerprint Enroll SUW > Let's Start!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLLING_SETUP = 246;
-
- // OPEN: Fingerprint Enroll SUW > Find Sensor
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_FIND_SENSOR_SETUP = 247;
-
- // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_FINISH_SETUP = 248;
-
- // OPEN: Fingerprint Enroll SUW introduction
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_INTRO_SETUP = 249;
-
- // OPEN: Settings > Developer Options > Background Check
- // CATEGORY: SETTINGS
- // OS: N
- BACKGROUND_CHECK_SUMMARY = 258;
-
- // OPEN: Settings > Notifications > [App] > Channel Notifications
- // CATEGORY: SETTINGS
- // OS: N
- NOTIFICATION_TOPIC_NOTIFICATION = 265;
-
- // OPEN: Settings > Security > User credentials
- // CATEGORY: Settings
- // OS: N
- USER_CREDENTIALS = 285;
-
- // Logs that the user has edited the enabled VR listeners.
- // CATEGORY: SETTINGS
- // OS: N
- VR_MANAGE_LISTENERS = 334;
-
- // Settings -> Accessibility -> Click after pointer stops moving
- // CATEGORY: SETTINGS
- // OS: N
- ACCESSIBILITY_TOGGLE_AUTOCLICK = 335;
-
- // Settings -> Sound
- // CATEGORY: SETTINGS
- // OS: N
- SOUND = 336;
-
- // Settings -> Notifications -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- CONFIGURE_NOTIFICATION = 337;
-
- // Settings -> Wi-Fi -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- CONFIGURE_WIFI = 338;
-
- // Settings -> Display -> Display size
- // OS: N
- DISPLAY_SCREEN_ZOOM = 339;
-
- // Settings -> Display -> Font size
- // CATEGORY: SETTINGS
- // OS: N
- ACCESSIBILITY_FONT_SIZE = 340;
-
- // Settings -> Data usage -> Cellular/Wi-Fi data usage
- // CATEGORY: SETTINGS
- // OS: N
- DATA_USAGE_LIST = 341;
-
- // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- BILLING_CYCLE = 342;
-
- // DATA_USAGE_LIST -> Any item or App info -> Data usage
- // CATEGORY: SETTINGS
- // OS: N
- APP_DATA_USAGE = 343;
-
- // Settings -> Language & input -> Language
- // CATEGORY: SETTINGS
- // OS: N
- USER_LOCALE_LIST = 344;
-
- // Settings -> Language & input -> Virtual keyboard
- // CATEGORY: SETTINGS
- // OS: N
- VIRTUAL_KEYBOARDS = 345;
-
- // Settings -> Language & input -> Physical keyboard
- // CATEGORY: SETTINGS
- // OS: N
- PHYSICAL_KEYBOARDS = 346;
-
- // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard
- // CATEGORY: SETTINGS
- // OS: N
- ENABLE_VIRTUAL_KEYBOARDS = 347;
-
- // Settings -> Data usage -> Data Saver
- // CATEGORY: SETTINGS
- // OS: N
- DATA_SAVER_SUMMARY = 348;
-
- // Settings -> Data usage -> Data Saver -> Unrestricted data access
- // CATEGORY: SETTINGS
- // OS: N
- DATA_USAGE_UNRESTRICTED_ACCESS = 349;
-
- // Settings -> Apps -> Gear -> Special access
- SPECIAL_ACCESS = 351;
-
- // OPEN: SUW Welcome Screen -> Vision Settings
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY = 367;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification gestures (Renamed in O)
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with triple-tap
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with button
- // ACTION: New magnification gesture configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 368;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Font size
- // ACTION: New font size is chosen
- // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is largest
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_FONT_SIZE = 369;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Display size
- // ACTION: New display size is chosen
- // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is larger, 4 is largest
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_DISPLAY_SIZE = 370;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> TalkBack
- // ACTION: New screen reader configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SCREEN_READER = 371;
-
- // Airplane mode on
- SETTINGS_CONDITION_AIRPLANE_MODE = 377;
- // AKA Data saver on
- SETTINGS_CONDITION_BACKGROUND_DATA = 378;
- // Battery saver on
- SETTINGS_CONDITION_BATTERY_SAVER = 379;
- // Cellular data off
- SETTINGS_CONDITION_CELLULAR_DATA = 380;
- // Do not disturb on
- SETTINGS_CONDITION_DND = 381;
- // Hotspot on
- SETTINGS_CONDITION_HOTSPOT = 382;
- // Work profile off
- SETTINGS_CONDITION_WORK_MODE = 383;
-
- // Settings > Apps > Gear > Special Access > Premium SMS access
- PREMIUM_SMS_ACCESS = 388;
-
- // OPEN: Settings > Accounts > Work profile settings
- // CATEGORY: SETTINGS
- ACCOUNTS_WORK_PROFILE_SETTINGS = 401;
-
- // Settings -> Dev options -> Convert to file encryption
- CONVERT_FBE = 402;
-
- // Settings -> Dev options -> Convert to file encryption -> WIPE AND CONVERT...
- CONVERT_FBE_CONFIRM = 403;
-
- // Settings -> Dev options -> Running services
- RUNNING_SERVICES = 404;
-
- // The dialog shown by 3P intent to change current webview implementation.
- WEBVIEW_IMPLEMENTATION = 405;
-
- // OPEN: Settings > Internal storage > Storage manager
- // CATEGORY: SETTINGS
- STORAGE_MANAGER_SETTINGS = 458;
-
- // OPEN: Settings -> Gestures
- // CATEGORY: SETTINGS
- SETTINGS_GESTURES = 459;
-
- // OPEN: Settings > Display > Night Light
- // CATEGORY: SETTINGS
- NIGHT_DISPLAY_SETTINGS = 488;
-
- // Night Light on
- SETTINGS_CONDITION_NIGHT_DISPLAY = 492;
-
- // OPEN: Settings > Language & input > Personal dictionary (single locale)
- USER_DICTIONARY_SETTINGS = 514;
-
- // OPEN: Settings > Date & time > Select time zone
- ZONE_PICKER = 515;
-
- // OPEN: Settings > Security > Device administrators
- DEVICE_ADMIN_SETTINGS = 516;
-
- // OPEN: Settings > Security > Factory Reset Protection dialog
- DIALOG_FRP = 528;
-
- // OPEN: Settings > Custom list preference with confirmation message
- DIALOG_CUSTOM_LIST_CONFIRMATION = 529;
-
- // OPEN: Settings > APN Editor > Error dialog
- DIALOG_APN_EDITOR_ERROR = 530;
-
- // OPEN: Settings > Users > Edit owner info dialog
- DIALOG_OWNER_INFO_SETTINGS = 531;
-
- // OPEN: Settings > Security > Use one lock dialog
- DIALOG_UNIFICATION_CONFIRMATION = 532;
-
- // OPEN: Settings > Security > User Credential
- DIALOG_USER_CREDENTIAL = 533;
-
- // OPEN: Settings > Accounts > Remove account
- DIALOG_REMOVE_USER = 534;
-
- // OPEN: Settings > Accounts > Confirm auto sync dialog
- DIALOG_CONFIRM_AUTO_SYNC_CHANGE = 535;
-
- // OPEN: Settings > Apps > Dialog for running service details
- DIALOG_RUNNIGN_SERVICE = 536;
-
- // OPEN: Settings > Bluetooth > Rename this device
- DIALOG_BLUETOOTH_RENAME = 538;
-
- // OPEN: Settings > Battery optimization > details for app
- DIALOG_HIGH_POWER_DETAILS = 540;
-
- // OPEN: Settings > Keyboard > Show keyboard layout dialog
- DIALOG_KEYBOARD_LAYOUT = 541;
-
- // OPEN: Settings > WIFI Scan permission dialog
- DIALOG_WIFI_SCAN_MODE = 543;
-
- // OPEN: Settings > Wireless > VPN > Config dialog
- DIALOG_LEGACY_VPN_CONFIG = 545;
-
- // OPEN: Settings > Wireless > VPN > Config dialog for app
- DIALOG_VPN_APP_CONFIG = 546;
-
- // OPEN: Settings > Wireless > VPN > Cannot connect dialog
- DIALOG_VPN_CANNOT_CONNECT = 547;
-
- // OPEN: Settings > Wireless > VPN > Replace existing VPN dialog
- DIALOG_VPN_REPLACE_EXISTING = 548;
-
- // OPEN: Settings > Billing cycle > Edit billing cycle dates dialog
- DIALOG_BILLING_CYCLE = 549;
-
- // OPEN: Settings > Billing cycle > Edit data limit/warning dialog
- DIALOG_BILLING_BYTE_LIMIT = 550;
-
- // OPEN: Settings > Billing cycle > turn on data limit dialog
- DIALOG_BILLING_CONFIRM_LIMIT = 551;
-
- // OPEN: Settings > Service > Turn off notification access dialog
- DIALOG_DISABLE_NOTIFICATION_ACCESS = 552;
-
- // OPEN: Settings > Sound > Use personal sound for work profile dialog
- DIALOG_UNIFY_SOUND_SETTINGS = 553;
-
- // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being granted.
- DIALOG_ZEN_ACCESS_GRANT = 554;
-
- // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being revoked.
- DIALOG_ZEN_ACCESS_REVOKE = 555;
-
- // OPEN: Settings > Zen mode > Dialog that picks time for zen mode.
- DIALOG_ZEN_TIMEPICKER = 556;
-
- // OPEN: Settings > Apps > Dialog that informs user to allow service access for app.
- DIALOG_SERVICE_ACCESS_WARNING = 557;
-
- // OPEN: Settings > Apps > Dialog for app actions (such as force stop/clear data)
- DIALOG_APP_INFO_ACTION = 558;
-
- // OPEN: Settings > Storage > Dialog for forgetting a storage device
- DIALOG_VOLUME_FORGET = 559;
-
- // OPEN: Settings > Storage > Dialog for initializing a volume
- DIALOG_VOLUME_INIT = 561;
-
- // OPEN: Settings > Storage > Dialog for unmounting a volume
- DIALOG_VOLUME_UNMOUNT = 562;
-
- // OPEN: Settings > Storage > Dialog for renaming a volume
- DIALOG_VOLUME_RENAME = 563;
-
- // OPEN: Settings > Storage > Dialog for clear cache
- DIALOG_STORAGE_CLEAR_CACHE = 564;
-
- // OPEN: Settings > Storage > Dialog for system info
- DIALOG_STORAGE_SYSTEM_INFO = 565;
-
- // OPEN: Settings > Storage > Dialog for other info
- DIALOG_STORAGE_OTHER_INFO = 566;
-
- // OPEN: Settings > Storage > Dialog for user info
- DIALOG_STORAGE_USER_INFO = 567;
- // OPEN: Settings > Add fingerprint > Dialog when user touches fingerprint icon.
- DIALOG_FINGERPRINT_ICON_TOUCH = 568;
-
- // OPEN: Settings > Add fingerprint > Error dialog
- DIALOG_FINGERPINT_ERROR = 569;
-
- // OPEN: Settings > Fingerprint > Rename or delete dialog
- DIALOG_FINGERPINT_EDIT = 570;
-
- // OPEN: Settings > Fingerprint > Dialog for deleting last fingerprint
- DIALOG_FINGERPINT_DELETE_LAST = 571;
-
- // OPEN: SUW > Fingerprint > Dialog to confirm skip fingerprint setup entirely.
- DIALOG_FINGERPRINT_SKIP_SETUP = 573;
-
- // OPEN: Settings > Proxy Selector error dialog
- DIALOG_PROXY_SELECTOR_ERROR = 574;
-
- // OPEN: Settings > Wifi > P2P Settings > Disconnect dialog
- DIALOG_WIFI_P2P_DISCONNECT = 575;
-
- // OPEN: Settings > Wifi > P2P Settings > Cancel connection dialog
- DIALOG_WIFI_P2P_CANCEL_CONNECT = 576;
-
- // OPEN: Settings > Wifi > P2P Settings > Rename dialog
- DIALOG_WIFI_P2P_RENAME = 577;
-
- // OPEN: Settings > Wifi > P2P Settings > Forget group dialog
- DIALOG_WIFI_P2P_DELETE_GROUP = 578;
-
- // OPEN: Settings > APN > Restore default dialog
- DIALOG_APN_RESTORE_DEFAULT = 579;
-
- // OPEN: Settings > Encryption interstitial accessibility warning dialog
- DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY = 581;
-
- // OPEN: Settings > Acessibility > Enable accessiblity service dialog
- DIALOG_ACCESSIBILITY_SERVICE_ENABLE = 583;
-
- // OPEN: Settings > Acessibility > Disable accessiblity service dialog
- DIALOG_ACCESSIBILITY_SERVICE_DISABLE = 584;
-
- // OPEN: Settings > Account > Remove account dialog
- DIALOG_ACCOUNT_SYNC_REMOVE = 585;
-
- // OPEN: Settings > Account > Remove account failed dialog
- DIALOG_ACCOUNT_SYNC_FAILED_REMOVAL = 586;
-
- // OPEN: Settings > Account > Cannot do onetime sync dialog
- DIALOG_ACCOUNT_SYNC_CANNOT_ONETIME_SYNC = 587;
-
- // OPEN: Settings > Display > Night light > Set start time dialog
- DIALOG_NIGHT_DISPLAY_SET_START_TIME = 588;
-
- // OPEN: Settings > Display > Night light > Set end time dialog
- DIALOG_NIGHT_DISPLAY_SET_END_TIME = 589;
-
-
-
- // OPEN: Settings > User > Edit info dialog
- DIALOG_USER_EDIT = 590;
-
- // OPEN: Settings > User > Confirm remove dialog
- DIALOG_USER_REMOVE = 591;
-
- // OPEN: Settings > User > Enable calling dialog
- DIALOG_USER_ENABLE_CALLING = 592;
-
- // OPEN: Settings > User > Enable calling and sms dialog
- DIALOG_USER_ENABLE_CALLING_AND_SMS = 593;
-
- // OPEN: Settings > User > Cannot manage device message dialog
- DIALOG_USER_CANNOT_MANAGE = 594;
-
- // OPEN: Settings > User > Add user dialog
- DIALOG_USER_ADD = 595;
-
- // OPEN: Settings > User > Setup user dialog
- DIALOG_USER_SETUP = 596;
-
- // OPEN: Settings > User > Setup profile dialog
- DIALOG_USER_SETUP_PROFILE = 597;
-
- // OPEN: Settings > User > Choose user type dialog
- DIALOG_USER_CHOOSE_TYPE = 598;
-
- // OPEN: Settings > User > Need lockscreen dialog
- DIALOG_USER_NEED_LOCKSCREEN = 599;
-
- // OPEN: Settings > User > Confirm exit guest mode dialog
- DIALOG_USER_CONFIRM_EXIT_GUEST = 600;
-
- // OPEN: Settings > User > Edit user profile dialog
- DIALOG_USER_EDIT_PROFILE = 601;
-
-
- // OPEN: Settings > Wifi > Saved AP > Edit dialog
- DIALOG_WIFI_SAVED_AP_EDIT = 602;
-
- // OPEN: Settings > Wifi > Edit AP dialog
- DIALOG_WIFI_AP_EDIT = 603;
-
- // OPEN: Settings > Wifi > Write config to NFC dialog
- DIALOG_WIFI_WRITE_NFC = 606;
-
- // OPEN: Settings > Date > Date picker dialog
- DIALOG_DATE_PICKER = 607;
-
- // OPEN: Settings > Date > Time picker dialog
- DIALOG_TIME_PICKER = 608;
-
- // OPEN: Settings > Wireless > Manage wireless plan dialog
- DIALOG_MANAGE_MOBILE_PLAN = 609;
-
- // OPEN Settings > Bluetooth > Attempt to connect to device that shows dialog
- BLUETOOTH_DIALOG_FRAGMENT = 613;
-
- // OPEN: Settings > Security
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_SETTINGS = 628;
-
- // OPEN: Settings > System
- SETTINGS_SYSTEM_CATEGORY = 744;
-
- // OPEN: Settings > Storage
- SETTINGS_STORAGE_CATEGORY = 745;
-
- // OPEN: Settings > Network & Internet
- SETTINGS_NETWORK_CATEGORY = 746;
-
- // OPEN: Settings > Connected Device
- SETTINGS_CONNECTED_DEVICE_CATEGORY = 747;
-
- // OPEN: Settings > App & Notification
- SETTINGS_APP_NOTIF_CATEGORY = 748;
-
- // OPEN: Settings > System > Language & Region
- SETTINGS_LANGUAGE_CATEGORY = 750;
-
- // OPEN: Settings > System > Input & Gesture > Swipe to notification gesture
- SETTINGS_GESTURE_SWIPE_TO_NOTIFICATION = 751;
-
- // OPEN: Settings > System > Input & Gesture > Double tap power button gesture
- SETTINGS_GESTURE_DOUBLE_TAP_POWER = 752;
-
- // OPEN: Settings > System > Input & Gesture > Pick up gesture
- SETTINGS_GESTURE_PICKUP = 753;
-
- // OPEN: Settings > System > Input & Gesture > Double tap screen gesture
- SETTINGS_GESTURE_DOUBLE_TAP_SCREEN = 754;
-
- // OPEN: Settings > System > Input & Gesture > Double twist gesture
- SETTINGS_GESTURE_DOUBLE_TWIST = 755;
-
- // OPEN: Settings > Apps > Default Apps > Default browser
- DEFAULT_BROWSER_PICKER = 785;
- // OPEN: Settings > Apps > Default Apps > Default emergency app
- DEFAULT_EMERGENCY_APP_PICKER = 786;
-
- // OPEN: Settings > Apps > Default Apps > Default home
- DEFAULT_HOME_PICKER = 787;
-
- // OPEN: Settings > Apps > Default Apps > Default phone
- DEFAULT_PHONE_PICKER = 788;
-
- // OPEN: Settings > Apps > Default Apps > Default sms
- DEFAULT_SMS_PICKER = 789;
-
- // OPEN: Settings > Apps > Notification > Notification Assistant
- DEFAULT_NOTIFICATION_ASSISTANT = 790;
-
-
- // OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection
- DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791;
-
- // OPEN: Settings > Apps > Default Apps > Default autofill app
- DEFAULT_AUTOFILL_PICKER = 792;
-
- // OPEN: Settings > Apps > Gear > Special Access > Install other apps
- // CATEGORY: SETTINGS
- // OS: 8.0
- MANAGE_EXTERNAL_SOURCES = 808;
-
- // Logs that the user has edited the picture-in-picture settings.
- // CATEGORY: SETTINGS
- SETTINGS_MANAGE_PICTURE_IN_PICTURE = 812;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Select to Speak
- // ACTION: Select to Speak configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK = 817;
-
- // OPEN: Settings > System > Backup
- // CATEGORY: SETTINGS
- // OS: O
- BACKUP_SETTINGS = 818;
-
- // OPEN: Settings > Storage > Games
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_GAMES = 838;
-
- // OPEN: Settings > Storage > Audio and Music
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_MUSIC = 839;
-
- // ACTION: Settings > Storage > Free Up Space to launch Deletion Helper
- // CATEGORY: SETTINGS
- // OS: O
- STORAGE_FREE_UP_SPACE_NOW = 840;
-
- // ACTION: Settings > Storage > Files to open the File Manager
- // CATEGORY: SETTINGS
- // OS: O
- STORAGE_FILES = 841;
-
- // OPEN: Settings > Apps > Default Apps > Assist > Default assist
- DEFAULT_ASSIST_PICKER = 843;
-
- // OPEN: Settings > Apps > Default Apps > Assist > Default voice input
- DEFAULT_VOICE_INPUT_PICKER = 844;
-
- // OPEN: Settings > Storage > [Profile]
- SETTINGS_STORAGE_PROFILE = 845;
-
- // OPEN: Settings > Security & screen lock -> Encryption & crendentials
- // CATEGORY: SETTINGS
- // OS: O
- ENCRYPTION_AND_CREDENTIAL = 846;
-
- // OPEN: Settings > Wi-Fi > Network Details (click on Access Point)
- // CATEGORY: SETTINGS
- // OS: O
- WIFI_NETWORK_DETAILS = 849;
-
- // OPEN: Settings > Wi-Fi > Wifi Preferences -> Advanced -> Network Scorer
- // CATEGORY: SETTINGS
- // OS: O
- SETTINGS_NETWORK_SCORER = 861;
-
- // OPEN: Settings > About device > Model > Hardware info dialog
- DIALOG_SETTINGS_HARDWARE_INFO = 862;
-
- // OPEN: Settings > Security & screen lock -> Lock screen preferences
- // CATEGORY: SETTINGS
- SETTINGS_LOCK_SCREEN_PREFERENCES = 882;
-
-
- // OPEN: Settings -> Display -> When in VR Mode
- VR_DISPLAY_PREFERENCE = 921;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: O
- ACCESSIBILITY_SCREEN_MAGNIFICATION_SETTINGS = 922;
-
- // OPEN: Settings -> System -> Reset options
- RESET_DASHBOARD = 924;
-
- // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
- // CATEGORY: SETTINGS
- // OS: O
- FINGERPRINT_REMOVE_SIDECAR = 934;
-
- // OPEN: Settings > Storage > Movies & TV
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_MOVIES = 935;
-
- // OPEN: Settings > Security > Managed Device Info > Apps installed
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_INSTALLED_APPS = 938;
-
- // OPEN: Settings > Security > Managed Device Info > nnn permissions
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_PERMISSIONS = 939;
-
-
- // OPEN: Settings > Security > Managed Device Info > Default apps
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_DEFAULT_APPS = 940;
-
- // OPEN: Choose screen lock dialog in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_CHOOSE_LOCK_DIALOG = 990;
-
- // OPEN: Settings > System > Languages & input > Assist gesture
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE = 996;
-
- // OPEN: Settings > Connected Devices > Bluetooth > (click on details link for a paired device)
- BLUETOOTH_DEVICE_DETAILS = 1009;
-
- // OPEN: Settings > credential pages - prompt for key guard configuration confirmation
- CONFIGURE_KEYGUARD_DIALOG = 1010;
-
- // OPEN: Settings > Network > Tether > Wi-Fi hotspot
- WIFI_TETHER_SETTINGS = 1014;
-
- // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
- // -> Edit name button.
- // CATEGORY: SETTINGS
- // OS: O DR
- DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME = 1015;
-
- // OPEN: Settings > Connected devices > Bluetooth > Pair new device
- // CATEGORY: SETTINGS
- // OS: O DR
- BLUETOOTH_PAIRING = 1018;
-
- // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
- // -> Forget button.
- // CATEGORY: SETTINGS
- // OS: O DR
- DIALOG_BLUETOOTH_PAIRED_DEVICE_FORGET = 1031;
-
- // OPEN: Settings > Storage > Photos & Videos
- // CATEGORY: SETTINGS
- // OS: O MR
- APPLICATIONS_STORAGE_PHOTOS = 1092;
-
- // OPEN: Settings > Display > Colors
- // CATEGORY: SETTINGS
- // OS: O MR
- COLOR_MODE_SETTINGS = 1143;
-
- // OPEN: Settings > Developer Options > Experiment dashboard
- // CATEGORY: SETTINGS
- SETTINGS_FEATURE_FLAGS_DASHBOARD = 1217;
-
- // OPEN: Settings > Notifications > [App] > Topic Notifications
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_CHANNEL_GROUP = 1218;
-
- // OPEN: Settings > Developer options > Enable > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_DEVELOPMENT_OPTIONS = 1219;
-
- // OPEN: Settings > Developer options > OEM unlocking > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_OEM_UNLOCKING = 1220;
-
- // OPEN: Settings > Developer options > USB debugging > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_ADB = 1222;
-
- // OPEN: Settings > Security > Nexus Imprint > [Fingerprint]
- // CATEGORY: SETTINGS
- // OS: P
- FINGERPRINT_AUTHENTICATE_SIDECAR = 1221;
-
- // OPEN: Settings > Developer options > Revoke USB debugging authorizations > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_CLEAR_ADB_KEYS = 1223;
-
- // Open: Settings > Developer options > Quick setting tile config
- // CATEGORY: SETTINGS
- // OS: P
- DEVELOPMENT_QS_TILE_CONFIG = 1224;
-
- // OPEN: Settings > Developer options > Store logger data persistently on device > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_LOG_PERSIST = 1225;
-
- // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling
- // CATEGORY: SETTINGS
- // OS: P
- WIFI_CALLING_FOR_SUB = 1230;
-
- // Open: Settings > Dev options > Oem unlock > lock it > warning dialog.
- // OS: P
- DIALOG_OEM_LOCK_INFO = 1238;
-
- // Open: Settings > System > About phone > IMEI
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_IMEI_INFO = 1240;
-
- // OPEN: Settings > System > About Phone > Sim status
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SIM_STATUS = 1246;
-
- // OPEN: Settings > System > About Phone > Android Version
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_FIRMWARE_VERSION = 1247;
-
- // OPEN: Settings > Battery(version 2)
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_POWER_USAGE_SUMMARY_V2 = 1263;
-
- // OPEN: Settings > Connected devices > Connection preferences
- // CATEGORY: SETTINGS
- // OS: P
- CONNECTION_DEVICE_ADVANCED = 1264;
-
- // OPEN: Settings > Security > Screen lock gear icon
- // CATEGORY: SETTINGS
- // OS: P
- SCREEN_LOCK_SETTINGS = 1265;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Delete rule (trash can icon)
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_DELETE_RULE_DIALOG = 1266;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule > Event/Time
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG = 1269;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG = 1270;
-
- // OPEN: Settings > Battery > Smart Battery
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_SMART_BATTERY = 1281;
-
- // OPEN: Settings > Battery > Smart Battery > Restricted apps
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_RESTRICTED_APP_DETAILS = 1285;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > Turn on now
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_ENABLE_DIALOG = 1286;
-
- // OPEN: Settings->Connected Devices->USB->(click on details link)
- // CATEGORY: SETTINGS
- // OS: P
- USB_DEVICE_DETAILS = 1291;
-
- // OPEN: Settings > Accessibility > Vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION = 1292;
-
- // OPEN: Settings > Accessibility > Vibration > Notification vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION_NOTIFICATION = 1293;
-
- // OPEN: Settings > Accessibility > Vibration > Touch vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION_TOUCH = 1294;
-
- // OPEN: Settings->Developer Options->Default USB
- // CATEGORY: SETTINGS
- // OS: P
- USB_DEFAULT = 1312;
-
- // OPEN: Settings > Battery > Battery tip > Battery tip Dialog
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_BATTERY_TIP_DIALOG = 1323;
-
- // OPEN: DND Settings > What to block
- // OS: P
- ZEN_WHAT_TO_BLOCK = 1339;
-
- // OPEN: Settings > Sounds > Do Not Disturb > Duration
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_DURATION_DIALOG = 1341;
-
- // OPEN: Settings > Date & time > Select time zone -> Region
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_REGION = 1355;
-
- // OPEN: Settings > Date & time > Select time zone -> Time Zone
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_TIME_ZONE = 1356;
- // OPEN: Settings > Date & time > Select time zone -> Select UTC Offset
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_FIXED_OFFSET = 1357;
-
- // OPEN: Settings > Gestures > Prevent Ringing
- // OS: P
- SETTINGS_PREVENT_RINGING = 1360;
-
- // Settings > Condition > Device muted
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_CONDITION_DEVICE_MUTED = 1368;
-
- // Settings > Condition > Device vibrate
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_CONDITION_DEVICE_VIBRATE = 1369;
-
- // OPEN: Settings > Connected devices > previously connected devices
- // CATEGORY: SETTINGS
- // OS: P
- PREVIOUSLY_CONNECTED_DEVICES = 1370;
-
- // OPEN: Settings > Network & Internet > Wi-Fi > Wi-Fi Preferences > Turn on Wi-Fi automatically
- // note: Wifi Scanning must be off for this dialog to show
- // CATEGORY: SETTINGS
- // OS: P
- WIFI_SCANNING_NEEDED_DIALOG = 1373;
-
- // OPEN: Settings > System > Gestures > System navigation
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_GESTURE_SWIPE_UP = 1374;
-
- // OPEN: Settings > Storage > Dialog to format a storage volume
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_VOLUME_FORMAT = 1375;
-
- // OPEN: DND onboarding activity
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZEN_ONBOARDING = 1380;
-
- // OPEN: Settings > Display > Auto brightness
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_AUTO_BRIGHTNESS = 1381;
-
- // OPEN: Settings > Connected Devices > Bluetooth
- // CATEGORY: SETTINGS
- // OS: P
- BLUETOOTH_FRAGMENT = 1390;
-
- // Screen: DND Settings > Notifications
- // OS: P
- SETTINGS_ZEN_NOTIFICATIONS = 1400;
-
- // An event category for slices.
- // OPEN: Slice became visible.
- // CLOSE: Slice became invisible.
- // ACTION: Slice was tapped.
- SLICE = 1401;
-
- // OPEN: Settings -> Developer Options -> Disable Bluetooth A2DP hardware
- // offload
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD = 1441;
-
- // OPEN: Settings homepage
- SETTINGS_HOMEPAGE = 1502;
-
- // OPEN: Settings > Create shortcut(widget)
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_CREATE_SHORTCUT = 1503;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_INTRO = 1506;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_ENROLLING = 1507;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_FINISHED = 1508;
-
- // OPEN: Face Enroll sidecar
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_SIDECAR = 1509;
-
- // OPEN: Settings > Add face > Error dialog
- // OS: Q
- DIALOG_FACE_ERROR = 1510;
-
- // OPEN: Settings > Security > Face
- // CATEGORY: SETTINGS
- // OS: Q
- FACE = 1511;
-
- // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog
- // CATEGORY: SETTINGS
- // OS: Q
- DIALOG_ACCESSIBILITY_HEARINGAID = 1512;
-
- // OPEN: Settings > Add face
- // OS: Q
- FACE_ENROLL_PREVIEW = 1554;
-
- // OPEN: Settings > Network & Internet > Wi-Fi > Add network
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_WIFI_ADD_NETWORK = 1556;
-
- // OPEN: Settings > System > Input & Gesture > Reach up gesture
- // OS: Q
- SETTINGS_GESTURE_WAKE_LOCK_SCREEN = 1557;
-
- // OPEN: Settings > System > Input & Gesture > Wake screen
- SETTINGS_GESTURE_WAKE_SCREEN = 1570;
-
- // OPEN: Settings > Network & internet > Mobile network
- MOBILE_NETWORK = 1571;
-
- // OPEN: Settings > Network & internet > Mobile network > Choose network
- MOBILE_NETWORK_SELECT = 1581;
-
- // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog
- MOBILE_DATA_DIALOG = 1582;
-
- // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog
- MOBILE_ROAMING_DIALOG = 1583;
-
- // Settings > Display > Lock screen display > On lock screen
- LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
-
- // ConfirmDeviceCredentials > BiometricPrompt
- BIOMETRIC_FRAGMENT = 1585;
-
- // OPEN: Biometric Enrollment (android.settings.BIOMETRIC_ENROLL action intent)
- BIOMETRIC_ENROLL_ACTIVITY = 1586;
-
- // OPEN: Settings > Privacy
- TOP_LEVEL_PRIVACY = 1587;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
- // Allow apps to override
- // CATEGORY: SETTINGS
- // OS: Q
- NOTIFICATION_ZEN_MODE_OVERRIDING_APPS = 1588;
-
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
- // Allow apps to override > Choose app
- // CATEGORY: SETTINGS
- // OS: Q
- NOTIFICATION_ZEN_MODE_OVERRIDING_APP = 1589;
-
- // OPEN: Settings > Developer options > Disable > Info dialog
- DIALOG_DISABLE_DEVELOPMENT_OPTIONS = 1591;
-
- // OPEN: WifiDppConfiguratorActivity (android.settings.WIFI_DPP_CONFIGURATOR_XXX action intents)
- SETTINGS_WIFI_DPP_CONFIGURATOR = 1595;
-
- // OPEN: WifiDppEnrolleeActivity (android.settings.WIFI_DPP_ENROLLEE_XXX action intents)
- SETTINGS_WIFI_DPP_ENROLLEE = 1596;
-
- // OPEN: Settings > Apps & Notifications -> Special app access -> Financial Apps Sms Access
- SETTINGS_FINANCIAL_APPS_SMS_ACCESS = 1597;
-
-
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_SETTINGS = 1604;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Custom
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_SOUND_SETTINGS = 1605;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_DEFAULT_SETTINGS = 1606;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS = 1608;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_VIS_EFFECTS = 1609;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom > Allow messages
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_MESSAGES = 1610;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom > Allow calls
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_CALLS = 1611;
-
- // OPEN: Settings > Sound > Do Not Disturb > Click footer link if custom settings applied
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_SETTINGS_DIALOG = 1612;
-
- // OPEN: Settings > Developer Options > Game Driver Preferences
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_GAME_DRIVER_DASHBOARD = 1613;
-
- // OPEN: Settings > Accessibility > Vibration > Ring vibration
- // CATEGORY: SETTINGS
- // OS: Q
- ACCESSIBILITY_VIBRATION_RING = 1620;
-
- // OPEN: Settings > System > Input & Gesture > Skip songs
- SETTINGS_GESTURE_SKIP = 1624;
-
- // OPEN: Settings > System > Input & Gesture > Silence alerts
- SETTINGS_GESTURE_SILENCE = 1625;
-
- // OPEN: Settings > System > Input & Gesture > Tap to check
- SETTINGS_GESTURE_TAP_SCREEN = 1626;
-
- // OPEN: Settings > Network & internet > Click Mobile network to land on a page with a list of
- // SIM/eSIM subscriptions.
- MOBILE_NETWORK_LIST = 1627;
-
- // OPEN: Settings > Display > Adaptive sleep
- // OS: Q
- SETTINGS_ADAPTIVE_SLEEP = 1628;
-
- // OPEN: Settings > System > Aware
- SETTINGS_AWARE = 1632;
-
- // OPEN: Settings > System > Aware > Disable > Dialog
- DIALOG_AWARE_DISABLE = 1633;
-
- // OPEN: Settings > Settings > Network & internet > Click Mobile network to land on page with
- // details for a SIM/eSIM mobile network > Click edit icon to bring up a rename dialog.
- // OS: Q
- MOBILE_NETWORK_RENAME_DIALOG = 1642;
-
- // OPEN: Set new password (android.app.action.SET_NEW_PASSWORD action intent)
- // CATEGORY: SETTINGS
- // OS: Q
- SET_NEW_PASSWORD_ACTIVITY = 1644;
-
- // Panel for Internet Connectivity
- PANEL_INTERNET_CONNECTIVITY = 1654;
-
- // Panel for Volume
- PANEL_VOLUME = 1655;
-
- // Panel for NFC
- PANEL_NFC = 1656;
-
- // Panel for Media Output
- PANEL_MEDIA_OUTPUT = 1657;
-
- // Mapping: go/at-mapping
- PAGE_ATSSI = 1667;
-
- PAGE_ATSII = 1668;
-
- PAGE_ATUS = 1669;
-
- PAGE_ATSSP = 1670;
-
- PAGE_ATSAP = 1671;
-
- PAGE_ATSCP = 1672;
-
- PAGE_ATHNP = 1673;
-
- // OPEN: Accessibility detail settings (android.settings.ACCESSIBILITY_DETAILS_SETTINGS intent)
- ACCESSIBILITY_DETAILS_SETTINGS = 1682;
-
- // Open: Settings will show the conditional when Grayscale mode is on
- SETTINGS_CONDITION_GRAYSCALE_MODE = 1683;
-
- // Panel for Wifi
- PANEL_WIFI = 1687;
-
- // Open: Settings > Special App Access > Do not disturb control for app
- ZEN_ACCESS_DETAIL = 1692;
-
- // OPEN: Settings > Face > Remove face
- // OS: Q
- DIALOG_FACE_REMOVE = 1693;
-
- // Settings > Display > Theme
- DARK_UI_SETTINGS = 1698;
-
- // Settings > global bubble settings
- BUBBLE_SETTINGS = 1699;
-
- // Settings > app > bubble settings
- APP_BUBBLE_SETTINGS = 1700;
-
- // OPEN: Settings > System > Aware > Info dialog
- DIALOG_AWARE_STATUS = 1701;
-
- // Open: Settings > app > bubble settings > confirmation dialog
- DIALOG_APP_BUBBLE_SETTINGS = 1702;
-
- // OPEN: Settings > Pick SIM dialog
- DIALOG_SIM_LIST = 1707;
-
- // OPEN: Settings > Pick SIM (that supports calling) dialog
- DIALOG_CALL_SIM_LIST = 1708;
-
- // OPEN: Settings > Pick preferred SIM dialog
- DIALOG_PREFERRED_SIM_PICKER = 1709;
-
- // OPEN: Settings > Network & internet > Mobile network > Delete sim
- DIALOG_DELETE_SIM_CONFIRMATION = 1713;
-
- // OPEN: Settings > Network & internet > Mobile network > Delete sim > (answer yes to
- // confirmation)
- DIALOG_DELETE_SIM_PROGRESS = 1714;
-
- // Settings > Apps and notifications > Notifications > Gentle notifications
- GENTLE_NOTIFICATIONS_SCREEN = 1715;
-
- // OPEN: Settings > System > Gestures > Global Actions Panel
- // CATEGORY: SETTINGS
- // OS: Q
- GLOBAL_ACTIONS_PANEL_SETTINGS = 1728;
-
- // OPEN: Settings > Display > Dark Theme
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Only shows up on first time toggle
- DIALOG_DARK_UI_INFO = 1740;
-
- // OPEN: Settings > About phone > Legal information > Google Play system update licenses
- // CATEGORY: SETTINGS
- // OS: Q
- MODULE_LICENSES_DASHBOARD = 1746;
-
- // OPEN: Settings > System > Gestures > System navigation > Info icon
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Info icon is visible only when gesture navigation is not available and disabled
- SETTINGS_GESTURE_NAV_NOT_AVAILABLE_DLG = 1747;
-
- // OPEN: Settings > System > Gestures > System navigation > Gear icon
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
- SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
-
- // OPEN: Settings > System > Aware > Aware Display
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_AWARE_DISPLAY = 1750;
-
- // OPEN: Settings > System > Input & Gesture > tap gesture
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_GESTURE_TAP = 1751;
- // ---- End Q Constants, all Q constants go above this line ----
- // OPEN: Settings > Network & Internet > Wi-Fi > Click new network
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_WIFI_CONFIGURE_NETWORK = 1800;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: R
- // Note: Shows up only when Magnify with shortcut is enabled
- // and under accessibility button mode.
- DIALOG_TOGGLE_SCREEN_MAGNIFICATION_ACCESSIBILITY_BUTTON = 1801;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: R
- // Note: Shows up only when Magnify with shortcut is enabled.
- // and under gesture navigation mode.
- DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION = 1802;
-
- // OPEN: Settings > Security & screen lock -> Encryption & credentials > Install a certificate
- // CATEGORY: SETTINGS
- // OS: R
- INSTALL_CERTIFICATE_FROM_STORAGE = 1803;
-
- // OPEN: Settings > Apps and notifications > Special app access > notification access >
- // an app
- // CATEGORY: SETTINGS
- // OS: R
- NOTIFICATION_ACCESS_DETAIL = 1804;
-
- // OPEN: Settings > Developer Options > Platform Compat
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_PLATFORM_COMPAT_DASHBOARD = 1805;
-
- // OPEN: Settings > Location -> Work profile tab
- // CATEGORY: SETTINGS
- // OS: R
- LOCATION_WORK = 1806;
-
- // OPEN: Settings > Account -> Work profile tab
- // CATEGORY: SETTINGS
- // OS: R
- ACCOUNT_WORK = 1807;
-
- // OPEN: Settings > Developer Options > Bug report handler
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_BUGREPORT_HANDLER = 1808;
-
- // Panel for adding Wi-Fi networks
- // CATEGORY: SETTINGS
- // OS: R
- PANEL_ADD_WIFI_NETWORKS = 1809;
-
- // OPEN: Settings > Accessibility > Enable the feature or shortcut > Show tutorial dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_ACCESSIBILITY_TUTORIAL = 1810;
-
- // OPEN: Settings > Accessibility > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_ACCESSIBILITY_SERVICE_EDIT_SHORTCUT = 1812;
-
- // OPEN: Settings > Accessibility > Magnification > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_MAGNIFICATION_EDIT_SHORTCUT = 1813;
-
- // OPEN: Settings > Accessibility > Color correction > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_DALTONIZER_EDIT_SHORTCUT = 1814;
-
- // OPEN: Settings > Accessibility > Magnification > Settings
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_MAGNIFICATION_SETTINGS = 1815;
-
- // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_MAGNIFICATION_CAPABILITY = 1816;
-
- // OPEN: Settings > Accessibility > Color inversion
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_COLOR_INVERSION_SETTINGS = 1817;
-
- // OPEN: Settings > Accessibility > Color inversion > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_COLOR_INVERSION_EDIT_SHORTCUT = 1818;
-
- // OPEN: Settings > Accessibility > Captions preference > Captions appearance
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_CAPTION_APPEARANCE = 1819;
-
- // OPEN: Settings > Accessibility > Captions preference > More options
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_CAPTION_MORE_OPTIONS = 1820;
-
- // OPEN: Settings > Battery > Battery share
- // CATEGORY: SETTINGS
- // OS: R
- FUELGAUGE_BATTERY_SHARE = 1821;
-
- // OPEN: Settings -> Apps & Notifications -> Special App Access
- // CATEGORY: SETTINGS
- // OS: R
- MANAGE_EXTERNAL_STORAGE = 1822;
-
- // Open: Settings > DND > People
- // OS: R
- DND_PEOPLE = 1823;
-
- // OPEN: Settings > Apps and notifications > App info > one of any app > Open by default
- // > Open supported links
- // CATEGORY: SETTINGS
- // OS: R
- OPEN_SUPPORTED_LINKS = 1824;
-
- // OPEN: Settings > Display > Dark theme > Set start time dialog
- DIALOG_DARK_THEME_SET_START_TIME = 1825;
-
- // OPEN: Settings > Display > Dark theme > Set end time dialog
- DIALOG_DARK_THEME_SET_END_TIME = 1826;
-
- // OPEN: Settings -> Sound -> Vibrate for calls
- // CATEGORY: SETTINGS
- // OS: R
- VIBRATE_FOR_CALLS = 1827;
-
- // OPEN: Settings > Connected devices > Connection preferences > NFC
- // CATEGORY: SETTINGS
- // OS: R
- CONNECTION_DEVICE_ADVANCED_NFC = 1828;
-
- // OPEN: Settings -> Apps & Notifications -> Special App Access
- INTERACT_ACROSS_PROFILES = 1829;
-
- // OPEN: Settings > Notifications > (app or conversations) > conversation
- NOTIFICATION_CONVERSATION_SETTINGS = 1830;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_ADB_WIRELESS = 1831;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Pair device with pairing code > Pairing code dialog
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_PAIRING_DIALOG = 1832;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Pair device with QR code > Scan QR code > Pairing device dialog
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_QR_PAIRING_DIALOG = 1833;
-
- // OPEN: Settings > apps & notifications > notifications > conversations
- // CATEGORY: SETTINGS
- // OS: R
- NOTIFICATION_CONVERSATION_LIST_SETTINGS = 1834;
-
- // Panel for Media Output Group operation
- // CATEGORY: SETTINGS
- // OS: R
- PANEL_MEDIA_OUTPUT_GROUP = 1835;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Click on paired device
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_DETAILS = 1836;
-
- // Open: Settings > Sound > Do Not Disturb > People > Conversations
- // OS: R
- DND_CONVERSATIONS = 1837;
-
- // Open: Settings > Sound > Do Not Disturb > People > Calls
- // OS: R
- DND_CALLS = 1838;
-
- // Open: Settings > Sound > Do Not Disturb > People > Messages
- // OS: R
- DND_MESSAGES = 1839;
-
- // Open: Settings > Sound > Do Not Disturb > Apps > <Choose App>
- // OS: R
- DND_APPS_BYPASSING = 1840;
-
- // OPEN: Settings > Battery > Advanced battery option
- // CATEGORY: SETTINGS
- // OS: R
- FUELGAUGE_ADVANCED_BATTERY_OPTION = 1842;
-
- // OPEN: Settings > System > Gestures > Power menu
- // CATEGORY: SETTINGS
- // OS: R
- POWER_MENU_SETTINGS = 1843;
-
- // OPEN: Settings > System > Gestures > Power menu > Device controls
- // CATEGORY: SETTINGS
- // OS: R
- DEVICE_CONTROLS_SETTINGS = 1844;
-
- // OPEN: Settings > Sound > Media
- // CATEGORY: SETTINGS
- // OS: R
- MEDIA_CONTROLS_SETTINGS = 1845;
-}
diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto
deleted file mode 100644
index 31c5dd6b730a..000000000000
--- a/core/proto/android/app/tvsettings_enums.proto
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.tvsettings;
-option java_multiple_files = true;
-option java_outer_classname = "TvSettingsEnums";
-
-/** The performed action types */
-enum Action {
-
- /**
- * Denotes an unknown action. It is a filler that should generally be
- * avoided.
- */
- ACTION_UNKNOWN = 0;
-
- /**
- * Denotes that a TvSettings page is being focused. (Previewing a page in
- * two panel settings should NOT be considered as focusing on the page.)
- */
- PAGE_FOCUSED = 1;
-
- /**
- * Denotes that an entry (typically a leaf node of settings tree) is
- * selected by a user.
- */
- ENTRY_SELECTED = 2;
-
- /** Denotes that a toggle is clicked by a user. */
- TOGGLE_INTERACTED = 3;
-
- /**
- * Denotes that a TvSettings page is being focused in the forward direction
- * into the settings tree.
- */
- PAGE_FOCUSED_FORWARD = 4;
-
- /**
- * Denotes that a TvSettings page is being focused in the backward direction
- * up the settings tree.
- */
- PAGE_FOCUSED_BACKWARD = 5;
-
- /** Denotes that a toggle is turned on by a user. */
- TOGGLED_ON = 6;
-
- /** Denotes that a toggle is turned off by a user. */
- TOGGLED_OFF = 7;
-
-}
-
-/**
- * Ids for TvSettings focusable pages or actionable entries
- *
- * For details of the scheme, please refer to the "Definition of item_id" and
- * "Evolve of item_id" sections in go/atv-settings-ww-logging-design.
- */
-enum ItemId {
-
- option allow_alias = true;
-
- // Filler that should be avoided
- UNKNOWN = 0x00000000;
-
- // TvSettings
- TV_SETTINGS_ROOT = 0x00000001;
-
- // TvSettings unknown/default classic page
- PAGE_CLASSIC_DEFAULT = 0x00000002;
-
- // TvSettings unknown/default slice page
- PAGE_SLICE_DEFAULT = 0x00000003;
-
- // TvSettings unknown/default entry
- ENTRY_DEFAULT = 0x00000004;
-
- // TvSettings > Suggested settings entry
- SUGGESTED_SETTINGS = 0x00000010;
-
- // TvSettings > Quick Settings
- QUICK_SETTINGS = 0x00000011;
-
- // VERSION 1: Starting with Q
- // These are ordered in depth-first search manner.
-
- // TvSettings > Network & Internet
- NETWORK = 0x11000000;
-
- // TvSettings > Network & Internet > Wi-Fi (toggle)
- NETWORK_WIFI_ON_OFF = 0x11100000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list]
- NETWORK_AP_INFO = 0x11200000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > Proxy settings
- NETWORK_AP_INFO_PROXY_SETTINGS = 0x11210000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > IP settings
- NETWORK_AP_INFO_IP_SETTINGS = 0x11220000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > Forget network
- NETWORK_AP_INFO_FORGET_NETWORK = 0x11230000;
-
- // TvSettings > Network & Internet >
- // [A not connected network entry in available networks list]
- NETWORK_NOT_CONNECTED_AP = 0x11300000;
-
- // TvSettings > Network & Internet > See all
- NETWORK_SEE_ALL = 0x11400000;
-
- // TvSettings > Network & Internet > See fewer
- NETWORK_SEE_FEWER = 0x11500000;
-
- // TvSettings > Network & Internet > Add new network
- NETWORK_ADD_NEW_NETWORK = 0x11600000;
-
- // TvSettings > Network & Internet > Scanning always available (toggle)
- NETWORK_ALWAYS_SCANNING_NETWORKS = 0x11700000;
-
- // TvSettings > Network & Internet > Proxy settings (in Ethernet category)
- NETWORK_ETHERNET_PROXY_SETTINGS = 0x11800000;
-
- // TvSettings > Network & Internet > IP settings (in Ethernet category)
- NETWORK_ETHERNET_IP_SETTINGS = 0x11900000;
-
- // TvSettings > Account & Sign In (Slice)
- ACCOUNT_SLICE = 0x12000000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account]
- ACCOUNT_SLICE_REG_ACCOUNT = 0x12100000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT = 0x12130000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > SafeSearch filter (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH = 0x12131000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Block offensive words (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Searchable apps
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS = 0x12133000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Personal results (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_PERSONAL_RESULTS = 0x12134000;
-
- // Reserving [0x12140000, 0x12190000] for possible future settings
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] > Remove
- ACCOUNT_SLICE_REG_ACCOUNT_REMOVE = 0x121A0000;
-
- // Reserving [0x12200000, 0x12900000] for possible future settings
-
- // TvSettings > Account & Sign In (Slice) > Add account...
- ACCOUNT_SLICE_ADD_ACCOUNT = 0x12A00000;
-
- // TvSettings > Account & Sign In (Classic)
- ACCOUNT_CLASSIC = 0x13000000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account]
- ACCOUNT_CLASSIC_REG_ACCOUNT = 0x13100000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] > Sync now
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_NOW = 0x13110000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // Remove account
- ACCOUNT_CLASSIC_REG_ACCOUNT_REMOVE_ACCOUNT = 0x13120000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Calendar (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CALENDAR = 0x13130000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Contacts (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CONTACTS = 0x13140000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Google Play Movies & TV (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPMT = 0x13150000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Google Play Music (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPM = 0x13160000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] People details (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_PEOPLE = 0x13170000;
-
- // Reserving [0x13200000, 0x13900000] for possible future settings
-
- // TvSettings > Account & Sign In (Classic) > Add account
- ACCOUNT_CLASSIC_ADD_ACCOUNT = 0x13A00000;
-
- // TvSettings > Display & Sound
- DISPLAY_SOUND = 0x15000000;
-
- // TvSettings > Display & Sound > Advanced display settings
- DISPLAY_SOUND_ADVANCED_DISPLAY = 0x15100000;
-
- // TvSettings > Display & Sound > Advanced display settings >
- // Allow game mode (toggle)
- DISPLAY_SOUND_ADVANCED_DISPLAY_GAME_MODE = 0x15110000;
-
- // TvSettings > Display & Sound > System sounds (toggle)
- DISPLAY_SOUND_SYSTEM_SOUNDS = 0x15200000;
-
- // TvSettings > Display & Sound > Advanced sound settings
- DISPLAY_SOUND_ADVANCED_SOUNDS = 0x15300000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS = 0x15310000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // Auto...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_AUTO = 0x15311000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // None...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_NONE = 0x15312000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // Manual...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_MANUAL = 0x15313000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby AC-4 (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DAC4 = 0x15320000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Atmos in Dolby Digital Plus (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DADDP = 0x15330000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Digital (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DD = 0x15340000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Digital Plus (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DDP = 0x15350000;
-
- // TvSettings > Display & Sound > Advanced sound settings > DTS (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTS = 0x15360000;
-
- // TvSettings > Display & Sound > Advanced sound settings > DTS-HD (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTSHD = 0x15370000;
-
- // TvSettings > Display & Sound > Advanced sound settings > AAC (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_AAC = 0x15380000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby TrueHD (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTHD = 0x15390000;
-
- // TvSettings > Apps
- APPS = 0x16000000;
-
- // TvSettings > Apps > See all apps
- APPS_ALL_APPS = 0x16100000;
-
- // TvSettings > Apps > See all apps > [An app entry]
- APPS_ALL_APPS_APP_ENTRY = 0x16110000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Open
- APPS_ALL_APPS_APP_ENTRY_OPEN = 0x16111000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Force stop
- APPS_ALL_APPS_APP_ENTRY_FORCE_STOP = 0x16112000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Uninstall
- APPS_ALL_APPS_APP_ENTRY_UNINSTALL = 0x16113000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Uninstall updates
- APPS_ALL_APPS_APP_ENTRY_UNINSTALL_UPDATES = 0x16114000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Disable
- APPS_ALL_APPS_APP_ENTRY_DISABLE = 0x16115000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear data
- APPS_ALL_APPS_APP_ENTRY_CLEAR_DATA = 0x16116000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear cache
- APPS_ALL_APPS_APP_ENTRY_CLEAR_CACHE = 0x16117000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear defaults
- APPS_ALL_APPS_APP_ENTRY_CLEAR_DEFAULTS = 0x16118000;
-
- // TvSettings > Apps > See all apps > [An app entry] >
- // Notifications (toggle)
- APPS_ALL_APPS_APP_ENTRY_NOTIFICATIONS = 0x16119000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Permissions
- APPS_ALL_APPS_APP_ENTRY_PERMISSIONS = 0x1611A000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Enable
- APPS_ALL_APPS_APP_ENTRY_ENABLE = 0x1611B000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Open source licenses
- APPS_ALL_APPS_APP_ENTRY_LICENSES = 0x1611C000;
-
- // TvSettings > Apps > See all apps > Show system apps
- APPS_ALL_APPS_SHOW_SYSTEM_APPS = 0x16120000;
-
- // TvSettings > Apps > App permissions
- APPS_APP_PERMISSIONS = 0x16200000;
-
- // TvSettings > Apps > App permission > Body sensors
- APPS_APP_PERMISSIONS_BODY_SENSORS = 0x16210000;
-
- // TvSettings > Apps > App permission > Calendar
- APPS_APP_PERMISSIONS_CALENDAR = 0x16220000;
-
- // TvSettings > Apps > App permission > Call logs
- APPS_APP_PERMISSIONS_CALL_LOGS = 0x16230000;
-
- // TvSettings > Apps > App permission > Camera
- APPS_APP_PERMISSIONS_CAMERA = 0x16240000;
-
- // TvSettings > Apps > App permission > Contacts
- APPS_APP_PERMISSIONS_CONTACTS = 0x16250000;
-
- // TvSettings > Apps > App permission > Location
- APPS_APP_PERMISSIONS_LOCATION = 0x16260000;
-
- // TvSettings > Apps > App permission > Microphone
- APPS_APP_PERMISSIONS_MICROPHONE = 0x16270000;
-
- // TvSettings > Apps > App permission > Phone
- APPS_APP_PERMISSIONS_PHONE = 0x16280000;
-
- // TvSettings > Apps > App permission > Physical activity
- APPS_APP_PERMISSIONS_PHYSICAL_ACTIVITY = 0x16290000;
-
- // TvSettings > Apps > App permission > SMS
- APPS_APP_PERMISSIONS_SMS = 0x162A0000;
-
- // TvSettings > Apps > App permission > Storage
- APPS_APP_PERMISSIONS_STORAGE = 0x162B0000;
-
- // TvSettings > Apps > App permission > Additional permissions
- APPS_APP_PERMISSIONS_ADDITIONAL = 0x162C0000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // real all TV listings
- APPS_APP_PERMISSIONS_ADDITIONAL_READ_TV_LISTINGS = 0x162C1000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // real instant messages
- APPS_APP_PERMISSIONS_ADDITIONAL_READ_INSTANT_MESSAGES = 0x162C2000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // write instant messages
- APPS_APP_PERMISSIONS_ADDITIONAL_WRITE_INSTANT_MESSAGES = 0x162C3000;
-
- // TvSettings > Apps > Special app access
- APPS_SPECIAL_APP_ACCESS = 0x16300000;
-
- // TvSettings > Apps > Special app access > Energy optimization
- APPS_SPECIAL_APP_ACCESS_ENERGY_OPTIMIZATION = 0x16310000;
-
- // TvSettings > Apps > Special app access > Usage access
- APPS_SPECIAL_APP_ACCESS_USAGE_ACCESS = 0x16320000;
-
- // TvSettings > Apps > Special app access > Notification access
- APPS_SPECIAL_APP_ACCESS_NOTIFICATION_ACCESS = 0x16330000;
-
- // TvSettings > Apps > Special app access > Display over other apps
- APPS_SPECIAL_APP_ACCESS_DISPLAY_OVER_OTHERS = 0x16340000;
-
- // TvSettings > Apps > Special app access > Modify system settings
- APPS_SPECIAL_APP_ACCESS_MODIFY_SYSTEM_SETTINGS = 0x16350000;
-
- // TvSettings > Apps > Special app access > Picture-in-picture
- APPS_SPECIAL_APP_ACCESS_PICTURE_IN_PICTURE = 0x16360000;
-
- // TvSettings > Apps > Security & restrictions
- APPS_SECURITY_RESTRICTIONS = 0x16400000;
-
- // TvSettings > Apps > Security & restrictions > Unknown sources
- APPS_SECURITY_RESTRICTIONS_UNKNOWN_SOURCES = 0x16410000;
-
- // TvSettings > Apps > Security & restrictions > Verify apps (toggle)
- APPS_SECURITY_RESTRICTIONS_VERIFY_APPS = 0x16420000;
-
- // TvSettings > Apps > Security & restrictions > Create restricted profile
- APPS_SECURITY_RESTRICTIONS_CREATE_PROFILE = 0x16430000;
-
- // TvSettings > Apps > Security & restrictions > Enter restricted profile
- APPS_SECURITY_RESTRICTIONS_ENTER_PROFILE = 0x16440000;
-
- // TvSettings > Apps > Security & restrictions >
- // Allowed apps (Restricted Profile)
- APPS_SECURITY_RESTRICTIONS_PROFILE_ALLOWED_APPS = 0x16450000;
-
- // TvSettings > Apps > Security & restrictions >
- // Change pin (Restricted Profile)
- APPS_SECURITY_RESTRICTIONS_PROFILE_CHANGE_PIN = 0x16460000;
-
- // TvSettings > Apps > Security & restrictions >
- // Delete restricted profile
- APPS_SECURITY_RESTRICTIONS_DELETE_PROFILE = 0x16470000;
-
- // TvSettings > Apps > Security & restrictions >
- // Exit restricted profile
- APPS_SECURITY_RESTRICTIONS_EXIT_PROFILE = 0x16480000;
-
- // TvSettings > System (same as TvSettings > Device Preferences)
- SYSTEM = 0x17000000;
-
- // TvSettings > System > About
- SYSTEM_ABOUT = 0x17100000;
-
- // TvSettings > System > System update
- SYSTEM_ABOUT_SYSTEM_UPDATE = 0x17110000;
-
- // TvSettings > System > Device name
- SYSTEM_ABOUT_DEVICE_NAME = 0x17120000;
-
- // TvSettings > System > Factory reset
- SYSTEM_ABOUT_FACTORY_RESET = 0x17130000;
-
- // TvSettings > System > Status
- SYSTEM_ABOUT_STATUS = 0x17140000;
-
- // TvSettings > System > Legal information
- SYSTEM_ABOUT_LEGAL_INFO = 0x17150000;
-
- // TvSettings > System > Legal information > Open source licenses
- SYSTEM_ABOUT_LEGAL_INFO_OPEN_SOURCE = 0x17151000;
-
- // TvSettings > System > Legal information > Google legal
- SYSTEM_ABOUT_LEGAL_INFO_GOOGLE_LEGAL = 0x17152000;
-
- // TvSettings > System > Legal information > System WebView licenses
- SYSTEM_ABOUT_LEGAL_INFO_SYSTEM_WEBVIEW = 0x17153000;
-
- // TvSettings > System > Build
- SYSTEM_ABOUT_BUILD = 0x17160000;
-
- // TvSettings > System > Date & time
- SYSTEM_DATE_TIME = 0x17200000;
-
- // TvSettings > System > Date & time > Automatic data & time
- SYSTEM_DATE_TIME_AUTOMATIC = 0x17210000;
-
- // TvSettings > System > Date & time > Automatic data & time >
- // Use network-provided time
- SYSTEM_DATE_TIME_AUTOMATIC_USE_NETWORK_TIME = 0x17211000;
-
- // TvSettings > System > Date & time > Automatic data & time > Off
- SYSTEM_DATE_TIME_AUTOMATIC_OFF = 0x17212000;
-
- // TvSettings > System > Date & time > Set date
- SYSTEM_DATE_TIME_SET_DATE = 0x17220000;
-
- // TvSettings > System > Date & time > Set time
- SYSTEM_DATE_TIME_SET_TIME = 0x17230000;
-
- // TvSettings > System > Date & time > Set time zone
- SYSTEM_DATE_TIME_SET_TIME_ZONE = 0x17240000;
-
- // TvSettings > System > Date & time > Set time zone > [A time zone button]
- SYSTEM_DATE_TIME_SET_TIME_ZONE_BUTTON = 0x17241000;
-
- // TvSettings > System > Date & time > Use 24-hour format (toggle)
- SYSTEM_DATE_TIME_USE_24_HOUR_FORMAT = 0x17250000;
-
- // TvSettings > System > Language
- SYSTEM_LANGUAGE = 0x17300000;
-
- // TvSettings > System > Language > [A language button]
- SYSTEM_LANGUAGE_BUTTON = 0x17310000;
-
- // TvSettings > System > Keyboard
- SYSTEM_KEYBOARD = 0x17400000;
-
- // TvSettings > System > Keyboard > Current keyboard
- SYSTEM_KEYBOARD_CURRENT_KEYBOARD = 0x17410000;
-
- // TvSettings > System > Keyboard > Gboard Settings
- SYSTEM_KEYBOARD_GBOARD_SETTINGS = 0x17420000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Languages
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_LANGUAGES = 0x17421000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Terms of services
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_TOS = 0x17422000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Privacy policy
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_PRIVACY_POLICY = 0x17423000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Open source licenses
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_OPEN_SOURCE = 0x17424000;
-
- // TvSettings > System > Keyboard > Gboard Settings >
- // Share usage statistics (toggle)
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_SHARE_USAGE_STATS = 0x17425000;
-
- // TvSettings > System > Keyboard > Manage keyboards
- SYSTEM_KEYBOARD_MANAGE_KEYBOARDS = 0x17430000;
-
- // TvSettings > System > Storage
- SYSTEM_STORAGE = 0x17500000;
-
- // TvSettings > System > Internal shared storage
- SYSTEM_STORAGE_INTERNAL_STORAGE = 0x17510000;
-
- // TvSettings > System > Internal shared storage > Apps
- SYSTEM_STORAGE_INTERNAL_STORAGE_APPS = 0x17511000;
-
- // TvSettings > System > Internal shared storage >
- // Cached data (brings up "Clear cached data?" dialog upon click)
- SYSTEM_STORAGE_INTERNAL_STORAGE_CACHED = 0x17512000;
-
- // TvSettings > System > Energy saver
- SYSTEM_ENERGYSAVER = 0x17700000;
-
- // TvSettings > System > Energy saver > Turn off display after
- SYSTEM_ENERGYSAVER_START_DELAY = 0x17710000;
-
- // TvSettings > System > Energy saver > Turn off display after > 15 minutes
- SYSTEM_ENERGYSAVER_START_DELAY_15M = 0x17711000;
-
- // TvSettings > System > Energy saver > Turn off display after > 30 minutes
- SYSTEM_ENERGYSAVER_START_DELAY_30M = 0x17712000;
-
- // TvSettings > System > Energy saver > Turn off display after > 1 hour
- SYSTEM_ENERGYSAVER_START_DELAY_1H = 0x17713000;
-
- // TvSettings > System > Energy saver > Turn off display after > 3 hours
- SYSTEM_ENERGYSAVER_START_DELAY_3H = 0x17714000;
-
- // TvSettings > System > Energy saver > Turn off display after > 6 hours
- SYSTEM_ENERGYSAVER_START_DELAY_6H = 0x17715000;
-
- // TvSettings > System > Energy saver > Turn off display after > 12 hours
- SYSTEM_ENERGYSAVER_START_DELAY_12H = 0x17716000;
-
- // TvSettings > System > Energy saver > Turn off display after > Never
- SYSTEM_ENERGYSAVER_START_DELAY_NEVER = 0x17717000;
-
- // TvSettings > System > Accessibility
- SYSTEM_A11Y = 0x17800000;
-
- // TvSettings > System > Accessibility > Captions
- SYSTEM_A11Y_CAPTIONS = 0x17810000;
-
- // TvSettings > System > Accessibility > Captions > Display (toggle)
- SYSTEM_A11Y_CAPTIONS_DISPLAY_ON_OFF = 0x17811000;
-
- // TvSettings > System > Accessibility > Captions > Language
- SYSTEM_A11Y_CAPTIONS_LANGUAGE = 0x17812000;
-
- // TvSettings > System > Accessibility > Captions > Language > [A language]
- SYSTEM_A11Y_CAPTIONS_LANGUAGE_BUTTON = 0x17812100;
-
- // TvSettings > System > Accessibility > Captions > Text size
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE = 0x17813000;
-
- // TvSettings > System > Accessibility > Captions > Text size > Very small
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_SMALL = 0x17813100;
-
- // TvSettings > System > Accessibility > Captions > Text size > Small
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_SMALL = 0x17813200;
-
- // TvSettings > System > Accessibility > Captions > Text size > Normal
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_NORMAL = 0x17813300;
-
- // TvSettings > System > Accessibility > Captions > Text size > Large
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_LARGE = 0x17813400;
-
- // TvSettings > System > Accessibility > Captions > Text size > Very large
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_LARGE = 0x17813500;
-
- // TvSettings > System > Accessibility > Captions >
- // White on black (radio button)
- SYSTEM_A11Y_CAPTIONS_WHITE_ON_BLACK = 0x17814000;
-
- // TvSettings > System > Accessibility > Captions >
- // Black on white (radio button)
- SYSTEM_A11Y_CAPTIONS_BLACK_ON_WHITE = 0x17815000;
-
- // TvSettings > System > Accessibility > Captions >
- // Yellow on black (radio button)
- SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLACK = 0x17816000;
-
- // TvSettings > System > Accessibility > Captions >
- // Yellow on blue (radio button)
- SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLUE = 0x17817000;
-
- // TvSettings > System > Accessibility > Captions > Custom
- SYSTEM_A11Y_CAPTIONS_CUSTOM = 0x17818000;
-
- // TvSettings > System > Accessibility > Captions > Custom > Font family
- SYSTEM_A11Y_CAPTIONS_CUSTOM_FONT = 0x17818100;
-
- // TvSettings > System > Accessibility > Captions > Custom > Text color
- SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_COLOR = 0x17818200;
-
- // TvSettings > System > Accessibility > Captions > Custom > Text opacity
- SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_OPACITY = 0x17818300;
-
- // TvSettings > System > Accessibility > Captions > Custom > Edge type
- SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_TYPE = 0x17818400;
-
- // TvSettings > System > Accessibility > Captions > Custom > Edge color
- SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_COLOR = 0x17818500;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Show background (toggle)
- SYSTEM_A11Y_CAPTIONS_SHOW_BACKGROUND = 0x17818600;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Background color
- SYSTEM_A11Y_CAPTIONS_BACKGROUND_COLOR = 0x17818700;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Background opacity
- SYSTEM_A11Y_CAPTIONS_BACKGROUND_OPACITY = 0x17818800;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Show window (toggle)
- SYSTEM_A11Y_CAPTIONS_SHOW_WINDOW = 0x17818900;
-
- // TvSettings > System > Accessibility > Captions > Custom > Window color
- SYSTEM_A11Y_CAPTIONS_WINDOW_COLOR = 0x17818A00;
-
- // TvSettings > System > Accessibility > Captions > Custom > Window opacity
- SYSTEM_A11Y_CAPTIONS_WINDOW_OPACITY = 0x17818B00;
-
- // TvSettings > System > Accessibility > High contrast text (toggle)
- SYSTEM_A11Y_HIGH_CONTRAST_TEXT = 0x17820000;
-
- // TvSettings > System > Accessibility > Text to speech
- SYSTEM_A11Y_TTS = 0x17830000;
-
- // TvSettings > System > Accessibility > Text to speech > [Select an engine]
- SYSTEM_A11Y_TTS_ENGINE_SELECT = 0x17831000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration
- SYSTEM_A11Y_TTS_ENGINE_CONFIG = 0x17832000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Language
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE = 0x17832100;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Language > Button
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE_CHOOSE_LANGUAGE = 0x17832110;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Settings for Google Text-to-speech Engine
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_SETTINGS_GTTS_ENGINE = 0x17832200;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Install voice data
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_INSTALL_VOICE_DATA = 0x17832300;
-
- // TvSettings > System > Accessibility > Text to speech > Speech rate
- SYSTEM_A11Y_TTS_SPEECH_RATE = 0x17833000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Listen to an example
- SYSTEM_A11Y_TTS_LISTEN_EXAMPLE = 0x17834000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut
- SYSTEM_A11Y_SHORTCUT = 0x17840000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut >
- // Enable (toggle)
- SYSTEM_A11Y_SHORTCUT_ON_OFF = 0x17841000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut >
- // Shortcut services
- SYSTEM_A11Y_SHORTCUT_SERVICE = 0x17842000;
-
- // TvSettings > System > Accessibility > TalkBack
- SYSTEM_A11Y_TALKBACK = 0x17850000;
-
- // TvSettings > System > Accessibility > TalkBack > Enable (toggle)
- SYSTEM_A11Y_TALKBACK_ON_OFF = 0x17851000;
-
- // TvSettings > System > Accessibility > TalkBack > Configuration
- SYSTEM_A11Y_TALKBACK_CONFIG = 0x17852000;
-
- // TvSettings > System > Accessibility > Accessibility Menu
- SYSTEM_A11Y_A11Y_MENU = 0x17860000;
-
- // TvSettings > System > Accessibility > Accessibility Menu >
- // Enable (toggle)
- SYSTEM_A11Y_A11Y_MENU_ON_OFF = 0x17861000;
-
- // TvSettings > System > Accessibility > Accessibility Menu > Configuration
- SYSTEM_A11Y_A11Y_MENU_CONFIG = 0x17862000;
-
- // TvSettings > System > Accessibility > Select to Speak
- SYSTEM_A11Y_STS = 0x17870000;
-
- // TvSettings > System > Accessibility > Select to Speak > Enable (toggle)
- SYSTEM_A11Y_STS_ON_OFF = 0x17871000;
-
- // TvSettings > System > Accessibility > Select to Speak > Configuration
- SYSTEM_A11Y_STS_CONFIG = 0x17872000;
-
- // TvSettings > System > Accessibility > Switch Access
- SYSTEM_A11Y_SWITCH_ACCESS = 0x17880000;
-
- // TvSettings > System > Accessibility > Switch Access > Enable (Toggle)
- SYSTEM_A11Y_SWITCH_ACCESS_ON_OFF = 0x17881000;
-
- // TvSettings > System > Accessibility > Switch Access > Configuration
- SYSTEM_A11Y_SWITCH_ACCESS_CONFIG = 0x17882000;
-
- // TvSettings > System > Reboot
- SYSTEM_REBOOT = 0x17900000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings)
- PREFERENCES_HOME_SCREEN = 0x17A00000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS = 0x17A10000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN = 0x17A11000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > On (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_ON_OFF = 0x17A11100;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Google Play Movies & TV (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPMT = 0x17A11200;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Google Play Music (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPM = 0x17A11300;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Promotional channels (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_PROMOTIONAL = 0x17A11400;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Home screen channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_HOME_SCREEN = 0x17A12000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Promotional channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PROMOTIONAL = 0x17A13000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Enable video previews (toggle)
- PREFERENCES_HOME_SCREEN_VIDEO_PREVIEWS = 0x17A20000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Enable audio previews (toggle)
- PREFERENCES_HOME_SCREEN_AUDIO_PREVIEWS = 0x17A30000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Reorder apps
- PREFERENCES_HOME_SCREEN_REORDER_APPS = 0x17A40000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Reorder games
- PREFERENCES_HOME_SCREEN_REORDER_GAMES = 0x17A50000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Android TV Home open source licenses
- PREFERENCES_HOME_SCREEN_ATVH_OPEN_SOURCE = 0x17A60000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Android TV Core Services open source licenses
- PREFERENCES_HOME_SCREEN_ATVCS_OPEN_SOURCE = 0x17A70000;
-
- // TvSettings > Device Preferences > Google Assistant
- PREFERENCES_ASSISTANT = 0x17B00000;
-
- // TvSettings > Device Preferences > Google Assistant > Accounts
- PREFERENCES_ASSISTANT_ACCOUNTS = 0x17B10000;
-
- // TvSettings > Device Preferences > Google Assistant > Accept permissions
- PREFERENCES_ASSISTANT_ACCEPT_PERMISSIONS = 0x17B20000;
-
- // TvSettings > Device Preferences > Google Assistant > View permissions
- PREFERENCES_ASSISTANT_VIEW_PERMISSIONS = 0x17B30000;
-
- // TvSettings > Device Preferences > Google Assistant > Searchable apps
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS)
- PREFERENCES_ASSISTANT_SEARCHABLE_APPS = 0x12133000;
-
- // TvSettings > Device Preferences > Google Assistant > SafeSearch filter
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH)
- PREFERENCES_ASSISTANT_SAFESEARCH_FILTER = 0x12131000;
-
- // TvSettings > Device Preferences > Google Assistant >
- // Block offensive words
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE)
- PREFERENCES_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000;
-
- // TvSettings > Device Preferences > Google Assistant > Open source licenses
- PREFERENCES_ASSISTANT_OPEN_SOURCE = 0x17B40000;
-
- // TvSettings > Device Preferences > Chromecast Android Shell
- PREFERENCES_CHROMECAST_SHELL = 0x17C00000;
-
- // TvSettings > Device Preferences > Chromecast Android Shell >
- // Open source licenses
- PREFERENCES_CHROMECAST_SHELL_OPEN_SOURCE = 0x17C10000;
-
- // TvSettings > Device Preferences > Screen saver
- PREFERENCES_SCREENSAVER = 0x17D00000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser)
- PREFERENCES_SCREENSAVER_CHOOSER = 0x17D10000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Turn screen off
- PREFERENCES_SCREENSAVER_CHOOSER_SCREEN_OFF = 0x17D11000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Backdrop
- PREFERENCES_SCREENSAVER_CHOOSER_BACKDROP = 0x17D12000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Colors
- PREFERENCES_SCREENSAVER_CHOOSER_COLORS = 0x17D13000;
-
- // TvSettings > Device Preferences > Screen saver > When to start
- PREFERENCES_SCREENSAVER_START_DELAY = 0x17D20000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 5 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_5M = 0x17D21000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 15 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_15M = 0x17D22000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 30 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_30M = 0x17D23000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 1 hour
- PREFERENCES_SCREENSAVER_START_DELAY_1H = 0x17D24000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 2 hours
- PREFERENCES_SCREENSAVER_START_DELAY_2H = 0x17D25000;
-
- // TvSettings > Device Preferences > Screen saver > Start now
- PREFERENCES_SCREENSAVER_START_NOW = 0x17D30000;
-
- // TvSettings > Connected Devices (Slice)
- CONNECTED_SLICE = 0x18000000;
-
- // TvSettings > Connected Devices (Slice) > Connect remote or headphones
- CONNECTED_SLICE_CONNECT_NEW_DEVICES = 0x18100000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device]
- CONNECTED_SLICE_DEVICE_ENTRY = 0x18200000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] >
- // Remote update
- CONNECTED_SLICE_DEVICE_ENTRY_UPDATE = 0x18210000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] > Rename
- CONNECTED_SLICE_DEVICE_ENTRY_RENAME = 0x18220000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] > Forget
- CONNECTED_SLICE_DEVICE_ENTRY_FORGET = 0x18230000;
-
- // TvSettings > Connected Devices (Slice) > HDMI-CEC
- CONNECTED_SLICE_HDMICEC = 0x18300000;
-
- // TvSettings > Connected Devices (Slice) > HDMI-CEC > Enable (toggle)
- CONNECTED_SLICE_HDMICEC_ON_OFF = 0x18310000;
-
- // TvSettings > Connected Devices (aliasing CONNECTED_SLICE)
- CONNECTED_CLASSIC = 0x18000000;
-
- // TvSettings > Connected Devices > Connect remote
- // (aliasing CONNECTED_SLICE_CONNECT_NEW_DEVICES)
- CONNECTED_CLASSIC_CONNECT_REMOTE = 0x18100000;
-
- // TvSettings > Connected Devices > [A connected device]
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY)
- CONNECTED_CLASSIC_DEVICE_ENTRY = 0x18200000;
-
- // TvSettings > Connected Devices > [A connected device] > Update
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_UPDATE)
- CONNECTED_CLASSIC_DEVICE_ENTRY_UPDATE = 0x18210000;
-
- // TvSettings > Connected Devices > [A connected device] > Rename
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_RENAME)
- CONNECTED_CLASSIC_DEVICE_ENTRY_RENAME = 0x18220000;
-
- // TvSettings > Connected Devices > [A connected device] > Forget
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_FORGET)
- CONNECTED_CLASSIC_DEVICE_ENTRY_FORGET = 0x18230000;
-
- // TvSettings > Connected Devices > HDMI-CEC
- // (aliasing CONNECTED_SLICE_HDMICEC)
- CONNECTED_CLASSIC_HDMICEC = 0x18300000;
-
- // TvSettings > Connected Devices > HDMI-CEC > Enable (toggle)
- // (aliasing CONNECTED_SLICE_HDMICEC_ON_OFF)
- CONNECTED_CLASSIC_HDMICEC_ON_OFF = 0x18310000;
-
- // TvSettings > Help & Feedback
- FEEDBACK = 0x19000000;
-
- // TvSettings > Help & Feedback > Send feedback
- FEEDBACK_SEND = 0x19100000;
-}
diff --git a/core/proto/android/bluetooth/a2dp/enums.proto b/core/proto/android/bluetooth/a2dp/enums.proto
deleted file mode 100644
index 5a025bdd6c10..000000000000
--- a/core/proto/android/bluetooth/a2dp/enums.proto
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.a2dp;
-
-option java_outer_classname = "BluetoothA2dpProtoEnums";
-option java_multiple_files = true;
-
-// A2dp playback state enum, defined from:
-// frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java
-enum PlaybackStateEnum {
- PLAYBACK_STATE_UNKNOWN = 0;
- PLAYBACK_STATE_PLAYING = 10;
- PLAYBACK_STATE_NOT_PLAYING = 11;
-}
-
-enum AudioCodingModeEnum {
- AUDIO_CODING_MODE_UNKNOWN = 0;
- AUDIO_CODING_MODE_HARDWARE = 1;
- AUDIO_CODING_MODE_SOFTWARE = 2;
-}
diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto
deleted file mode 100644
index 22f249820b11..000000000000
--- a/core/proto/android/bluetooth/enums.proto
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth;
-
-option java_outer_classname = "BluetoothProtoEnums";
-option java_multiple_files = true;
-
-// Bluetooth connection states.
-enum ConnectionStateEnum {
- CONNECTION_STATE_DISCONNECTED = 0;
- CONNECTION_STATE_CONNECTING = 1;
- CONNECTION_STATE_CONNECTED = 2;
- CONNECTION_STATE_DISCONNECTING = 3;
-}
-
-// Bluetooth Adapter Enable and Disable Reasons
-enum EnableDisableReasonEnum {
- ENABLE_DISABLE_REASON_UNSPECIFIED = 0;
- ENABLE_DISABLE_REASON_APPLICATION_REQUEST = 1;
- ENABLE_DISABLE_REASON_AIRPLANE_MODE = 2;
- ENABLE_DISABLE_REASON_DISALLOWED = 3;
- ENABLE_DISABLE_REASON_RESTARTED = 4;
- ENABLE_DISABLE_REASON_START_ERROR = 5;
- ENABLE_DISABLE_REASON_SYSTEM_BOOT = 6;
- ENABLE_DISABLE_REASON_CRASH = 7;
- ENABLE_DISABLE_REASON_USER_SWITCH = 8;
- ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9;
- ENABLE_DISABLE_REASON_FACTORY_RESET = 10;
-}
-
-enum DirectionEnum {
- DIRECTION_UNKNOWN = 0;
- DIRECTION_OUTGOING = 1;
- DIRECTION_INCOMING = 2;
-}
-
-// First item is the default value, other values follow Bluetooth spec definition
-enum LinkTypeEnum {
- // Link type is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- LINK_TYPE_UNKNOWN = 0xFFF;
- LINK_TYPE_SCO = 0x00;
- LINK_TYPE_ACL = 0x01;
- LINK_TYPE_ESCO = 0x02;
-}
-
-enum DeviceInfoSrcEnum {
- DEVICE_INFO_SRC_UNKNOWN = 0;
- // Within Android Bluetooth stack
- DEVICE_INFO_INTERNAL = 1;
- // Outside Android Bluetooth stack
- DEVICE_INFO_EXTERNAL = 2;
-}
-
-enum DeviceTypeEnum {
- DEVICE_TYPE_UNKNOWN = 0;
- DEVICE_TYPE_CLASSIC = 1;
- DEVICE_TYPE_LE = 2;
- DEVICE_TYPE_DUAL = 3;
-}
-
-// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
-enum TransportTypeEnum {
- TRANSPORT_TYPE_AUTO = 0;
- TRANSPORT_TYPE_BREDR = 1;
- TRANSPORT_TYPE_LE = 2;
-}
-
-// Bond state enum
-// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
-enum BondStateEnum {
- BOND_STATE_UNKNOWN = 0;
- BOND_STATE_NONE = 10;
- BOND_STATE_BONDING = 11;
- BOND_STATE_BONDED = 12;
-}
-
-// Sub states within the bonding general state
-enum BondSubStateEnum {
- BOND_SUB_STATE_UNKNOWN = 0;
- BOND_SUB_STATE_LOCAL_OOB_DATA_PROVIDED = 1;
- BOND_SUB_STATE_LOCAL_PIN_REQUESTED = 2;
- BOND_SUB_STATE_LOCAL_PIN_REPLIED = 3;
- BOND_SUB_STATE_LOCAL_SSP_REQUESTED = 4;
- BOND_SUB_STATE_LOCAL_SSP_REPLIED = 5;
-}
-
-enum UnbondReasonEnum {
- UNBOND_REASON_UNKNOWN = 0;
- UNBOND_REASON_AUTH_FAILED = 1;
- UNBOND_REASON_AUTH_REJECTED = 2;
- UNBOND_REASON_AUTH_CANCELED = 3;
- UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
- UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
- UNBOND_REASON_AUTH_TIMEOUT = 6;
- UNBOND_REASON_REPEATED_ATTEMPTS = 7;
- UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
- UNBOND_REASON_REMOVED = 9;
-}
-
-enum SocketTypeEnum {
- SOCKET_TYPE_UNKNOWN = 0;
- SOCKET_TYPE_RFCOMM = 1;
- SOCKET_TYPE_SCO = 2;
- SOCKET_TYPE_L2CAP_BREDR = 3;
- SOCKET_TYPE_L2CAP_LE = 4;
-}
-
-enum SocketConnectionstateEnum {
- SOCKET_CONNECTION_STATE_UNKNOWN = 0;
- // Socket acts as a server waiting for connection
- SOCKET_CONNECTION_STATE_LISTENING = 1;
- // Socket acts as a client trying to connect
- SOCKET_CONNECTION_STATE_CONNECTING = 2;
- // Socket is connected
- SOCKET_CONNECTION_STATE_CONNECTED = 3;
- // Socket tries to disconnect from remote
- SOCKET_CONNECTION_STATE_DISCONNECTING = 4;
- // This socket is closed
- SOCKET_CONNECTION_STATE_DISCONNECTED = 5;
-}
-
-enum SocketRoleEnum {
- SOCKET_ROLE_UNKNOWN = 0;
- SOCKET_ROLE_LISTEN = 1;
- SOCKET_ROLE_CONNECTION = 2;
-}
diff --git a/core/proto/android/bluetooth/hci/enums.proto b/core/proto/android/bluetooth/hci/enums.proto
deleted file mode 100644
index ef894e548351..000000000000
--- a/core/proto/android/bluetooth/hci/enums.proto
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.hci;
-
-option java_outer_classname = "BluetoothHciProtoEnums";
-option java_multiple_files = true;
-
-// HCI command opcodes (OCF+OGF) from Bluetooth 5.0 specification Vol 2, Part E, Section 7
-// Original definition: system/bt/stack/include/hcidefs.h
-enum CommandEnum {
- // Opcode is at most 2 bytes (0xFFFF), thus 0xFFFFF must not be a valid value
- CMD_UNKNOWN = 0xFFFFF;
- // Link control commands 0x0400
- CMD_INQUIRY = 0x0401;
- CMD_INQUIRY_CANCEL = 0x0402;
- CMD_PERIODIC_INQUIRY_MODE = 0x0403;
- CMD_EXIT_PERIODIC_INQUIRY_MODE = 0x0404;
- CMD_CREATE_CONNECTION = 0x0405;
- CMD_DISCONNECT = 0x0406;
- CMD_ADD_SCO_CONNECTION = 0x0407; // Deprecated since Bluetooth 1.2
- CMD_CREATE_CONNECTION_CANCEL = 0x0408;
- CMD_ACCEPT_CONNECTION_REQUEST = 0x0409;
- CMD_REJECT_CONNECTION_REQUEST = 0x040A;
- CMD_LINK_KEY_REQUEST_REPLY = 0x040B;
- CMD_LINK_KEY_REQUEST_NEG_REPLY = 0x040C;
- CMD_PIN_CODE_REQUEST_REPLY = 0x040D;
- CMD_PIN_CODE_REQUEST_NEG_REPLY = 0x040E;
- CMD_CHANGE_CONN_PACKET_TYPE = 0x040F;
- CMD_AUTHENTICATION_REQUESTED = 0x0411;
- CMD_SET_CONN_ENCRYPTION = 0x0413;
- CMD_CHANGE_CONN_LINK_KEY = 0x0415;
- CMD_MASTER_LINK_KEY = 0x0417;
- CMD_RMT_NAME_REQUEST = 0x0419;
- CMD_RMT_NAME_REQUEST_CANCEL = 0x041A;
- CMD_READ_RMT_FEATURES = 0x041B;
- CMD_READ_RMT_EXT_FEATURES = 0x041C;
- CMD_READ_RMT_VERSION_INFO = 0x041D;
- CMD_READ_RMT_CLOCK_OFFSET = 0x041F;
- CMD_READ_LMP_HANDLE = 0x0420;
- CMD_SETUP_ESCO_CONNECTION = 0x0428;
- CMD_ACCEPT_ESCO_CONNECTION = 0x0429;
- CMD_REJECT_ESCO_CONNECTION = 0x042A;
- CMD_IO_CAPABILITY_REQUEST_REPLY = 0x042B;
- CMD_USER_CONF_REQUEST_REPLY = 0x042C;
- CMD_USER_CONF_VALUE_NEG_REPLY = 0x042D;
- CMD_USER_PASSKEY_REQ_REPLY = 0x042E;
- CMD_USER_PASSKEY_REQ_NEG_REPLY = 0x042F;
- CMD_REM_OOB_DATA_REQ_REPLY = 0x0430;
- CMD_REM_OOB_DATA_REQ_NEG_REPLY = 0x0433;
- CMD_IO_CAP_REQ_NEG_REPLY = 0x0434;
- // BEGIN: AMP commands (not used in system/bt)
- CMD_CREATE_PHYSICAL_LINK = 0x0435;
- CMD_ACCEPT_PHYSICAL_LINK = 0x0436;
- CMD_DISCONNECT_PHYSICAL_LINK = 0x0437;
- CMD_CREATE_LOGICAL_LINK = 0x0438;
- CMD_ACCEPT_LOGICAL_LINK = 0x0439;
- CMD_DISCONNECT_LOGICAL_LINK = 0x043A;
- CMD_LOGICAL_LINK_CANCEL = 0x043B;
- CMD_FLOW_SPEC_MODIFY = 0x043C;
- // END: AMP commands
- CMD_ENH_SETUP_ESCO_CONNECTION = 0x043D;
- CMD_ENH_ACCEPT_ESCO_CONNECTION = 0x043E;
- CMD_TRUNCATED_PAGE = 0x043F;
- CMD_TRUNCATED_PAGE_CANCEL = 0x0440;
- CMD_SET_CLB = 0x0441;
- CMD_RECEIVE_CLB = 0x0442;
- CMD_START_SYNC_TRAIN = 0x0443;
- CMD_RECEIVE_SYNC_TRAIN = 0x0444;
- CMD_REM_OOB_EXTENDED_DATA_REQ_REPLY = 0x0445; // Not currently used in system/bt
- // Link policy commands 0x0800
- CMD_HOLD_MODE = 0x0801;
- CMD_SNIFF_MODE = 0x0803;
- CMD_EXIT_SNIFF_MODE = 0x0804;
- CMD_PARK_MODE = 0x0805;
- CMD_EXIT_PARK_MODE = 0x0806;
- CMD_QOS_SETUP = 0x0807;
- CMD_ROLE_DISCOVERY = 0x0809;
- CMD_SWITCH_ROLE = 0x080B;
- CMD_READ_POLICY_SETTINGS = 0x080C;
- CMD_WRITE_POLICY_SETTINGS = 0x080D;
- CMD_READ_DEF_POLICY_SETTINGS = 0x080E;
- CMD_WRITE_DEF_POLICY_SETTINGS = 0x080F;
- CMD_FLOW_SPECIFICATION = 0x0810;
- CMD_SNIFF_SUB_RATE = 0x0811;
- // Host controller baseband commands 0x0C00
- CMD_SET_EVENT_MASK = 0x0C01;
- CMD_RESET = 0x0C03;
- CMD_SET_EVENT_FILTER = 0x0C05;
- CMD_FLUSH = 0x0C08;
- CMD_READ_PIN_TYPE = 0x0C09;
- CMD_WRITE_PIN_TYPE = 0x0C0A;
- CMD_CREATE_NEW_UNIT_KEY = 0x0C0B;
- CMD_GET_MWS_TRANS_LAYER_CFG = 0x0C0C; // Deprecated (not used in spec)
- CMD_READ_STORED_LINK_KEY = 0x0C0D;
- CMD_WRITE_STORED_LINK_KEY = 0x0C11;
- CMD_DELETE_STORED_LINK_KEY = 0x0C12;
- CMD_CHANGE_LOCAL_NAME = 0x0C13;
- CMD_READ_LOCAL_NAME = 0x0C14;
- CMD_READ_CONN_ACCEPT_TOUT = 0x0C15;
- CMD_WRITE_CONN_ACCEPT_TOUT = 0x0C16;
- CMD_READ_PAGE_TOUT = 0x0C17;
- CMD_WRITE_PAGE_TOUT = 0x0C18;
- CMD_READ_SCAN_ENABLE = 0x0C19;
- CMD_WRITE_SCAN_ENABLE = 0x0C1A;
- CMD_READ_PAGESCAN_CFG = 0x0C1B;
- CMD_WRITE_PAGESCAN_CFG = 0x0C1C;
- CMD_READ_INQUIRYSCAN_CFG = 0x0C1D;
- CMD_WRITE_INQUIRYSCAN_CFG = 0x0C1E;
- CMD_READ_AUTHENTICATION_ENABLE = 0x0C1F;
- CMD_WRITE_AUTHENTICATION_ENABLE = 0x0C20;
- CMD_READ_ENCRYPTION_MODE = 0x0C21; // Deprecated
- CMD_WRITE_ENCRYPTION_MODE = 0x0C22; // Deprecated
- CMD_READ_CLASS_OF_DEVICE = 0x0C23;
- CMD_WRITE_CLASS_OF_DEVICE = 0x0C24;
- CMD_READ_VOICE_SETTINGS = 0x0C25;
- CMD_WRITE_VOICE_SETTINGS = 0x0C26;
- CMD_READ_AUTOMATIC_FLUSH_TIMEOUT = 0x0C27;
- CMD_WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x0C28;
- CMD_READ_NUM_BCAST_REXMITS = 0x0C29;
- CMD_WRITE_NUM_BCAST_REXMITS = 0x0C2A;
- CMD_READ_HOLD_MODE_ACTIVITY = 0x0C2B;
- CMD_WRITE_HOLD_MODE_ACTIVITY = 0x0C2C;
- CMD_READ_TRANSMIT_POWER_LEVEL = 0x0C2D;
- CMD_READ_SCO_FLOW_CTRL_ENABLE = 0x0C2E;
- CMD_WRITE_SCO_FLOW_CTRL_ENABLE = 0x0C2F;
- CMD_SET_HC_TO_HOST_FLOW_CTRL = 0x0C31;
- CMD_HOST_BUFFER_SIZE = 0x0C33;
- CMD_HOST_NUM_PACKETS_DONE = 0x0C35;
- CMD_READ_LINK_SUPER_TOUT = 0x0C36;
- CMD_WRITE_LINK_SUPER_TOUT = 0x0C37;
- CMD_READ_NUM_SUPPORTED_IAC = 0x0C38;
- CMD_READ_CURRENT_IAC_LAP = 0x0C39;
- CMD_WRITE_CURRENT_IAC_LAP = 0x0C3A;
- CMD_READ_PAGESCAN_PERIOD_MODE = 0x0C3B; // Deprecated
- CMD_WRITE_PAGESCAN_PERIOD_MODE = 0x0C3C; // Deprecated
- CMD_READ_PAGESCAN_MODE = 0x0C3D; // Deprecated
- CMD_WRITE_PAGESCAN_MODE = 0x0C3E; // Deprecated
- CMD_SET_AFH_CHANNELS = 0x0C3F;
- CMD_READ_INQSCAN_TYPE = 0x0C42;
- CMD_WRITE_INQSCAN_TYPE = 0x0C43;
- CMD_READ_INQUIRY_MODE = 0x0C44;
- CMD_WRITE_INQUIRY_MODE = 0x0C45;
- CMD_READ_PAGESCAN_TYPE = 0x0C46;
- CMD_WRITE_PAGESCAN_TYPE = 0x0C47;
- CMD_READ_AFH_ASSESSMENT_MODE = 0x0C48;
- CMD_WRITE_AFH_ASSESSMENT_MODE = 0x0C49;
- CMD_READ_EXT_INQ_RESPONSE = 0x0C51;
- CMD_WRITE_EXT_INQ_RESPONSE = 0x0C52;
- CMD_REFRESH_ENCRYPTION_KEY = 0x0C53;
- CMD_READ_SIMPLE_PAIRING_MODE = 0x0C55;
- CMD_WRITE_SIMPLE_PAIRING_MODE = 0x0C56;
- CMD_READ_LOCAL_OOB_DATA = 0x0C57;
- CMD_READ_INQ_TX_POWER_LEVEL = 0x0C58;
- CMD_WRITE_INQ_TX_POWER_LEVEL = 0x0C59;
- CMD_READ_ERRONEOUS_DATA_RPT = 0x0C5A;
- CMD_WRITE_ERRONEOUS_DATA_RPT = 0x0C5B;
- CMD_ENHANCED_FLUSH = 0x0C5F;
- CMD_SEND_KEYPRESS_NOTIF = 0x0C60;
- CMD_READ_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C61;
- CMD_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C62;
- CMD_SET_EVENT_MASK_PAGE_2 = 0x0C63;
- CMD_READ_LOCATION_DATA = 0x0C64;
- CMD_WRITE_LOCATION_DATA = 0x0C65;
- CMD_READ_FLOW_CONTROL_MODE = 0x0C66;
- CMD_WRITE_FLOW_CONTROL_MODE = 0x0C67;
- CMD_READ_ENHANCED_TX_PWR_LEVEL = 0x0C68; // Not currently used in system/bt
- CMD_READ_BE_FLUSH_TOUT = 0x0C69;
- CMD_WRITE_BE_FLUSH_TOUT = 0x0C6A;
- CMD_SHORT_RANGE_MODE = 0x0C6B;
- CMD_READ_BLE_HOST_SUPPORT = 0x0C6C;
- CMD_WRITE_BLE_HOST_SUPPORT = 0x0C6D;
- CMD_SET_MWS_CHANNEL_PARAMETERS = 0x0C6E;
- CMD_SET_EXTERNAL_FRAME_CONFIGURATION = 0x0C6F;
- CMD_SET_MWS_SIGNALING = 0x0C70;
- CMD_SET_MWS_TRANSPORT_LAYER = 0x0C71;
- CMD_SET_MWS_SCAN_FREQUENCY_TABLE = 0x0C72;
- CMD_SET_MWS_PATTERN_CONFIGURATION = 0x0C73;
- CMD_SET_RESERVED_LT_ADDR = 0x0C74;
- CMD_DELETE_RESERVED_LT_ADDR = 0x0C75;
- CMD_WRITE_CLB_DATA = 0x0C76;
- CMD_READ_SYNC_TRAIN_PARAM = 0x0C77;
- CMD_WRITE_SYNC_TRAIN_PARAM = 0x0C78;
- CMD_READ_SECURE_CONNS_SUPPORT = 0x0C79;
- CMD_WRITE_SECURE_CONNS_SUPPORT = 0x0C7A;
- CMD_READ_AUTHED_PAYLOAD_TIMEOUT = 0x0C7B; // Not currently used in system/bt
- CMD_WRITE_AUTHED_PAYLOAD_TIMEOUT = 0x0C7C; // Not currently used in system/bt
- CMD_READ_LOCAL_OOB_EXTENDED_DATA = 0x0C7D; // Not currently used in system/bt
- CMD_READ_EXTENDED_PAGE_TIMEOUT = 0x0C7E; // Not currently used in system/bt
- CMD_WRITE_EXTENDED_PAGE_TIMEOUT = 0x0C7F; // Not currently used in system/bt
- CMD_READ_EXTENDED_INQUIRY_LENGTH = 0x0C80; // Not currently used in system/bt
- CMD_WRITE_EXTENDED_INQUIRY_LENGTH = 0x0C81; // Not currently used in system/bt
- // Informational parameter commands 0x1000
- CMD_READ_LOCAL_VERSION_INFO = 0x1001;
- CMD_READ_LOCAL_SUPPORTED_CMDS = 0x1002;
- CMD_READ_LOCAL_FEATURES = 0x1003;
- CMD_READ_LOCAL_EXT_FEATURES = 0x1004;
- CMD_READ_BUFFER_SIZE = 0x1005;
- CMD_READ_COUNTRY_CODE = 0x1007; // Deprecated
- CMD_READ_BD_ADDR = 0x1009;
- CMD_READ_DATA_BLOCK_SIZE = 0x100A;
- CMD_READ_LOCAL_SUPPORTED_CODECS = 0x100B;
- // Status parameter commands 0x1400
- CMD_READ_FAILED_CONTACT_COUNTER = 0x1401;
- CMD_RESET_FAILED_CONTACT_COUNTER = 0x1402;
- CMD_GET_LINK_QUALITY = 0x1403;
- CMD_READ_RSSI = 0x1405;
- CMD_READ_AFH_CH_MAP = 0x1406;
- CMD_READ_CLOCK = 0x1407;
- CMD_READ_ENCR_KEY_SIZE = 0x1408;
- CMD_READ_LOCAL_AMP_INFO = 0x1409;
- CMD_READ_LOCAL_AMP_ASSOC = 0x140A;
- CMD_WRITE_REMOTE_AMP_ASSOC = 0x140B;
- CMD_GET_MWS_TRANSPORT_CFG = 0x140C; // Not currently used in system/bt
- CMD_SET_TRIGGERED_CLK_CAPTURE = 0x140D; // Not currently used in system/bt
- // Testing commands 0x1800
- CMD_READ_LOOPBACK_MODE = 0x1801;
- CMD_WRITE_LOOPBACK_MODE = 0x1802;
- CMD_ENABLE_DEV_UNDER_TEST_MODE = 0x1803;
- CMD_WRITE_SIMP_PAIR_DEBUG_MODE = 0x1804;
- CMD_ENABLE_AMP_RCVR_REPORTS = 0x1807;
- CMD_AMP_TEST_END = 0x1808;
- CMD_AMP_TEST = 0x1809;
- CMD_WRITE_SECURE_CONN_TEST_MODE = 0x180A; // Not currently used in system/bt
- // BLE commands 0x2000
- CMD_BLE_SET_EVENT_MASK = 0x2001;
- CMD_BLE_READ_BUFFER_SIZE = 0x2002;
- CMD_BLE_READ_LOCAL_SPT_FEAT = 0x2003;
- CMD_BLE_WRITE_LOCAL_SPT_FEAT = 0x2004;
- CMD_BLE_WRITE_RANDOM_ADDR = 0x2005;
- CMD_BLE_WRITE_ADV_PARAMS = 0x2006;
- CMD_BLE_READ_ADV_CHNL_TX_POWER = 0x2007;
- CMD_BLE_WRITE_ADV_DATA = 0x2008;
- CMD_BLE_WRITE_SCAN_RSP_DATA = 0x2009;
- CMD_BLE_WRITE_ADV_ENABLE = 0x200A;
- CMD_BLE_WRITE_SCAN_PARAMS = 0x200B;
- CMD_BLE_WRITE_SCAN_ENABLE = 0x200C;
- CMD_BLE_CREATE_LL_CONN = 0x200D;
- CMD_BLE_CREATE_CONN_CANCEL = 0x200E;
- CMD_BLE_READ_WHITE_LIST_SIZE = 0x200F;
- CMD_BLE_CLEAR_WHITE_LIST = 0x2010;
- CMD_BLE_ADD_WHITE_LIST = 0x2011;
- CMD_BLE_REMOVE_WHITE_LIST = 0x2012;
- CMD_BLE_UPD_LL_CONN_PARAMS = 0x2013;
- CMD_BLE_SET_HOST_CHNL_CLASS = 0x2014;
- CMD_BLE_READ_CHNL_MAP = 0x2015;
- CMD_BLE_READ_REMOTE_FEAT = 0x2016;
- CMD_BLE_ENCRYPT = 0x2017;
- CMD_BLE_RAND = 0x2018;
- CMD_BLE_START_ENC = 0x2019;
- CMD_BLE_LTK_REQ_REPLY = 0x201A;
- CMD_BLE_LTK_REQ_NEG_REPLY = 0x201B;
- CMD_BLE_READ_SUPPORTED_STATES = 0x201C;
- CMD_BLE_RECEIVER_TEST = 0x201D;
- CMD_BLE_TRANSMITTER_TEST = 0x201E;
- CMD_BLE_TEST_END = 0x201F;
- CMD_BLE_RC_PARAM_REQ_REPLY = 0x2020;
- CMD_BLE_RC_PARAM_REQ_NEG_REPLY = 0x2021;
- CMD_BLE_SET_DATA_LENGTH = 0x2022;
- CMD_BLE_READ_DEFAULT_DATA_LENGTH = 0x2023;
- CMD_BLE_WRITE_DEFAULT_DATA_LENGTH = 0x2024;
- CMD_BLE_GENERATE_DHKEY = 0x2026; // Not currently used in system/bt
- CMD_BLE_ADD_DEV_RESOLVING_LIST = 0x2027;
- CMD_BLE_RM_DEV_RESOLVING_LIST = 0x2028;
- CMD_BLE_CLEAR_RESOLVING_LIST = 0x2029;
- CMD_BLE_READ_RESOLVING_LIST_SIZE = 0x202A;
- CMD_BLE_READ_RESOLVABLE_ADDR_PEER = 0x202B;
- CMD_BLE_READ_RESOLVABLE_ADDR_LOCAL = 0x202C;
- CMD_BLE_SET_ADDR_RESOLUTION_ENABLE = 0x202D;
- CMD_BLE_SET_RAND_PRIV_ADDR_TIMOUT = 0x202E;
- CMD_BLE_READ_MAXIMUM_DATA_LENGTH = 0x202F;
- CMD_BLE_READ_PHY = 0x2030;
- CMD_BLE_SET_DEFAULT_PHY = 0x2031;
- CMD_BLE_SET_PHY = 0x2032;
- CMD_BLE_ENH_RECEIVER_TEST = 0x2033;
- CMD_BLE_ENH_TRANSMITTER_TEST = 0x2034;
- CMD_BLE_SET_EXT_ADVERTISING_RANDOM_ADDRESS = 0x2035;
- CMD_BLE_SET_EXT_ADVERTISING_PARAM = 0x2036;
- CMD_BLE_SET_EXT_ADVERTISING_DATA = 0x2037;
- CMD_BLE_SET_EXT_ADVERTISING_SCAN_RESP = 0x2038;
- CMD_BLE_SET_EXT_ADVERTISING_ENABLE = 0x2039;
- CMD_BLE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 0x203A;
- CMD_BLE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 0x203B;
- CMD_BLE_REMOVE_ADVERTISING_SET = 0x203C;
- CMD_BLE_CLEAR_ADVERTISING_SETS = 0x203D;
- CMD_BLE_SET_PERIODIC_ADVERTISING_PARAM = 0x203E;
- CMD_BLE_SET_PERIODIC_ADVERTISING_DATA = 0x203F;
- CMD_BLE_SET_PERIODIC_ADVERTISING_ENABLE = 0x2040;
- CMD_BLE_SET_EXTENDED_SCAN_PARAMETERS = 0x2041;
- CMD_BLE_SET_EXTENDED_SCAN_ENABLE = 0x2042;
- CMD_BLE_EXTENDED_CREATE_CONNECTION = 0x2043;
- CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC = 0x2044;
- CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 0x2045;
- CMD_BLE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 0x2046;
- CMD_BLE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = 0x2047;
- CMD_BLE_RM_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = 0x2048;
- CMD_BLE_CLEAR_PERIODIC_ADVERTISING_LIST = 0x2049;
- CMD_BLE_READ_PERIODIC_ADVERTISING_LIST_SIZE = 0x204A;
- CMD_BLE_READ_TRANSMIT_POWER = 0x204B;
- CMD_BLE_READ_RF_COMPENS_POWER = 0x204C;
- CMD_BLE_WRITE_RF_COMPENS_POWER = 0x204D;
- CMD_BLE_SET_PRIVACY_MODE = 0x204E;
- // Vendor specific commands 0xFC00 and above
- // Android vendor specific commands defined in
- // https://source.android.com/devices/bluetooth/hci_requirements#vendor-specific-capabilities
- CMD_BLE_VENDOR_CAP = 0xFD53;
- CMD_BLE_MULTI_ADV = 0xFD54;
- CMD_BLE_BATCH_SCAN = 0xFD56;
- CMD_BLE_ADV_FILTER = 0xFD57;
- CMD_BLE_TRACK_ADV = 0xFD58;
- CMD_BLE_ENERGY_INFO = 0xFD59;
- CMD_BLE_EXTENDED_SCAN_PARAMS = 0xFD5A;
- CMD_CONTROLLER_DEBUG_INFO = 0xFD5B;
- CMD_CONTROLLER_A2DP_OPCODE = 0xFD5D;
- CMD_BRCM_SET_ACL_PRIORITY = 0xFC57;
- // Other vendor specific commands below here
-}
-
-// HCI event codes from the Bluetooth 5.0 specification Vol 2, Part 7, Section 7
-// Original definition: system/bt/stack/include/hcidefs.h
-enum EventEnum {
- // Event is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- EVT_UNKNOWN = 0xFFF;
- EVT_INQUIRY_COMP = 0x01;
- EVT_INQUIRY_RESULT = 0x02;
- EVT_CONNECTION_COMP = 0x03;
- EVT_CONNECTION_REQUEST = 0x04;
- EVT_DISCONNECTION_COMP = 0x05;
- EVT_AUTHENTICATION_COMP = 0x06;
- EVT_RMT_NAME_REQUEST_COMP = 0x07;
- EVT_ENCRYPTION_CHANGE = 0x08;
- EVT_CHANGE_CONN_LINK_KEY = 0x09;
- EVT_MASTER_LINK_KEY_COMP = 0x0A;
- EVT_READ_RMT_FEATURES_COMP = 0x0B;
- EVT_READ_RMT_VERSION_COMP = 0x0C;
- EVT_QOS_SETUP_COMP = 0x0D;
- EVT_COMMAND_COMPLETE = 0x0E;
- EVT_COMMAND_STATUS = 0x0F;
- EVT_HARDWARE_ERROR = 0x10;
- EVT_FLUSH_OCCURRED = 0x11;
- EVT_ROLE_CHANGE = 0x12;
- EVT_NUM_COMPL_DATA_PKTS = 0x13;
- EVT_MODE_CHANGE = 0x14;
- EVT_RETURN_LINK_KEYS = 0x15;
- EVT_PIN_CODE_REQUEST = 0x16;
- EVT_LINK_KEY_REQUEST = 0x17;
- EVT_LINK_KEY_NOTIFICATION = 0x18;
- EVT_LOOPBACK_COMMAND = 0x19;
- EVT_DATA_BUF_OVERFLOW = 0x1A;
- EVT_MAX_SLOTS_CHANGED = 0x1B;
- EVT_READ_CLOCK_OFF_COMP = 0x1C;
- EVT_CONN_PKT_TYPE_CHANGE = 0x1D;
- EVT_QOS_VIOLATION = 0x1E;
- EVT_PAGE_SCAN_MODE_CHANGE = 0x1F; // Deprecated
- EVT_PAGE_SCAN_REP_MODE_CHNG = 0x20;
- EVT_FLOW_SPECIFICATION_COMP = 0x21;
- EVT_INQUIRY_RSSI_RESULT = 0x22;
- EVT_READ_RMT_EXT_FEATURES_COMP = 0x23;
- EVT_ESCO_CONNECTION_COMP = 0x2C;
- EVT_ESCO_CONNECTION_CHANGED = 0x2D;
- EVT_SNIFF_SUB_RATE = 0x2E;
- EVT_EXTENDED_INQUIRY_RESULT = 0x2F;
- EVT_ENCRYPTION_KEY_REFRESH_COMP = 0x30;
- EVT_IO_CAPABILITY_REQUEST = 0x31;
- EVT_IO_CAPABILITY_RESPONSE = 0x32;
- EVT_USER_CONFIRMATION_REQUEST = 0x33;
- EVT_USER_PASSKEY_REQUEST = 0x34;
- EVT_REMOTE_OOB_DATA_REQUEST = 0x35;
- EVT_SIMPLE_PAIRING_COMPLETE = 0x36;
- EVT_LINK_SUPER_TOUT_CHANGED = 0x38;
- EVT_ENHANCED_FLUSH_COMPLETE = 0x39;
- EVT_USER_PASSKEY_NOTIFY = 0x3B;
- EVT_KEYPRESS_NOTIFY = 0x3C;
- EVT_RMT_HOST_SUP_FEAT_NOTIFY = 0x3D;
- EVT_BLE_META = 0x3E;
- EVT_PHYSICAL_LINK_COMP = 0x40;
- EVT_CHANNEL_SELECTED = 0x41;
- EVT_DISC_PHYSICAL_LINK_COMP = 0x42;
- EVT_PHY_LINK_LOSS_EARLY_WARNING = 0x43;
- EVT_PHY_LINK_RECOVERY = 0x44;
- EVT_LOGICAL_LINK_COMP = 0x45;
- EVT_DISC_LOGICAL_LINK_COMP = 0x46;
- EVT_FLOW_SPEC_MODIFY_COMP = 0x47;
- EVT_NUM_COMPL_DATA_BLOCKS = 0x48;
- EVT_AMP_TEST_START = 0x49; // Not currently used in system/bt
- EVT_AMP_TEST_END = 0x4A; // Not currently used in system/bt
- EVT_AMP_RECEIVER_RPT = 0x4B; // Not currently used in system/bt
- EVT_SHORT_RANGE_MODE_COMPLETE = 0x4C;
- EVT_AMP_STATUS_CHANGE = 0x4D;
- EVT_SET_TRIGGERED_CLOCK_CAPTURE = 0x4E;
- EVT_SYNC_TRAIN_CMPL = 0x4F; // Not currently used in system/bt
- EVT_SYNC_TRAIN_RCVD = 0x50; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_RCVD = 0x51; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_TIMEOUT = 0x52; // Not currently used in system/bt
- EVT_TRUNCATED_PAGE_CMPL = 0x53; // Not currently used in system/bt
- EVT_SLAVE_PAGE_RES_TIMEOUT = 0x54; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_CHNL_MAP_CHANGE = 0x55; // Not currently used in system/bt
- EVT_INQUIRY_RES_NOTIFICATION = 0x56; // Not currently used in system/bt
- EVT_AUTHED_PAYLOAD_TIMEOUT = 0x57; // Not currently used in system/bt
- EVT_SAM_STATUS_CHANGE = 0x58; // Not currently used in system/bt
-}
-
-// Bluetooth low energy related meta event codes
-// from the Bluetooth 5.0 specification Vol 2, Part E, Section 7.7.65
-// Original definition: system/bt/stack/include/hcidefs.h
-enum BleMetaEventEnum {
- // BLE meta event code is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- BLE_EVT_UNKNOWN = 0xFFF;
- BLE_EVT_CONN_COMPLETE_EVT = 0x01;
- BLE_EVT_ADV_PKT_RPT_EVT = 0x02;
- BLE_EVT_LL_CONN_PARAM_UPD_EVT = 0x03;
- BLE_EVT_READ_REMOTE_FEAT_CMPL_EVT = 0x04;
- BLE_EVT_LTK_REQ_EVT = 0x05;
- BLE_EVT_RC_PARAM_REQ_EVT = 0x06;
- BLE_EVT_DATA_LENGTH_CHANGE_EVT = 0x07;
- BLE_EVT_READ_LOCAL_P256_PUB_KEY = 0x08; // Not currently used in system/bt
- BLE_EVT_GEN_DHKEY_CMPL = 0x09; // Not currently used in system/bt
- BLE_EVT_ENHANCED_CONN_COMPLETE_EVT = 0x0a;
- BLE_EVT_DIRECT_ADV_EVT = 0x0b;
- BLE_EVT_PHY_UPDATE_COMPLETE_EVT = 0x0c;
- BLE_EVT_EXTENDED_ADVERTISING_REPORT_EVT = 0x0D;
- BLE_EVT_PERIODIC_ADV_SYNC_EST_EVT = 0x0E;
- BLE_EVT_PERIODIC_ADV_REPORT_EVT = 0x0F;
- BLE_EVT_PERIODIC_ADV_SYNC_LOST_EVT = 0x10;
- BLE_EVT_SCAN_TIMEOUT_EVT = 0x11;
- BLE_EVT_ADVERTISING_SET_TERMINATED_EVT = 0x12;
- BLE_EVT_SCAN_REQ_RX_EVT = 0x13;
- BLE_EVT_CHNL_SELECTION_ALGORITHM = 0x14; // Not currently used in system/bt
-}
-
-// HCI status code from the Bluetooth 5.0 specification Vol 2, Part D.
-// Original definition: system/bt/stack/include/hcidefs.h
-enum StatusEnum {
- // Status is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- STATUS_UNKNOWN = 0xFFF;
- STATUS_SUCCESS = 0x00;
- STATUS_ILLEGAL_COMMAND = 0x01;
- STATUS_NO_CONNECTION = 0x02;
- STATUS_HW_FAILURE = 0x03;
- STATUS_PAGE_TIMEOUT = 0x04;
- STATUS_AUTH_FAILURE = 0x05;
- STATUS_KEY_MISSING = 0x06;
- STATUS_MEMORY_FULL = 0x07;
- STATUS_CONNECTION_TOUT = 0x08;
- STATUS_MAX_NUM_OF_CONNECTIONS = 0x09;
- STATUS_MAX_NUM_OF_SCOS = 0x0A;
- STATUS_CONNECTION_EXISTS = 0x0B;
- STATUS_COMMAND_DISALLOWED = 0x0C;
- STATUS_HOST_REJECT_RESOURCES = 0x0D;
- STATUS_HOST_REJECT_SECURITY = 0x0E;
- STATUS_HOST_REJECT_DEVICE = 0x0F;
- STATUS_HOST_TIMEOUT = 0x10;
- STATUS_UNSUPPORTED_VALUE = 0x11;
- STATUS_ILLEGAL_PARAMETER_FMT = 0x12;
- STATUS_PEER_USER = 0x13;
- STATUS_PEER_LOW_RESOURCES = 0x14;
- STATUS_PEER_POWER_OFF = 0x15;
- STATUS_CONN_CAUSE_LOCAL_HOST = 0x16;
- STATUS_REPEATED_ATTEMPTS = 0x17;
- STATUS_PAIRING_NOT_ALLOWED = 0x18;
- STATUS_UNKNOWN_LMP_PDU = 0x19;
- STATUS_UNSUPPORTED_REM_FEATURE = 0x1A;
- STATUS_SCO_OFFSET_REJECTED = 0x1B;
- STATUS_SCO_INTERVAL_REJECTED = 0x1C;
- STATUS_SCO_AIR_MODE = 0x1D;
- STATUS_INVALID_LMP_PARAM = 0x1E;
- STATUS_UNSPECIFIED = 0x1F;
- STATUS_UNSUPPORTED_LMP_FEATURE = 0x20;
- STATUS_ROLE_CHANGE_NOT_ALLOWED = 0x21;
- STATUS_LMP_RESPONSE_TIMEOUT = 0x22;
- STATUS_LMP_STATUS_TRANS_COLLISION = 0x23;
- STATUS_LMP_PDU_NOT_ALLOWED = 0x24;
- STATUS_ENCRY_MODE_NOT_ACCEPTABLE = 0x25;
- STATUS_UNIT_KEY_USED = 0x26;
- STATUS_QOS_NOT_SUPPORTED = 0x27;
- STATUS_INSTANT_PASSED = 0x28;
- STATUS_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29;
- STATUS_DIFF_TRANSACTION_COLLISION = 0x2A;
- STATUS_UNDEFINED_0x2B = 0x2B; // Not used
- STATUS_QOS_UNACCEPTABLE_PARAM = 0x2C;
- STATUS_QOS_REJECTED = 0x2D;
- STATUS_CHAN_CLASSIF_NOT_SUPPORTED = 0x2E;
- STATUS_INSUFFCIENT_SECURITY = 0x2F;
- STATUS_PARAM_OUT_OF_RANGE = 0x30;
- STATUS_UNDEFINED_0x31 = 0x31; // Not used
- STATUS_ROLE_SWITCH_PENDING = 0x32;
- STATUS_UNDEFINED_0x33 = 0x33;
- STATUS_RESERVED_SLOT_VIOLATION = 0x34;
- STATUS_ROLE_SWITCH_FAILED = 0x35;
- STATUS_INQ_RSP_DATA_TOO_LARGE = 0x36;
- STATUS_SIMPLE_PAIRING_NOT_SUPPORTED = 0x37;
- STATUS_HOST_BUSY_PAIRING = 0x38;
- STATUS_REJ_NO_SUITABLE_CHANNEL = 0x39;
- STATUS_CONTROLLER_BUSY = 0x3A;
- STATUS_UNACCEPT_CONN_INTERVAL = 0x3B;
- STATUS_ADVERTISING_TIMEOUT = 0x3C;
- STATUS_CONN_TOUT_DUE_TO_MIC_FAILURE = 0x3D;
- STATUS_CONN_FAILED_ESTABLISHMENT = 0x3E;
- STATUS_MAC_CONNECTION_FAILED = 0x3F;
- STATUS_LT_ADDR_ALREADY_IN_USE = 0x40;
- STATUS_LT_ADDR_NOT_ALLOCATED = 0x41;
- STATUS_CLB_NOT_ENABLED = 0x42;
- STATUS_CLB_DATA_TOO_BIG = 0x43;
- STATUS_OPERATION_CANCELED_BY_HOST = 0x44; // Not currently used in system/bt
-}
-
-enum BqrIdEnum {
- BQR_ID_UNKNOWN = 0x00;
- BQR_ID_MONITOR_MODE = 0x01;
- BQR_ID_APPROACH_LSTO = 0x02;
- BQR_ID_A2DP_AUDIO_CHOPPY = 0x03;
- BQR_ID_SCO_VOICE_CHOPPY = 0x04;
-}
-
-enum BqrPacketTypeEnum {
- BQR_PACKET_TYPE_UNKNOWN = 0x00;
- BQR_PACKET_TYPE_ID = 0x01;
- BQR_PACKET_TYPE_NULL = 0x02;
- BQR_PACKET_TYPE_POLL = 0x03;
- BQR_PACKET_TYPE_FHS = 0x04;
- BQR_PACKET_TYPE_HV1 = 0x05;
- BQR_PACKET_TYPE_HV2 = 0x06;
- BQR_PACKET_TYPE_HV3 = 0x07;
- BQR_PACKET_TYPE_DV = 0x08;
- BQR_PACKET_TYPE_EV3 = 0x09;
- BQR_PACKET_TYPE_EV4 = 0x0A;
- BQR_PACKET_TYPE_EV5 = 0x0B;
- BQR_PACKET_TYPE_2EV3 = 0x0C;
- BQR_PACKET_TYPE_2EV5 = 0x0D;
- BQR_PACKET_TYPE_3EV3 = 0x0E;
- BQR_PACKET_TYPE_3EV5 = 0x0F;
- BQR_PACKET_TYPE_DM1 = 0x10;
- BQR_PACKET_TYPE_DH1 = 0x11;
- BQR_PACKET_TYPE_DM3 = 0x12;
- BQR_PACKET_TYPE_DH3 = 0x13;
- BQR_PACKET_TYPE_DM5 = 0x14;
- BQR_PACKET_TYPE_DH5 = 0x15;
- BQR_PACKET_TYPE_AUX1 = 0x16;
- BQR_PACKET_TYPE_2DH1 = 0x17;
- BQR_PACKET_TYPE_2DH3 = 0x18;
- BQR_PACKET_TYPE_2DH5 = 0x19;
- BQR_PACKET_TYPE_3DH1 = 0x1A;
- BQR_PACKET_TYPE_3DH3 = 0x1B;
- BQR_PACKET_TYPE_3DH5 = 0x1C;
-}
diff --git a/core/proto/android/bluetooth/hfp/enums.proto b/core/proto/android/bluetooth/hfp/enums.proto
deleted file mode 100644
index d286e4b64d67..000000000000
--- a/core/proto/android/bluetooth/hfp/enums.proto
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.hfp;
-
-option java_outer_classname = "BluetoothHfpProtoEnums";
-option java_multiple_files = true;
-
-enum ScoCodec {
- SCO_CODEC_UNKNOWN = 0;
- SCO_CODEC_CVSD = 1;
- // Default codec behind Wide Band Speech
- SCO_CODEC_MSBC = 2;
-} \ No newline at end of file
diff --git a/core/proto/android/bluetooth/smp/enums.proto b/core/proto/android/bluetooth/smp/enums.proto
deleted file mode 100644
index c6747b78dc29..000000000000
--- a/core/proto/android/bluetooth/smp/enums.proto
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.smp;
-
-option java_outer_classname = "BluetoothSmpProtoEnums";
-option java_multiple_files = true;
-
-// SMP Pairing command codes
-enum CommandEnum {
- CMD_UNKNOWN = 0x00;
- CMD_PAIRING_REQUEST = 0x01;
- CMD_PAIRING_RESPONSE = 0x02;
- CMD_PAIRING_CONFIRM = 0x03;
- CMD_PAIRING_RANDOM = 0x04;
- CMD_PAIRING_FAILED = 0x05;
- CMD_ENCRYPTION_INFON = 0x06;
- CMD_MASTER_IDENTIFICATION = 0x07;
- CMD_IDENTITY_INFO = 0x08;
- CMD_IDENTITY_ADDR_INFO = 0x09;
- CMD_SIGNING_INFO = 0x0A;
- CMD_SECURITY_REQUEST = 0x0B;
- CMD_PAIRING_PUBLIC_KEY = 0x0C;
- CMD_PAIRING_DHKEY_CHECK = 0x0D;
- CMD_PAIRING_KEYPRESS_INFO = 0x0E;
-}
-
-enum PairingFailReasonEnum {
- PAIRING_FAIL_REASON_RESERVED = 0x00;
- PAIRING_FAIL_REASON_PASSKEY_ENTRY = 0x01;
- PAIRING_FAIL_REASON_OOB = 0x02;
- PAIRING_FAIL_REASON_AUTH_REQ = 0x03;
- PAIRING_FAIL_REASON_CONFIRM_VALUE = 0x04;
- PAIRING_FAIL_REASON_PAIR_NOT_SUPPORT = 0x05;
- PAIRING_FAIL_REASON_ENC_KEY_SIZE = 0x06;
- PAIRING_FAIL_REASON_INVALID_CMD = 0x07;
- PAIRING_FAIL_REASON_UNSPECIFIED = 0x08;
- PAIRING_FAIL_REASON_REPEATED_ATTEMPTS = 0x09;
- PAIRING_FAIL_REASON_INVALID_PARAMETERS = 0x0A;
- PAIRING_FAIL_REASON_DHKEY_CHK = 0x0B;
- PAIRING_FAIL_REASON_NUMERIC_COMPARISON = 0x0C;
- PAIRING_FAIL_REASON_CLASSIC_PAIRING_IN_PROGR = 0x0D;
- PAIRING_FAIL_REASON_XTRANS_DERIVE_NOT_ALLOW = 0x0E;
-} \ No newline at end of file
diff --git a/core/proto/android/debug/enums.proto b/core/proto/android/debug/enums.proto
deleted file mode 100644
index 6747bb7276b3..000000000000
--- a/core/proto/android/debug/enums.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.debug;
-
-option java_outer_classname = "AdbProtoEnums";
-option java_multiple_files = true;
-
-/**
- * adb connection state used to track adb connection changes in AdbDebuggingManager.java.
- */
-enum AdbConnectionStateEnum {
- UNKNOWN = 0;
-
- /**
- * The adb connection is waiting for approval from the user.
- */
- AWAITING_USER_APPROVAL = 1;
-
- /**
- * The user allowed the adb connection from the system.
- */
- USER_ALLOWED = 2;
-
- /**
- * The user denied the adb connection from the system.
- */
- USER_DENIED = 3;
-
- /**
- * The adb connection was automatically allowed without user interaction due to the system
- * being previously allowed by the user with the 'always allow' option selected, and the adb
- * grant has not yet expired.
- */
- AUTOMATICALLY_ALLOWED = 4;
-
- /**
- * An empty or invalid base64 encoded key was provided to the framework; the connection was
- * automatically denied.
- */
- DENIED_INVALID_KEY = 5;
-
- /**
- * vold decrypt has not yet occurred; the connection was automatically denied.
- */
- DENIED_VOLD_DECRYPT = 6;
-
- /**
- * The adb session has been disconnected.
- */
- DISCONNECTED = 7;
-}
-
diff --git a/core/proto/android/hardware/biometrics/enums.proto b/core/proto/android/hardware/biometrics/enums.proto
deleted file mode 100644
index f2e06383b5b1..000000000000
--- a/core/proto/android/hardware/biometrics/enums.proto
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.hardware.biometrics;
-
-option java_outer_classname = "BiometricsProtoEnums";
-option java_multiple_files = true;
-
-// Logging constants for <Biometric>Service and BiometricService
-
-enum ModalityEnum {
- MODALITY_UNKNOWN = 0;
- MODALITY_FINGERPRINT = 1; // 1 << 0
- MODALITY_IRIS = 2; // 1 << 1
- MODALITY_FACE = 4; // 1 << 2
-}
-
-enum ClientEnum {
- CLIENT_UNKNOWN = 0;
- CLIENT_KEYGUARD = 1;
- CLIENT_BIOMETRIC_PROMPT = 2;
- CLIENT_FINGERPRINT_MANAGER = 3; // Deprecated API before BiometricPrompt was introduced
-}
-
-enum ActionEnum {
- ACTION_UNKNOWN = 0;
- ACTION_ENROLL = 1;
- ACTION_AUTHENTICATE = 2;
- ACTION_ENUMERATE = 3;
- ACTION_REMOVE = 4;
-}
-
-enum IssueEnum {
- ISSUE_UNKNOWN = 0;
- // When a biometric HAL has crashed.
- ISSUE_HAL_DEATH = 1;
- // When Android Framework has a template that doesn't exist in the HAL. The framework
- // is expected to remove its template to stay in sync with the HAL.
- ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK = 2;
- // When the HAL has a template that doesn't exist in Android Framework. The framework
- // is expected to notify the HAL to remove this template to stay in sync with the framework.
- ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL = 3;
- // When the HAL has not sent ERROR_CANCELED within the specified timeout.
- ISSUE_CANCEL_TIMED_OUT = 4;
-} \ No newline at end of file
diff --git a/core/proto/android/hardware/sensor/assist/enums.proto b/core/proto/android/hardware/sensor/assist/enums.proto
deleted file mode 100644
index 012dcb2e937e..000000000000
--- a/core/proto/android/hardware/sensor/assist/enums.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.hardware.sensor.assist;
-
-option java_outer_classname = "AssistGestureProtoEnums";
-option java_multiple_files = true;
-
-enum AssistGestureStageEnum {
- ASSIST_GESTURE_STAGE_UNKNOWN = 0;
- ASSIST_GESTURE_STAGE_PROGRESS = 1;
- ASSIST_GESTURE_STAGE_PRIMED = 2;
- ASSIST_GESTURE_STAGE_DETECTED = 3;
-}
-
-enum AssistGestureFeedbackEnum {
- ASSIST_GESTURE_FEEDBACK_UNKNOWN = 0;
- ASSIST_GESTURE_FEEDBACK_NOT_USED = 1;
- ASSIST_GESTURE_FEEDBACK_USED = 2;
-} \ No newline at end of file
diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto
deleted file mode 100644
index be0cad18a24d..000000000000
--- a/core/proto/android/net/networkcapabilities.proto
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.net;
-
-option java_multiple_files = true;
-
-import "frameworks/base/core/proto/android/privacy.proto";
-
-/**
- * An android.net.NetworkCapabilities object.
- */
-message NetworkCapabilitiesProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- enum Transport {
- // Indicates this network uses a Cellular transport.
- TRANSPORT_CELLULAR = 0;
- // Indicates this network uses a Wi-Fi transport.
- TRANSPORT_WIFI = 1;
- // Indicates this network uses a Bluetooth transport.
- TRANSPORT_BLUETOOTH = 2;
- // Indicates this network uses an Ethernet transport.
- TRANSPORT_ETHERNET = 3;
- // Indicates this network uses a VPN transport.
- TRANSPORT_VPN = 4;
- // Indicates this network uses a Wi-Fi Aware transport.
- TRANSPORT_WIFI_AWARE = 5;
- // Indicates this network uses a LoWPAN transport.
- TRANSPORT_LOWPAN = 6;
- }
- repeated Transport transports = 1;
-
- enum NetCapability {
- // Indicates this is a network that has the ability to reach the
- // carrier's MMSC for sending and receiving MMS messages.
- NET_CAPABILITY_MMS = 0;
- // Indicates this is a network that has the ability to reach the
- // carrier's SUPL server, used to retrieve GPS information.
- NET_CAPABILITY_SUPL = 1;
- // Indicates this is a network that has the ability to reach the
- // carrier's DUN or tethering gateway.
- NET_CAPABILITY_DUN = 2;
- // Indicates this is a network that has the ability to reach the
- // carrier's FOTA portal, used for over the air updates.
- NET_CAPABILITY_FOTA = 3;
- // Indicates this is a network that has the ability to reach the
- // carrier's IMS servers, used for network registration and signaling.
- NET_CAPABILITY_IMS = 4;
- // Indicates this is a network that has the ability to reach the
- // carrier's CBS servers, used for carrier specific services.
- NET_CAPABILITY_CBS = 5;
- // Indicates this is a network that has the ability to reach a Wi-Fi
- // direct peer.
- NET_CAPABILITY_WIFI_P2P = 6;
- // Indicates this is a network that has the ability to reach a carrier's
- // Initial Attach servers.
- NET_CAPABILITY_IA = 7;
- // Indicates this is a network that has the ability to reach a carrier's
- // RCS servers, used for Rich Communication Services.
- NET_CAPABILITY_RCS = 8;
- // Indicates this is a network that has the ability to reach a carrier's
- // XCAP servers, used for configuration and control.
- NET_CAPABILITY_XCAP = 9;
- // Indicates this is a network that has the ability to reach a carrier's
- // Emergency IMS servers or other services, used for network signaling
- // during emergency calls.
- NET_CAPABILITY_EIMS = 10;
- // Indicates that this network is unmetered.
- NET_CAPABILITY_NOT_METERED = 11;
- // Indicates that this network should be able to reach the internet.
- NET_CAPABILITY_INTERNET = 12;
- // Indicates that this network is available for general use. If this is
- // not set applications should not attempt to communicate on this
- // network. Note that this is simply informative and not enforcement -
- // enforcement is handled via other means. Set by default.
- NET_CAPABILITY_NOT_RESTRICTED = 13;
- // Indicates that the user has indicated implicit trust of this network.
- // This generally means it's a sim-selected carrier, a plugged in
- // ethernet, a paired BT device or a wifi the user asked to connect to.
- // Untrusted networks are probably limited to unknown wifi AP. Set by
- // default.
- NET_CAPABILITY_TRUSTED = 14;
- // Indicates that this network is not a VPN. This capability is set by
- // default and should be explicitly cleared for VPN networks.
- NET_CAPABILITY_NOT_VPN = 15;
- // Indicates that connectivity on this network was successfully
- // validated. For example, for a network with NET_CAPABILITY_INTERNET,
- // it means that Internet connectivity was successfully detected.
- NET_CAPABILITY_VALIDATED = 16;
- // Indicates that this network was found to have a captive portal in
- // place last time it was probed.
- NET_CAPABILITY_CAPTIVE_PORTAL = 17;
- // Indicates that this network is not roaming.
- NET_CAPABILITY_NOT_ROAMING = 18;
- // Indicates that this network is available for use by apps, and not a
- // network that is being kept up in the background to facilitate fast
- // network switching.
- NET_CAPABILITY_FOREGROUND = 19;
- }
- repeated NetCapability capabilities = 2;
-
- // Passive link bandwidth. This is a rough guide of the expected peak
- // bandwidth for the first hop on the given transport. It is not measured,
- // but may take into account link parameters (Radio technology, allocated
- // channels, etc).
- optional int32 link_up_bandwidth_kbps = 3;
- optional int32 link_down_bandwidth_kbps = 4;
-
- optional string network_specifier = 5 [ (.android.privacy).dest = DEST_EXPLICIT ];
-
- // True if this object specifies a signal strength.
- optional bool can_report_signal_strength = 6;
- // This is a signed integer, and higher values indicate better signal. The
- // exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
- // Only valid if can_report_signal_strength is true.
- optional sint32 signal_strength = 7;
-}
diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto
index b35a0203ff02..6794c8cd8acb 100644
--- a/core/proto/android/net/networkrequest.proto
+++ b/core/proto/android/net/networkrequest.proto
@@ -20,8 +20,8 @@ package android.net;
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/net/networkcapabilities.proto";
/**
* An android.net.NetworkRequest object.
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 892ebf70ca75..7d68a0df23d5 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -19,10 +19,10 @@ option java_multiple_files = true;
package android.os;
-import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/os/powermanager.proto";
-import "frameworks/base/core/proto/android/telephony/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/job/enums.proto";
+import "frameworks/proto_logging/stats/enums/telephony/enums.proto";
message BatteryStatsProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/enums.proto b/core/proto/android/os/enums.proto
deleted file mode 100644
index 566861b6e836..000000000000
--- a/core/proto/android/os/enums.proto
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.os;
-
-option java_outer_classname = "OsProtoEnums";
-option java_multiple_files = true;
-
-// These constants are defined in hardware/interfaces/health/1.0/types.hal
-// They are primarily used by android/os/BatteryManager.java.
-enum BatteryHealthEnum {
- BATTERY_HEALTH_INVALID = 0;
- BATTERY_HEALTH_UNKNOWN = 1;
- BATTERY_HEALTH_GOOD = 2;
- BATTERY_HEALTH_OVERHEAT = 3;
- BATTERY_HEALTH_DEAD = 4;
- BATTERY_HEALTH_OVER_VOLTAGE = 5;
- BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
- BATTERY_HEALTH_COLD = 7;
-}
-
-// Plug states, primarily used by android/os/BatteryManager.java.
-enum BatteryPluggedStateEnum {
- // Note that NONE is not in BatteryManager.java's constants.
- BATTERY_PLUGGED_NONE = 0;
- // Power source is an AC charger.
- BATTERY_PLUGGED_AC = 1;
- // Power source is a USB port.
- BATTERY_PLUGGED_USB = 2;
- // Power source is wireless.
- BATTERY_PLUGGED_WIRELESS = 4;
-}
-
-// These constants are defined in hardware/interfaces/health/1.0/types.hal
-// They are primarily used by android/os/BatteryManager.java.
-enum BatteryStatusEnum {
- BATTERY_STATUS_INVALID = 0;
- BATTERY_STATUS_UNKNOWN = 1;
- BATTERY_STATUS_CHARGING = 2;
- BATTERY_STATUS_DISCHARGING = 3;
- BATTERY_STATUS_NOT_CHARGING = 4;
- BATTERY_STATUS_FULL = 5;
-}
-
-// These constants are defined in hardware/interfaces/thermal/1.0/types.hal
-// and in hardware/interfaces/thermal/2.0/types.hal
-// They are primarily used by android/os/HardwarePropertiesManager.java.
-// Any change to the types in the thermal hal should be made here as well.
-enum TemperatureTypeEnum {
- TEMPERATURE_TYPE_UNKNOWN = -1;
- TEMPERATURE_TYPE_CPU = 0;
- TEMPERATURE_TYPE_GPU = 1;
- TEMPERATURE_TYPE_BATTERY = 2;
- TEMPERATURE_TYPE_SKIN = 3;
- TEMPERATURE_TYPE_USB_PORT = 4;
- TEMPERATURE_TYPE_POWER_AMPLIFIER = 5;
-
- // Battery Charge Limit - virtual thermal sensors.
- TEMPERATURE_TYPE_BCL_VOLTAGE = 6;
- TEMPERATURE_TYPE_BCL_CURRENT = 7;
- TEMPERATURE_TYPE_BCL_PERCENTAGE = 8;
-
- // Neural Processing Unit.
- TEMPERATURE_TYPE_NPU = 9;
-}
-
-// Device throttling severity
-// These constants are defined in hardware/interfaces/thermal/2.0/types.hal.
-// Any change to the types in the thermal hal should be made here as well.
-enum ThrottlingSeverityEnum {
- // Not under throttling.
- NONE = 0;
- // Light throttling where UX is not impacted.
- LIGHT = 1;
- // Moderate throttling where UX is not largely impacted.
- MODERATE = 2;
- // Severe throttling where UX is largely impacted.
- // Similar to 1.0 throttlingThreshold.
- SEVERE = 3;
- // Platform has done everything to reduce power.
- CRITICAL = 4;
- // Key components in platform are shutting down due to thermal condition.
- // Device functionalities will be limited.
- EMERGENCY = 5;
- // Need shutdown immediately.
- SHUTDOWN = 6;
-};
-
-// Device cooling device types.
-// These constants are defined in hardware/interfaces/thermal/2.0/types.hal.
-// Any change to the types in the thermal hal should be made here as well.
-enum CoolingTypeEnum {
- FAN = 0;
- BATTERY = 1;
- CPU = 2;
- GPU = 3;
- MODEM = 4;
- NPU = 5;
- COMPONENT = 6;
-};
-
-// Wakelock types, primarily used by android/os/PowerManager.java.
-enum WakeLockLevelEnum {
- // NOTE: Wake lock levels were previously defined as a bit field, except
- // that only a few combinations were actually supported so the bit field
- // was removed. This explains why the numbering scheme is so odd. If
- // adding a new wake lock level, any unused value can be used.
-
- // Ensures that the CPU is running; the screen and keyboard backlight
- // will be allowed to go off.
- PARTIAL_WAKE_LOCK = 1;
-
- // Ensures that the screen is on (but may be dimmed); the keyboard
- // backlight will be allowed to go off. If the user presses the power
- // button, then the SCREEN_DIM_WAKE_LOCK will be implicitly released by
- // the system, causing both the screen and the CPU to be turned off.
- SCREEN_DIM_WAKE_LOCK = 6 [deprecated = true];
-
- // Ensures that the screen is on at full brightness; the keyboard
- // backlight will be allowed to go off. If the user presses the power
- // button, then the SCREEN_BRIGHT_WAKE_LOCK will be implicitly released
- // by the system, causing both the screen and the CPU to be turned off.
- SCREEN_BRIGHT_WAKE_LOCK = 10 [deprecated = true];
-
- // Ensures that the screen and keyboard backlight are on at full
- // brightness. If the user presses the power button, then the
- // FULL_WAKE_LOCK will be implicitly released by the system, causing
- // both the screen and the CPU to be turned off.
- FULL_WAKE_LOCK = 26 [deprecated = true];
-
- // Turns the screen off when the proximity sensor activates. If the
- // proximity sensor detects that an object is nearby, the screen turns
- // off immediately. Shortly after the object moves away, the screen
- // turns on again.
- // A proximity wake lock does not prevent the device from falling asleep
- // unlike FULL_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK and
- // SCREEN_DIM_WAKE_LOCK. If there is no user activity and no other wake
- // locks are held, then the device will fall asleep (and lock) as usual.
- // However, the device will not fall asleep while the screen has been
- // turned off by the proximity sensor because it effectively counts as
- // ongoing user activity.
- PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
-
- // Put the screen in a low power state and allow the CPU to suspend if
- // no other wake locks are held. This is used by the dream manager to
- // implement doze mode. It currently has no effect unless the power
- // manager is in the dozing state.
- DOZE_WAKE_LOCK = 64;
-
- // Keep the device awake enough to allow drawing to occur. This is used
- // by the window manager to allow applications to draw while the system
- // is dozing. It currently has no effect unless the power manager is in
- // the dozing state.
- DRAW_WAKE_LOCK = 128;
-}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 64cf75d51c3d..e97b1a8770ed 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -55,13 +55,13 @@ import "frameworks/base/core/proto/android/service/print.proto";
import "frameworks/base/core/proto/android/service/procstats.proto";
import "frameworks/base/core/proto/android/service/restricted_image.proto";
import "frameworks/base/core/proto/android/service/sensor_service.proto";
-import "frameworks/base/core/proto/android/service/usb.proto";
import "frameworks/base/core/proto/android/util/event_log_tags.proto";
import "frameworks/base/core/proto/android/util/log.proto";
import "frameworks/base/core/proto/android/util/textdump.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/section.proto";
import "frameworks/base/proto/src/ipconnectivity.proto";
+import "frameworks/proto_logging/stats/enums/service/usb.proto";
package android.os;
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 2d2ead455a4d..fa046c6593af 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -20,7 +20,6 @@ package com.android.server.am;
import "frameworks/base/core/proto/android/app/activitymanager.proto";
import "frameworks/base/core/proto/android/app/appexitinfo.proto";
-import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/app/notification.proto";
import "frameworks/base/core/proto/android/app/profilerinfo.proto";
import "frameworks/base/core/proto/android/content/component_name.proto";
@@ -35,6 +34,7 @@ import "frameworks/base/core/proto/android/server/intentresolver.proto";
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/util/common.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/enums.proto";
option java_multiple_files = true;
diff --git a/core/proto/android/server/bluetooth_manager_service.proto b/core/proto/android/server/bluetooth_manager_service.proto
index 998413f05ebe..c33f66a9aeca 100644
--- a/core/proto/android/server/bluetooth_manager_service.proto
+++ b/core/proto/android/server/bluetooth_manager_service.proto
@@ -17,8 +17,8 @@
syntax = "proto2";
package com.android.server;
-import "frameworks/base/core/proto/android/bluetooth/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/bluetooth/enums.proto";
option java_multiple_files = true;
diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp
deleted file mode 100644
index 413623963851..000000000000
--- a/core/proto/android/server/connectivity/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "datastallprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "data_stall_event.proto",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto
deleted file mode 100644
index 787074ba494e..000000000000
--- a/core/proto/android/server/connectivity/data_stall_event.proto
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package com.android.server.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "DataStallEventProto";
-
-enum ProbeResult {
- UNKNOWN = 0;
- VALID = 1;
- INVALID = 2;
- PORTAL = 3;
- PARTIAL = 4;
-}
-
-enum ApBand {
- AP_BAND_UNKNOWN = 0;
- AP_BAND_2GHZ = 1;
- AP_BAND_5GHZ = 2;
- AP_BAND_6GHZ = 3;
-}
-
-// Refer to definition in TelephonyManager.java.
-enum RadioTech {
- RADIO_TECHNOLOGY_UNKNOWN = 0;
- RADIO_TECHNOLOGY_GPRS = 1;
- RADIO_TECHNOLOGY_EDGE = 2;
- RADIO_TECHNOLOGY_UMTS = 3;
- RADIO_TECHNOLOGY_IS95A = 4;
- RADIO_TECHNOLOGY_IS95B = 5;
- RADIO_TECHNOLOGY_1XRTT = 6;
- RADIO_TECHNOLOGY_EVDO_0 = 7;
- RADIO_TECHNOLOGY_EVDO_A = 8;
- RADIO_TECHNOLOGY_HSDPA = 9;
- RADIO_TECHNOLOGY_HSUPA = 10;
- RADIO_TECHNOLOGY_HSPA = 11;
- RADIO_TECHNOLOGY_EVDO_B = 12;
- RADIO_TECHNOLOGY_LTE = 13;
- RADIO_TECHNOLOGY_EHRPD = 14;
- RADIO_TECHNOLOGY_HSPAP = 15;
- RADIO_TECHNOLOGY_GSM = 16;
- RADIO_TECHNOLOGY_TD_SCDMA = 17;
- RADIO_TECHNOLOGY_IWLAN = 18;
- RADIO_TECHNOLOGY_LTE_CA = 19;
- RADIO_TECHNOLOGY_NR = 20;
-}
-
-// Cellular specific information.
-message CellularData {
- // Indicate the radio technology at the time of data stall suspected.
- optional RadioTech rat_type = 1;
- // True if device is in roaming network at the time of data stall suspected.
- optional bool is_roaming = 2;
- // Registered network MccMnc when data stall happen
- optional string network_mccmnc = 3;
- // Indicate the SIM card carrier.
- optional string sim_mccmnc = 4;
- // Signal strength level at the time of data stall suspected.
- optional int32 signal_strength = 5;
-}
-
-// Wifi specific information.
-message WifiData {
- // Signal strength at the time of data stall suspected.
- // RSSI range is between -55 to -110.
- optional int32 signal_strength = 1;
- // AP band.
- optional ApBand wifi_band = 2;
-}
-
-message DnsEvent {
- // The dns return code.
- repeated int32 dns_return_code = 1;
- // Indicate the timestamp of the dns event.
- repeated int64 dns_time = 2;
-}
diff --git a/core/proto/android/server/enums.proto b/core/proto/android/server/enums.proto
deleted file mode 100644
index 89f7010e8d81..000000000000
--- a/core/proto/android/server/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.server;
-
-option java_outer_classname = "ServerProtoEnums";
-option java_multiple_files = true;
-
-enum DeviceIdleModeEnum {
- // Device idle mode - not active.
- DEVICE_IDLE_MODE_OFF = 0;
- // Device idle mode - active in lightweight mode.
- DEVICE_IDLE_MODE_LIGHT = 1;
- // Device idle mode - active in full mode.
- DEVICE_IDLE_MODE_DEEP = 2;
-}
-
-enum ErrorSource {
- ERROR_SOURCE_UNKNOWN = 0;
- // Data app
- DATA_APP = 1;
- // System app
- SYSTEM_APP = 2;
- // System server.
- SYSTEM_SERVER = 3;
-}
diff --git a/core/proto/android/server/job/enums.proto b/core/proto/android/server/job/enums.proto
deleted file mode 100644
index 50fc0310ad99..000000000000
--- a/core/proto/android/server/job/enums.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package com.android.server.job;
-
-// This file is for JobScheduler enums inside the server directory. If you're
-// adding enums for app-side code, use the file in
-// frameworks/base/core/proto/android/app/job.
-option java_outer_classname = "JobServerProtoEnums";
-option java_multiple_files = true;
-
-// Set of constraints that a job potentially needs satisfied before it can run.
-// Defined in
-// frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
-enum ConstraintEnum {
- CONSTRAINT_UNKNOWN = 0;
- CONSTRAINT_CHARGING = 1;
- CONSTRAINT_BATTERY_NOT_LOW = 2;
- CONSTRAINT_STORAGE_NOT_LOW = 3;
- CONSTRAINT_TIMING_DELAY = 4;
- CONSTRAINT_DEADLINE = 5;
- CONSTRAINT_IDLE = 6;
- CONSTRAINT_CONNECTIVITY = 7;
- CONSTRAINT_CONTENT_TRIGGER = 8;
- CONSTRAINT_DEVICE_NOT_DOZING = 9;
- CONSTRAINT_WITHIN_QUOTA = 10;
- CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 11;
-}
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index f2f20e3ac12e..d16ba284c1fe 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -20,7 +20,6 @@ package com.android.server.job;
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/content/clipdata.proto";
import "frameworks/base/core/proto/android/content/component_name.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
@@ -29,10 +28,11 @@ import "frameworks/base/core/proto/android/net/networkrequest.proto";
import "frameworks/base/core/proto/android/os/bundle.proto";
import "frameworks/base/core/proto/android/os/persistablebundle.proto";
import "frameworks/base/core/proto/android/server/appstatetracker.proto";
-import "frameworks/base/core/proto/android/server/job/enums.proto";
import "frameworks/base/core/proto/android/server/statlogger.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/util/quotatracker.proto";
+import "frameworks/proto_logging/stats/enums/app/job/enums.proto";
+import "frameworks/proto_logging/stats/enums/server/job/enums.proto";
message JobSchedulerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/location/enums.proto b/core/proto/android/server/location/enums.proto
deleted file mode 100644
index 943ff181fe14..000000000000
--- a/core/proto/android/server/location/enums.proto
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.server.location;
-
-option java_outer_classname = "ServerLocationProtoEnums";
-option java_multiple_files = true;
-
-// GPS Signal Quality levels,
-// primarily used by location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
-enum GpsSignalQualityEnum {
- GPS_SIGNAL_QUALITY_UNKNOWN = -1;
- GPS_SIGNAL_QUALITY_POOR = 0;
- GPS_SIGNAL_QUALITY_GOOD = 1;
-}
-
-// A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc.
-enum GnssNiType {
- VOICE = 1;
- UMTS_SUPL = 2;
- UMTS_CTRL_PLANE = 3;
- EMERGENCY_SUPL = 4;
-};
-
-// GNSS NI responses, used to define the response in NI structures.
-enum GnssUserResponseType {
- RESPONSE_ACCEPT = 1;
- RESPONSE_DENY = 2;
- RESPONSE_NORESP = 3;
-};
-
-// GNSS NI data encoding scheme.
-enum GnssNiEncodingType {
- ENC_NONE = 0;
- ENC_SUPL_GSM_DEFAULT = 1;
- ENC_SUPL_UTF8 = 2;
- ENC_SUPL_UCS2 = 3;
- ENC_UNKNOWN = -1;
-};
-
-// Protocol stack that initiated the non-framework location request.
-enum NfwProtocolStack {
- // Cellular control plane requests.
- CTRL_PLANE = 0;
- // All types of SUPL requests.
- SUPL = 1;
- // All types of requests from IMS.
- IMS = 10;
- // All types of requests from SIM.
- SIM = 11;
- // Requests from other protocol stacks.
- OTHER_PROTOCOL_STACK = 100;
-};
-
-// Source initiating/receiving the location information.
-enum NfwRequestor {
- // Wireless service provider.
- CARRIER = 0;
- // Device manufacturer.
- OEM = 10;
- // Modem chipset vendor.
- MODEM_CHIPSET_VENDOR = 11;
- // GNSS chipset vendor.
- GNSS_CHIPSET_VENDOR = 12;
- // Other chipset vendor.
- OTHER_CHIPSET_VENDOR = 13;
- // Automobile client.
- AUTOMOBILE_CLIENT = 20;
- // Other sources.
- OTHER_REQUESTOR = 100;
-};
-
-// Indicates whether location information was provided for this request.
-enum NfwResponseType {
- // Request rejected because framework has not given permission for this use case.
- REJECTED = 0;
- // Request accepted but could not provide location because of a failure.
- ACCEPTED_NO_LOCATION_PROVIDED = 1;
- // Request accepted and location provided.
- ACCEPTED_LOCATION_PROVIDED = 2;
-};
-
-// The SUPL mode.
-enum SuplMode {
- // Mobile Station Based.
- MSB = 0x01;
- // Mobile Station Assisted.
- MSA = 0x02;
-};
-
-// Enum that hold the bit masks for various LTE Positioning Profile settings (LPP_PROFILE
-// configuration parameter). If none of the bits in the enum are set, the default setting is
-// Radio Resource Location Protocol(RRLP).
-enum LppProfile {
- // Enable LTE Positioning Protocol user plane.
- USER_PLANE = 0x01;
- // Enable LTE Positioning Protocol Control plane.
- CONTROL_PLANE = 0x02;
-};
-
-// Positioning protocol on A-Glonass system.
-enum GlonassPosProtocol {
- // Radio Resource Control(RRC) control-plane.
- RRC_CPLANE = 0x01;
- // Radio Resource Location user-plane.
- RRLP_CPLANE = 0x02;
- // LTE Positioning Protocol User plane.
- LPP_UPLANE = 0x04;
-};
-
-// Configurations of how GPS functionalities should be locked when user turns off GPS On setting.
-enum GpsLock {
- // Lock Mobile Originated GPS functionalitues.
- MO = 0x01;
- // Lock Network Initiated GPS functionalities.
- NI = 0x02;
-};
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 0455d58f498b..c5c4d7c59784 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -19,16 +19,16 @@ package com.android.server.power;
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
-import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/os/looper.proto";
import "frameworks/base/core/proto/android/os/powermanager.proto";
import "frameworks/base/core/proto/android/os/worksource.proto";
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/wirelesschargerdetector.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/enums.proto";
+import "frameworks/proto_logging/stats/enums/os/enums.proto";
+import "frameworks/proto_logging/stats/enums/view/enums.proto";
message PowerManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 0f5616f78e69..420fc7deef28 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -24,11 +24,12 @@ import "frameworks/base/core/proto/android/server/windowcontainerthumbnail.proto
import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
import "frameworks/base/core/proto/android/view/displaycutout.proto";
import "frameworks/base/core/proto/android/view/displayinfo.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/view/surface.proto";
import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/view/enums.proto";
+
package com.android.server.wm;
option java_multiple_files = true;
diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto
index 586411f8ad96..3a112e7c85f0 100644
--- a/core/proto/android/service/battery.proto
+++ b/core/proto/android/service/battery.proto
@@ -20,8 +20,8 @@ package android.service.battery;
option java_multiple_files = true;
option java_outer_classname = "BatteryServiceProto";
-import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/os/enums.proto";
message BatteryServiceDumpProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index 7a4c0706e119..57051f07d124 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -21,8 +21,8 @@ option java_multiple_files = true;
option java_outer_classname = "ProcessStatsServiceProto";
import "frameworks/base/core/proto/android/util/common.proto";
-import "frameworks/base/core/proto/android/service/procstats_enum.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/service/procstats_enum.proto";
/**
* Data from ProcStatsService Dumpsys
diff --git a/core/proto/android/service/procstats_enum.proto b/core/proto/android/service/procstats_enum.proto
deleted file mode 100644
index 2abf3730aa9f..000000000000
--- a/core/proto/android/service/procstats_enum.proto
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service.procstats;
-
-option java_multiple_files = true;
-option java_outer_classname = "ProcessStatsEnums";
-
-enum ScreenState {
- SCREEN_STATE_UNKNOWN = 0;
- SCREEN_STATE_OFF = 1;
- SCREEN_STATE_ON = 2;
-}
-
-enum MemoryState {
- MEMORY_STATE_UNKNOWN = 0;
- MEMORY_STATE_NORMAL = 1; // normal.
- MEMORY_STATE_MODERATE = 2; // moderate memory pressure.
- MEMORY_STATE_LOW = 3; // low memory.
- MEMORY_STATE_CRITICAL = 4; // critical memory.
-}
-
-// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
-// and not frameworks/base/core/java/android/app/ActivityManager.java
-enum ProcessState {
- PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process.
- PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity.
- PROCESS_STATE_TOP = 2;
- // Important foreground process (ime, wallpaper, etc).
- PROCESS_STATE_IMPORTANT_FOREGROUND = 3;
- // Important background process.
- PROCESS_STATE_IMPORTANT_BACKGROUND = 4;
- // Performing backup operation.
- PROCESS_STATE_BACKUP = 5;
- // Background process running a service.
- PROCESS_STATE_SERVICE = 6;
- // Process not running, but would be if there was enough RAM.
- PROCESS_STATE_SERVICE_RESTARTING = 7;
- // Process running a receiver.
- PROCESS_STATE_RECEIVER = 8;
- // Heavy-weight process (currently not used).
- PROCESS_STATE_HEAVY_WEIGHT = 9;
- // Process hosting home/launcher app when not on top.
- PROCESS_STATE_HOME = 10;
- // Process hosting the last app the user was in.
- PROCESS_STATE_LAST_ACTIVITY = 11;
- // Cached process hosting a previous activity.
- PROCESS_STATE_CACHED_ACTIVITY = 12;
- // Cached process hosting a client activity.
- PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 13;
- // Cached process that is empty.
- PROCESS_STATE_CACHED_EMPTY = 14;
-}
-
-enum ServiceOperationState {
- SERVICE_OPERATION_STATE_UNKNOWN = 0;
- SERVICE_OPERATION_STATE_RUNNING = 1;
- SERVICE_OPERATION_STATE_STARTED = 2;
- SERVICE_OPERATION_STATE_FOREGROUND = 3;
- SERVICE_OPERATION_STATE_BOUND = 4;
- SERVICE_OPERATION_STATE_EXECUTING = 5;
-}
-
-// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
-// and not frameworks/base/core/java/android/app/ActivityManager.java
-enum AggregatedProcessState {
- AGGREGATED_PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process; PERSISTENT or PERSISTENT_UI in ActivityManager
- AGGREGATED_PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity; TOP or TOP_SLEEPING in ActivityManager
- AGGREGATED_PROCESS_STATE_TOP = 2;
- // Bound top foreground process; BOUND_TOP or BOUND_FOREGROUND_SERVICE in ActivityManager
- AGGREGATED_PROCESS_STATE_BOUND_TOP_OR_FGS = 3;
- // Important foreground process; FOREGROUND_SERVICE in ActivityManager
- AGGREGATED_PROCESS_STATE_FGS = 4;
- // Important foreground process ; IMPORTANT_FOREGROUND in ActivityManager
- AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND = 5;
- // Various background processes; IMPORTANT_BACKGROUND, TRANSIENT_BACKGROUND, BACKUP, SERVICE,
- // HEAVY_WEIGHT in ActivityManager
- AGGREGATED_PROCESS_STATE_BACKGROUND = 6;
- // Process running a receiver; RECEIVER in ActivityManager
- AGGREGATED_PROCESS_STATE_RECEIVER = 7;
- // Various cached processes; HOME, LAST_ACTIVITY, CACHED_ACTIVITY, CACHED_RECENT,
- // CACHED_ACTIVITY_CLIENT, CACHED_EMPTY in ActivityManager
- AGGREGATED_PROCESS_STATE_CACHED = 8;
-} \ No newline at end of file
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
deleted file mode 100644
index 40c5a85e1f24..000000000000
--- a/core/proto/android/service/usb.proto
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service.usb;
-
-option java_multiple_files = true;
-option java_outer_classname = "UsbServiceProto";
-
-import "frameworks/base/core/proto/android/content/component_name.proto";
-import "frameworks/base/core/proto/android/service/enums.proto";
-import "frameworks/base/core/proto/android/privacy.proto";
-
-message UsbServiceDumpProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceManagerProto device_manager = 1;
- optional UsbHostManagerProto host_manager = 2;
- optional UsbPortManagerProto port_manager = 3;
- optional UsbAlsaManagerProto alsa_manager = 4;
- optional UsbSettingsManagerProto settings_manager = 5;
- optional UsbPermissionsManagerProto permissions_manager = 6;
-}
-
-message UsbDeviceManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbHandlerProto handler = 1;
- optional UsbDebuggingManagerProto debugging_manager = 2;
-}
-
-message UsbHandlerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */
- enum Function {
- FUNCTION_ADB = 1;
- FUNCTION_ACCESSORY = 2;
- FUNCTION_MTP = 4;
- FUNCTION_MIDI = 8;
- FUNCTION_PTP = 16;
- FUNCTION_RNDIS = 32;
- FUNCTION_AUDIO_SOURCE = 64;
- }
-
- repeated Function current_functions = 1;
- optional bool current_functions_applied = 2;
- repeated Function screen_unlocked_functions = 3;
- optional bool screen_locked = 4;
- optional bool connected = 5;
- optional bool configured = 6;
- optional UsbAccessoryProto current_accessory = 7;
- optional bool host_connected = 8;
- optional bool source_power = 9;
- optional bool sink_power = 10;
- optional bool usb_charging = 11;
- optional bool hide_usb_notification = 12;
- optional bool audio_accessory_connected = 13;
- optional bool adb_enabled = 14;
- optional string kernel_state = 15;
- optional string kernel_function_list = 16;
-}
-
-message UsbAccessoryProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string manufacturer = 1;
- optional string model = 2;
- // For "classical" USB-accessories the manufacturer bakes this into the
- // firmware of the device. If an Android phone is configured as accessory, the
- // app that sets up the accessory side of the connection set this. Either way,
- // these are part of the detection protocol, and so they cannot be user set or
- // unique.
- optional string description = 3;
- optional string version = 4;
- optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ];
- // Non-resettable hardware ID.
- optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ];
-}
-
-message UsbDebuggingManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool connected_to_adb = 1;
- // A workstation that connects to the phone for debugging is identified by
- // this key.
- optional string last_key_received = 2 [ (android.privacy).dest = DEST_EXPLICIT ];
- optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ];
- optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ];
-}
-
-message UsbHostManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto default_usb_host_connection_handler = 1;
- repeated UsbDeviceProto devices = 2;
- optional int32 num_connects = 3;
- repeated UsbConnectionRecordProto connections = 4;
-}
-
-message UsbDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Generic USB name, not user-provided.
- optional string name = 1;
- // ID specific to the vendor, not the device.
- optional int32 vendor_id = 2;
- // ID of this product type: Each vendor gives each product a unique ID. E.g.
- // all mice of the same model would have the same ID.
- optional int32 product_id = 3;
- optional int32 class = 4;
- optional int32 subclass = 5;
- optional int32 protocol = 6;
- optional string manufacturer_name = 7;
- optional string product_name = 8;
- optional string version = 9;
- // Non-resettable hardware ID.
- optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ];
- repeated UsbConfigurationProto configurations = 11;
-}
-
-message UsbConfigurationProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // A single USB device can have several configurations and the app accessing
- // the USB device can switch between them. At any time only one can be active.
- // Each configuration can present completely different interfaces end
- // endpoints, i.e. a completely different behavior.
- optional int32 id = 1;
- // Hardware-defined name, not set by the user.
- optional string name = 2;
- optional uint32 attributes = 3;
- optional int32 max_power = 4;
- repeated UsbInterfaceProto interfaces = 5;
-}
-
-message UsbInterfaceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Hardware defined. This is the id used by the app to identify the interface.
- optional int32 id = 1;
- optional int32 alternate_settings = 2;
- optional string name = 3;
- optional int32 class = 4;
- optional int32 subclass = 5;
- optional int32 protocol = 6;
- repeated UsbEndPointProto endpoints = 7;
-}
-
-message UsbEndPointProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 endpoint_number = 1;
- optional android.service.UsbEndPointDirection direction = 2;
- // The address of the endpoint. Needed to read and write to the endpoint.
- optional int32 address = 3;
- optional android.service.UsbEndPointType type = 4;
- optional uint32 attributes = 5;
- optional int32 max_packet_size = 6;
- optional int32 interval = 7;
-}
-
-message UsbConnectionRecordProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string device_address = 1;
- optional android.service.UsbConnectionRecordMode mode = 2;
- optional int64 timestamp = 3;
- optional int32 manufacturer = 4;
- optional int32 product = 5;
- optional UsbIsHeadsetProto is_headset = 6;
-}
-
-message UsbIsHeadsetProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool in = 1;
- optional bool out = 2;
-}
-
-message UsbPortManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool is_simulation_active = 1;
- repeated UsbPortInfoProto usb_ports = 2;
-}
-
-message UsbPortInfoProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbPortProto port = 1;
- optional UsbPortStatusProto status = 2;
- optional bool can_change_mode = 3;
- optional bool can_change_power_role = 4;
- optional bool can_change_data_role = 5;
- optional int64 connected_at_millis = 6;
- optional int64 last_connect_duration_millis = 7;
-}
-
-message UsbPortProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */
- enum Mode {
- MODE_NONE = 0;
- MODE_UFP = 1;
- MODE_DFP = 2;
- MODE_DRP = 3;
- MODE_AUDIO_ACCESSORY = 4;
- MODE_DEBUG_ACCESSORY = 8;
- }
-
- // ID of the port. A device (eg: Chromebooks) might have multiple ports.
- optional string id = 1;
- repeated Mode supported_modes = 2;
-}
-
-/* Same as android.hardware.usb.V1_2.Constants.ContaminantPresenceStatus */
-enum ContaminantPresenceStatus {
- CONTAMINANT_STATUS_UNKNOWN = 0;
- CONTAMINANT_STATUS_NOT_SUPPORTED = 1;
- CONTAMINANT_STATUS_DISABLED = 2;
- CONTAMINANT_STATUS_NOT_DETECTED = 3;
- CONTAMINANT_STATUS_DETECTED = 4;
-}
-
-message UsbPortStatusProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */
- enum PowerRole {
- POWER_ROLE_NONE = 0;
- POWER_ROLE_SOURCE = 1;
- POWER_ROLE_SINK = 2;
- }
-
- /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */
- enum DataRole {
- DATA_ROLE_NONE = 0;
- DATA_ROLE_HOST = 1;
- DATA_ROLE_DEVICE = 2;
- }
-
- optional bool connected = 1;
- optional UsbPortProto.Mode current_mode = 2;
- optional PowerRole power_role = 3;
- optional DataRole data_role = 4;
- repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
- optional ContaminantPresenceStatus contaminant_presence_status = 6;
-}
-
-message UsbPortStatusRoleCombinationProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbPortStatusProto.PowerRole power_role = 1;
- optional UsbPortStatusProto.DataRole data_role = 2;
-}
-
-message UsbAlsaManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 cards_parser = 1;
- repeated UsbAlsaDeviceProto alsa_devices = 2;
- repeated UsbMidiDeviceProto midi_devices = 3;
-}
-
-message UsbAlsaDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 card = 1;
- optional int32 device = 2;
- optional string name = 3;
- optional bool has_playback = 4;
- optional bool has_capture = 5;
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string address = 6;
-}
-
-message UsbMidiDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 card = 1;
- optional int32 device = 2;
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string device_address = 3;
-}
-
-message UsbSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated UsbUserSettingsManagerProto user_settings = 1;
- repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2;
-}
-
-message UsbUserSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
- reserved 2; // previously device_permissions, now unused
- reserved 3; // previously accessory_permissions, now unused
- repeated UsbDeviceAttachedActivities device_attached_activities = 4;
- repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
-}
-
-message UsbProfileGroupSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // The user id of the personal profile if the device has a work profile.
- optional int32 parent_user_id = 1;
- repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
- repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
-}
-
-message UsbSettingsDevicePreferenceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceFilterProto filter = 1;
- optional UserPackageProto user_package = 2;
-}
-
-message UsbPermissionsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated UsbUserPermissionsManagerProto user_permissions = 1;
-}
-
-message UsbUserPermissionsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
-
- repeated UsbDevicePermissionProto device_permissions = 2;
- repeated UsbAccessoryPermissionProto accessory_permissions = 3;
-
- repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
- repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
-}
-
-message UsbDevicePermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Name of device set by manufacturer
- // All devices of the same model have the same name
- optional string device_name = 1;
- repeated int32 uids = 2;
-}
-
-message UsbAccessoryPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Description of accessory set by manufacturer
- // All accessories of the same model have the same description
- optional string accessory_description = 1;
- repeated int32 uids = 2;
-}
-
-message UsbDevicePersistentPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceFilterProto device_filter = 1;
- repeated UsbUidPermissionProto permission_values = 2;
-}
-
-message UsbAccessoryPersistentPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbAccessoryFilterProto accessory_filter = 1;
- repeated UsbUidPermissionProto permission_values = 2;
-}
-
-message UsbUidPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 uid = 1;
- optional bool is_granted = 2;
-}
-
-message UsbDeviceFilterProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Mirrors the vendor_id of UsbDeviceProto.
- optional int32 vendor_id = 1;
- optional int32 product_id = 2;
- optional int32 class = 3;
- optional int32 subclass = 4;
- optional int32 protocol = 5;
- optional string manufacturer_name = 6;
- optional string product_name = 7;
- optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ];
-}
-
-message UserPackageProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
- optional string package_name =2;
-}
-
-message UsbSettingsAccessoryPreferenceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbAccessoryFilterProto filter = 1;
- optional UserPackageProto user_package = 2;
-}
-
-message UsbAccessoryFilterProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string manufacturer = 1;
- optional string model = 2;
- optional string version = 3;
-}
-
-message UsbDeviceAttachedActivities {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto activity = 1;
- repeated UsbDeviceFilterProto filters = 2;
-}
-
-message UsbAccessoryAttachedActivities {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto activity = 1;
- repeated UsbAccessoryFilterProto filters = 2;
-}
diff --git a/core/proto/android/stats/accessibility/accessibility_enums.proto b/core/proto/android/stats/accessibility/accessibility_enums.proto
deleted file mode 100644
index 5118ad5a322c..000000000000
--- a/core/proto/android/stats/accessibility/accessibility_enums.proto
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.accessibility;
-option java_multiple_files = true;
-
-// The entry point of the accessibility shortcut.
-enum ShortcutType {
- UNKNOWN_TYPE = 0;
- A11Y_BUTTON = 1;
- VOLUME_KEY = 2;
- TRIPLE_TAP = 3;
- A11Y_BUTTON_LONG_PRESS = 4;
-}
-
-// The service status code.
-enum ServiceStatus {
- UNKNOWN = 0;
- ENABLED = 1;
- DISABLED = 2;
-} \ No newline at end of file
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
deleted file mode 100644
index 5e6ac3cd3ca1..000000000000
--- a/core/proto/android/stats/connectivity/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "networkstackprotos",
- proto: {
- type: "lite",
- },
- srcs: [
- "network_stack.proto",
- ],
- sdk_version: "system_29",
-}
-
-java_library_static {
- name: "tetheringprotos",
- proto: {
- type: "lite",
- },
- srcs: [
- "tethering.proto",
- ],
- apex_available: [
- "com.android.tethering",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/stats/connectivity/network_stack.proto b/core/proto/android/stats/connectivity/network_stack.proto
deleted file mode 100644
index e9726d7ce195..000000000000
--- a/core/proto/android/stats/connectivity/network_stack.proto
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "NetworkStackProto";
-
-enum DhcpRenewResult {
- RR_UNKNOWN = 0;
- RR_SUCCESS = 1;
- RR_ERROR_NAK = 2;
- RR_ERROR_IP_MISMATCH = 3;
- RR_ERROR_IP_EXPIRE = 4;
-}
-
-enum DisconnectCode {
- DC_NONE = 0;
- DC_NORMAL_TERMINATION = 1;
- DC_PROVISIONING_FAIL = 2;
- DC_ERROR_STARTING_IPV4 = 4;
- DC_ERROR_STARTING_IPV6 = 5;
- DC_ERROR_STARTING_IPREACHABILITYMONITOR = 6;
- DC_INVALID_PROVISIONING = 7;
- DC_INTERFACE_NOT_FOUND = 8;
- DC_PROVISIONING_TIMEOUT = 9;
-}
-
-enum TransportType {
- TT_UNKNOWN = 0;
- // Indicates this network uses a Cellular transport
- TT_CELLULAR = 1;
- // Indicates this network uses a Wi-Fi transport
- TT_WIFI = 2;
- // Indicates this network uses a Bluetooth transport
- TT_BLUETOOTH = 3;
- // Indicates this network uses an Ethernet transport
- TT_ETHERNET = 4;
- // Indicates this network uses a Wi-Fi Aware transport
- TT_WIFI_AWARE = 5;
- // Indicates this network uses a LoWPAN transport
- TT_LOWPAN = 6;
- // Indicates this network uses a Cellular+VPN transport
- TT_CELLULAR_VPN = 7;
- // Indicates this network uses a Wi-Fi+VPN transport
- TT_WIFI_VPN = 8;
- // Indicates this network uses a Bluetooth+VPN transport
- TT_BLUETOOTH_VPN = 9;
- // Indicates this network uses an Ethernet+VPN transport
- TT_ETHERNET_VPN = 10;
- // Indicates this network uses a Wi-Fi+Cellular+VPN transport
- TT_WIFI_CELLULAR_VPN = 11;
- // Indicates this network uses for test only
- TT_TEST = 12;
-}
-
-enum DhcpFeature {
- DF_UNKNOWN = 0;
- // DHCP INIT-REBOOT state
- DF_INITREBOOT = 1;
- // DHCP rapid commit option
- DF_RAPIDCOMMIT = 2;
- // Duplicate address detection
- DF_DAD = 3;
- // Fast initial Link setup
- DF_FILS = 4;
-}
-
-enum HostnameTransResult {
- HTR_UNKNOWN = 0;
- HTR_SUCCESS = 1;
- HTR_FAILURE = 2;
- HTR_DISABLE = 3;
-}
-
-enum ProbeResult {
- PR_UNKNOWN = 0;
- PR_SUCCESS = 1;
- PR_FAILURE = 2;
- PR_PORTAL = 3;
- // DNS query for the probe host returned a private IP address
- PR_PRIVATE_IP_DNS = 4;
-}
-
-enum ValidationResult {
- VR_UNKNOWN = 0;
- VR_SUCCESS = 1;
- VR_FAILURE = 2;
- VR_PORTAL = 3;
- VR_PARTIAL = 4;
-}
-
-enum ProbeType {
- PT_UNKNOWN = 0;
- PT_DNS = 1;
- PT_HTTP = 2;
- PT_HTTPS = 3;
- PT_PAC = 4;
- PT_FALLBACK = 5;
- PT_PRIVDNS = 6;
- PT_CAPPORT_API = 7;
-}
-
-// The Dhcp error code is defined in android.net.metrics.DhcpErrorEvent
-enum DhcpErrorCode {
- ET_UNKNOWN = 0;
- ET_L2_ERROR = 1;
- ET_L3_ERROR = 2;
- ET_L4_ERROR = 3;
- ET_DHCP_ERROR = 4;
- ET_MISC_ERROR = 5;
- /* Reserve for error type
- // ET_L2_ERROR_TYPE = ET_L2_ERROR << 8;
- ET_L2_ERROR_TYPE = 256;
- // ET_L3_ERROR_TYPE = ET_L3_ERROR << 8;
- ET_L3_ERROR_TYPE = 512;
- // ET_L4_ERROR_TYPE = ET_L4_ERROR << 8;
- ET_L4_ERROR_TYPE = 768;
- // ET_DHCP_ERROR_TYPE = ET_DHCP_ERROR << 8;
- ET_DHCP_ERROR_TYPE = 1024;
- // ET_MISC_ERROR_TYPE = ET_MISC_ERROR << 8;
- ET_MISC_ERROR_TYPE = 1280;
- */
- // ET_L2_TOO_SHORT = (ET_L2_ERROR_TYPE | 0x1) << 16;
- ET_L2_TOO_SHORT = 16842752;
- // ET_L2_WRONG_ETH_TYPE = (ET_L2_ERROR_TYPE | 0x2) << 16;
- ET_L2_WRONG_ETH_TYPE = 16908288;
- // ET_L3_TOO_SHORT = (ET_L3_ERROR_TYPE | 0x1) << 16;
- ET_L3_TOO_SHORT = 33619968;
- // ET_L3_NOT_IPV4 = (ET_L3_ERROR_TYPE | 0x2) << 16;
- ET_L3_NOT_IPV4 = 33685504;
- // ET_L3_INVALID_IP = (ET_L3_ERROR_TYPE | 0x3) << 16;
- ET_L3_INVALID_IP = 33751040;
- // ET_L4_NOT_UDP = (ET_L4_ERROR_TYPE | 0x1) << 16;
- ET_L4_NOT_UDP = 50397184;
- // ET_L4_WRONG_PORT = (ET_L4_ERROR_TYPE | 0x2) << 16;
- ET_L4_WRONG_PORT = 50462720;
- // ET_BOOTP_TOO_SHORT = (ET_DHCP_ERROR_TYPE | 0x1) << 16;
- ET_BOOTP_TOO_SHORT = 67174400;
- // ET_DHCP_BAD_MAGIC_COOKIE = (ET_DHCP_ERROR_TYPE | 0x2) << 16;
- ET_DHCP_BAD_MAGIC_COOKIE = 67239936;
- // ET_DHCP_INVALID_OPTION_LENGTH = (ET_DHCP_ERROR_TYPE | 0x3) << 16;
- ET_DHCP_INVALID_OPTION_LENGTH = 67305472;
- // ET_DHCP_NO_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x4) << 16;
- ET_DHCP_NO_MSG_TYPE = 67371008;
- // ET_DHCP_UNKNOWN_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x5) << 16;
- ET_DHCP_UNKNOWN_MSG_TYPE = 67436544;
- // ET_DHCP_NO_COOKIE = (ET_DHCP_ERROR_TYPE | 0x6) << 16;
- ET_DHCP_NO_COOKIE = 67502080;
- // ET_BUFFER_UNDERFLOW = (ET_MISC_ERROR_TYPE | 0x1) << 16;
- ET_BUFFER_UNDERFLOW = 83951616;
- // ET_RECEIVE_ERROR = (ET_MISC_ERROR_TYPE | 0x2) << 16;
- ET_RECEIVE_ERROR = 84017152;
- // ET_PARSING_ERROR = (ET_MISC_ERROR_TYPE | 0x3) << 16;
- ET_PARSING_ERROR = 84082688;
-}
-
-enum NetworkQuirkEvent {
- QE_UNKNOWN = 0;
- QE_IPV6_PROVISIONING_ROUTER_LOST = 1;
-}
-
-message NetworkStackEventData {
-
-}
-
diff --git a/core/proto/android/stats/connectivity/tethering.proto b/core/proto/android/stats/connectivity/tethering.proto
deleted file mode 100644
index 13f0b8c44fb5..000000000000
--- a/core/proto/android/stats/connectivity/tethering.proto
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "TetheringProto";
-
-enum ErrorCode {
- EC_NO_ERROR = 0;
- EC_UNKNOWN_IFACE = 1;
- EC_SERVICE_UNAVAIL = 2;
- EC_UNSUPPORTED = 3;
- EC_UNAVAIL_IFACE = 4;
- EC_INTERNAL_ERROR = 5;
- EC_TETHER_IFACE_ERROR = 6;
- EC_UNTETHER_IFACE_ERROR = 7;
- EC_ENABLE_FORWARDING_ERROR = 8;
- EC_DISABLE_FORWARDING_ERROR = 9;
- EC_IFACE_CFG_ERROR = 10;
- EC_PROVISIONING_FAILED = 11;
- EC_DHCPSERVER_ERROR = 12;
- EC_ENTITLEMENT_UNKNOWN = 13;
- EC_NO_CHANGE_TETHERING_PERMISSION = 14;
- EC_NO_ACCESS_TETHERING_PERMISSION = 15;
- EC_UNKNOWN_TYPE = 16;
-}
-
-enum DownstreamType {
- // Unspecific tethering type.
- DS_UNSPECIFIED = 0;
- // Wifi tethering type.
- DS_TETHERING_WIFI = 1;
- // USB tethering type.
- DS_TETHERING_USB = 2;
- // Bluetooth tethering type.
- DS_TETHERING_BLUETOOTH = 3;
- // Wifi P2p tethering type.
- DS_TETHERING_WIFI_P2P = 4;
- // NCM (Network Control Model) local tethering type.
- DS_TETHERING_NCM = 5;
- // Ethernet tethering type.
- DS_TETHERING_ETHERNET = 6;
-}
-
-enum UpstreamType {
- UT_UNKNOWN = 0;
- // Indicates upstream using a Cellular transport.
- UT_CELLULAR = 1;
- // Indicates upstream using a Wi-Fi transport.
- UT_WIFI = 2;
- // Indicates upstream using a Bluetooth transport.
- UT_BLUETOOTH = 3;
- // Indicates upstream using an Ethernet transport.
- UT_ETHERNET = 4;
- // Indicates upstream using a Wi-Fi Aware transport.
- UT_WIFI_AWARE = 5;
- // Indicates upstream using a LoWPAN transport.
- UT_LOWPAN = 6;
- // Indicates upstream using a Cellular+VPN transport.
- UT_CELLULAR_VPN = 7;
- // Indicates upstream using a Wi-Fi+VPN transport.
- UT_WIFI_VPN = 8;
- // Indicates upstream using a Bluetooth+VPN transport.
- UT_BLUETOOTH_VPN = 9;
- // Indicates upstream using an Ethernet+VPN transport.
- UT_ETHERNET_VPN = 10;
- // Indicates upstream using a Wi-Fi+Cellular+VPN transport.
- UT_WIFI_CELLULAR_VPN = 11;
- // Indicates upstream using for test only.
- UT_TEST = 12;
- // Indicates upstream using DUN capability + Cellular transport.
- UT_DUN_CELLULAR = 13;
-}
-
-enum UserType {
- // Unknown.
- USER_UNKNOWN = 0;
- // Settings.
- USER_SETTINGS = 1;
- // System UI.
- USER_SYSTEMUI = 2;
- // Google mobile service.
- USER_GMS = 3;
-}
diff --git a/core/proto/android/stats/devicepolicy/Android.bp b/core/proto/android/stats/devicepolicy/Android.bp
deleted file mode 100644
index 5fb278a34dae..000000000000
--- a/core/proto/android/stats/devicepolicy/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "devicepolicyprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "*.proto",
- ],
- java_version: "1.8",
- target: {
- android: {
- jarjar_rules: "jarjar-rules.txt",
- },
- host: {
- static_libs: ["libprotobuf-java-nano"],
- }
- },
- sdk_version: "core_platform",
-}
diff --git a/core/proto/android/stats/devicepolicy/device_policy.proto b/core/proto/android/stats/devicepolicy/device_policy.proto
deleted file mode 100644
index af30cf3f9941..000000000000
--- a/core/proto/android/stats/devicepolicy/device_policy.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.devicepolicy;
-option java_multiple_files = true;
-
-message StringList {
- repeated string string_value = 1;
-}
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
deleted file mode 100644
index 7c1a04944d68..000000000000
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.devicepolicy;
-option java_multiple_files = true;
-
-/**
- * Id for device policy features.
- */
-enum EventId {
- SET_PASSWORD_QUALITY = 1;
- SET_PASSWORD_MINIMUM_LENGTH = 2;
- SET_PASSWORD_MINIMUM_NUMERIC = 3;
- SET_PASSWORD_MINIMUM_NON_LETTER = 4;
- SET_PASSWORD_MINIMUM_LETTERS = 5;
- SET_PASSWORD_MINIMUM_LOWER_CASE = 6;
- SET_PASSWORD_MINIMUM_UPPER_CASE = 7;
- SET_PASSWORD_MINIMUM_SYMBOLS = 8;
- SET_KEYGUARD_DISABLED_FEATURES = 9;
- LOCK_NOW = 10;
- WIPE_DATA_WITH_REASON = 11;
- ADD_USER_RESTRICTION = 12;
- REMOVE_USER_RESTRICTION = 13;
- SET_SECURE_SETTING = 14;
- SET_SECURITY_LOGGING_ENABLED = 15;
- RETRIEVE_SECURITY_LOGS = 16;
- RETRIEVE_PRE_REBOOT_SECURITY_LOGS = 17;
- SET_PERMISSION_POLICY = 18;
- SET_PERMISSION_GRANT_STATE = 19;
- INSTALL_KEY_PAIR = 20;
- INSTALL_CA_CERT = 21;
- CHOOSE_PRIVATE_KEY_ALIAS = 22;
- REMOVE_KEY_PAIR = 23;
- UNINSTALL_CA_CERTS = 24;
- SET_CERT_INSTALLER_PACKAGE = 25;
- SET_ALWAYS_ON_VPN_PACKAGE = 26;
- SET_PERMITTED_INPUT_METHODS = 27;
- SET_PERMITTED_ACCESSIBILITY_SERVICES = 28;
- SET_SCREEN_CAPTURE_DISABLED = 29;
- SET_CAMERA_DISABLED = 30;
- QUERY_SUMMARY_FOR_USER = 31;
- QUERY_SUMMARY = 32;
- QUERY_DETAILS = 33;
- REBOOT = 34;
- SET_MASTER_VOLUME_MUTED = 35;
- SET_AUTO_TIME_REQUIRED = 36;
- SET_KEYGUARD_DISABLED = 37;
- SET_STATUS_BAR_DISABLED = 38;
- SET_ORGANIZATION_COLOR = 39;
- SET_PROFILE_NAME = 40;
- SET_USER_ICON = 41;
- SET_DEVICE_OWNER_LOCK_SCREEN_INFO = 42;
- SET_SHORT_SUPPORT_MESSAGE = 43;
- SET_LONG_SUPPORT_MESSAGE = 44;
- SET_CROSS_PROFILE_CONTACTS_SEARCH_DISABLED = 45;
- SET_CROSS_PROFILE_CALLER_ID_DISABLED = 46;
- SET_BLUETOOTH_CONTACT_SHARING_DISABLED = 47;
- ADD_CROSS_PROFILE_INTENT_FILTER = 48;
- ADD_CROSS_PROFILE_WIDGET_PROVIDER = 49;
- SET_SYSTEM_UPDATE_POLICY = 50;
- SET_LOCKTASK_MODE_ENABLED = 51;
- ADD_PERSISTENT_PREFERRED_ACTIVITY = 52;
- REQUEST_BUGREPORT = 53;
- GET_WIFI_MAC_ADDRESS = 54;
- REQUEST_QUIET_MODE_ENABLED = 55;
- WORK_PROFILE_LOCATION_CHANGED = 56;
- DO_USER_INFO_CLICKED = 57;
- TRANSFER_OWNERSHIP = 58;
- GENERATE_KEY_PAIR = 59;
- SET_KEY_PAIR_CERTIFICATE = 60;
- SET_KEEP_UNINSTALLED_PACKAGES = 61;
- SET_APPLICATION_RESTRICTIONS = 62;
- SET_APPLICATION_HIDDEN = 63;
- ENABLE_SYSTEM_APP = 64;
- ENABLE_SYSTEM_APP_WITH_INTENT = 65;
- INSTALL_EXISTING_PACKAGE = 66;
- SET_UNINSTALL_BLOCKED = 67;
- SET_PACKAGES_SUSPENDED = 68;
- ON_LOCK_TASK_MODE_ENTERING = 69;
- SET_CROSS_PROFILE_CALENDAR_PACKAGES = 70;
- GET_USER_PASSWORD_COMPLEXITY_LEVEL = 72;
- INSTALL_SYSTEM_UPDATE = 73;
- INSTALL_SYSTEM_UPDATE_ERROR = 74;
- IS_MANAGED_KIOSK = 75;
- IS_UNATTENDED_MANAGED_KIOSK = 76;
- PROVISIONING_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 77;
- PROVISIONING_PERSISTENT_DEVICE_OWNER = 78;
-
- // existing Tron logs to be migrated to statsd
- PROVISIONING_ENTRY_POINT_NFC = 79;
- PROVISIONING_ENTRY_POINT_QR_CODE = 80;
- PROVISIONING_ENTRY_POINT_CLOUD_ENROLLMENT = 81;
- PROVISIONING_ENTRY_POINT_ADB = 82;
- PROVISIONING_ENTRY_POINT_TRUSTED_SOURCE = 83;
- PROVISIONING_DPC_PACKAGE_NAME = 84;
- PROVISIONING_DPC_INSTALLED_BY_PACKAGE = 85;
- PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS = 86;
- PROVISIONING_PREPROVISIONING_ACTIVITY_TIME_MS = 87;
- PROVISIONING_ENCRYPT_DEVICE_ACTIVITY_TIME_MS = 88;
- PROVISIONING_WEB_ACTIVITY_TIME_MS = 89;
- PROVISIONING_TRAMPOLINE_ACTIVITY_TIME_MS = 90 [deprecated=true];
- PROVISIONING_POST_ENCRYPTION_ACTIVITY_TIME_MS = 91 [deprecated=true];
- PROVISIONING_FINALIZATION_ACTIVITY_TIME_MS = 92 [deprecated=true];
- PROVISIONING_NETWORK_TYPE = 93;
- PROVISIONING_ACTION = 94;
- PROVISIONING_EXTRAS = 95;
- PROVISIONING_COPY_ACCOUNT_TASK_MS = 96;
- PROVISIONING_CREATE_PROFILE_TASK_MS = 97;
- PROVISIONING_START_PROFILE_TASK_MS = 98;
- PROVISIONING_DOWNLOAD_PACKAGE_TASK_MS = 99;
- PROVISIONING_INSTALL_PACKAGE_TASK_MS = 100;
- PROVISIONING_CANCELLED = 101;
- PROVISIONING_ERROR = 102;
- PROVISIONING_COPY_ACCOUNT_STATUS = 103;
- PROVISIONING_TOTAL_TASK_TIME_MS = 104;
- PROVISIONING_SESSION_STARTED = 105;
- PROVISIONING_SESSION_COMPLETED = 106;
- PROVISIONING_TERMS_ACTIVITY_TIME_MS = 107;
- PROVISIONING_TERMS_COUNT = 108;
- PROVISIONING_TERMS_READ = 109;
-
- SEPARATE_PROFILE_CHALLENGE_CHANGED = 110;
- SET_GLOBAL_SETTING = 111;
- INSTALL_PACKAGE = 112;
- UNINSTALL_PACKAGE = 113;
- WIFI_SERVICE_ADD_NETWORK_SUGGESTIONS = 114;
- WIFI_SERVICE_ADD_OR_UPDATE_NETWORK = 115;
- QUERY_SUMMARY_FOR_DEVICE = 116;
- REMOVE_CROSS_PROFILE_WIDGET_PROVIDER = 117;
- ESTABLISH_VPN = 118;
- SET_NETWORK_LOGGING_ENABLED = 119;
- RETRIEVE_NETWORK_LOGS = 120;
- PROVISIONING_PREPARE_TOTAL_TIME_MS = 121;
- PROVISIONING_PREPARE_STARTED = 122;
- PROVISIONING_PREPARE_COMPLETED = 123;
- PROVISIONING_FLOW_TYPE = 124;
- CROSS_PROFILE_APPS_GET_TARGET_USER_PROFILES = 125;
- CROSS_PROFILE_APPS_START_ACTIVITY_AS_USER = 126;
- SET_AUTO_TIME = 127;
- SET_AUTO_TIME_ZONE = 128;
- SET_USER_CONTROL_DISABLED_PACKAGES = 129;
- SET_FACTORY_RESET_PROTECTION = 130;
- SET_COMMON_CRITERIA_MODE = 131;
- ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS = 132;
- SET_TIME = 133;
- SET_TIME_ZONE = 134;
- SET_PERSONAL_APPS_SUSPENDED = 135;
- SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF = 136;
- COMP_TO_ORG_OWNED_PO_MIGRATED = 137;
- SET_CROSS_PROFILE_PACKAGES = 138;
- SET_INTERACT_ACROSS_PROFILES_APP_OP = 139;
- GET_CROSS_PROFILE_PACKAGES = 140;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_TRUE = 141;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 142;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_WHITELIST = 143;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 144;
- CAN_INTERACT_ACROSS_PROFILES_TRUE = 145;
- CAN_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 146;
- CAN_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 147;
- CREATE_CROSS_PROFILE_INTENT = 148;
- IS_MANAGED_PROFILE = 149;
- START_ACTIVITY_BY_INTENT = 150;
- BIND_CROSS_PROFILE_SERVICE = 151;
- PROVISIONING_DPC_SETUP_STARTED = 152;
- PROVISIONING_DPC_SETUP_COMPLETED = 153;
- PROVISIONING_ORGANIZATION_OWNED_MANAGED_PROFILE = 154;
- RESOLVER_CROSS_PROFILE_TARGET_OPENED = 155;
- RESOLVER_SWITCH_TABS = 156;
- RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED = 157;
- RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL= 158;
- RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK= 159;
- RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED= 160;
- RESOLVER_AUTOLAUNCH_CROSS_PROFILE_TARGET = 161;
- CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP = 162;
- CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS = 163;
- CROSS_PROFILE_SETTINGS_PAGE_ADMIN_RESTRICTED = 164;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_WORK_APP = 165;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_PERSONAL_APP = 166;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_INSTALL_BANNER_INTENT = 167;
- CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED = 168;
- CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_NO_INTENT_CLICKED = 169;
- CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED = 170;
- CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT = 171;
- CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED = 172;
- DOCSUI_EMPTY_STATE_NO_PERMISSION = 173;
- DOCSUI_EMPTY_STATE_QUIET_MODE = 174;
- DOCSUI_LAUNCH_OTHER_APP = 175;
- DOCSUI_PICK_RESULT = 176;
-}
diff --git a/core/proto/android/stats/devicepolicy/jarjar-rules.txt b/core/proto/android/stats/devicepolicy/jarjar-rules.txt
deleted file mode 100644
index 40043a861ceb..000000000000
--- a/core/proto/android/stats/devicepolicy/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp
deleted file mode 100644
index 1e8c76314448..000000000000
--- a/core/proto/android/stats/dnsresolver/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "dnsresolverprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "dns_resolver.proto",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
deleted file mode 100644
index b17d12c9c315..000000000000
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.dnsresolver;
-
-enum EventType {
- EVENT_UNKNOWN = 0;
- EVENT_GETADDRINFO = 1;
- EVENT_GETHOSTBYNAME = 2;
- EVENT_GETHOSTBYADDR = 3;
- EVENT_RES_NSEND = 4;
-}
-
-// The return value of the DNS resolver for each DNS lookups.
-// bionic/libc/include/netdb.h
-// system/netd/resolv/include/netd_resolv/resolv.h
-enum ReturnCode {
- RC_EAI_NO_ERROR = 0;
- RC_EAI_ADDRFAMILY = 1;
- RC_EAI_AGAIN = 2;
- RC_EAI_BADFLAGS = 3;
- RC_EAI_FAIL = 4;
- RC_EAI_FAMILY = 5;
- RC_EAI_MEMORY = 6;
- RC_EAI_NODATA = 7;
- RC_EAI_NONAME = 8;
- RC_EAI_SERVICE = 9;
- RC_EAI_SOCKTYPE = 10;
- RC_EAI_SYSTEM = 11;
- RC_EAI_BADHINTS = 12;
- RC_EAI_PROTOCOL = 13;
- RC_EAI_OVERFLOW = 14;
- RC_RESOLV_INTERNAL_ERROR = 254;
- RC_RESOLV_TIMEOUT = 255;
- RC_EAI_MAX = 256;
-}
-
-enum NsRcode {
- NS_R_NO_ERROR = 0; // No error occurred.
- NS_R_FORMERR = 1; // Format error.
- NS_R_SERVFAIL = 2; // Server failure.
- NS_R_NXDOMAIN = 3; // Name error.
- NS_R_NOTIMPL = 4; // Unimplemented.
- NS_R_REFUSED = 5; // Operation refused.
- // these are for BIND_UPDATE
- NS_R_YXDOMAIN = 6; // Name exists
- NS_R_YXRRSET = 7; // RRset exists
- NS_R_NXRRSET = 8; // RRset does not exist
- NS_R_NOTAUTH = 9; // Not authoritative for zone
- NS_R_NOTZONE = 10; // Zone of record different from zone section
- NS_R_MAX = 11;
- // Define rcode=12~15(UNASSIGNED) in rcode enum type.
- // Some DNS Servers might return undefined code to devices.
- // Without the enum definition, that would be noise for our dashboard.
- NS_R_UNASSIGNED12 = 12; // Unassigned
- NS_R_UNASSIGNED13 = 13; // Unassigned
- NS_R_UNASSIGNED14 = 14; // Unassigned
- NS_R_UNASSIGNED15 = 15; // Unassigned
- // The following are EDNS extended rcodes
- NS_R_BADVERS = 16;
- // The following are TSIG errors
- // NS_R_BADSIG = 16,
- NS_R_BADKEY = 17;
- NS_R_BADTIME = 18;
- NS_R_INTERNAL_ERROR = 254;
- NS_R_TIMEOUT = 255;
-}
-
-// Currently defined type values for resources and queries.
-enum NsType {
- NS_T_INVALID = 0; // Cookie.
- NS_T_A = 1; // Host address.
- NS_T_NS = 2; // Authoritative server.
- NS_T_MD = 3; // Mail destination.
- NS_T_MF = 4; // Mail forwarder.
- NS_T_CNAME = 5; // Canonical name.
- NS_T_SOA = 6; // Start of authority zone.
- NS_T_MB = 7; // Mailbox domain name.
- NS_T_MG = 8; // Mail group member.
- NS_T_MR = 9; // Mail rename name.
- NS_T_NULL = 10; // Null resource record.
- NS_T_WKS = 11; // Well known service.
- NS_T_PTR = 12; // Domain name pointer.
- NS_T_HINFO = 13; // Host information.
- NS_T_MINFO = 14; // Mailbox information.
- NS_T_MX = 15; // Mail routing information.
- NS_T_TXT = 16; // Text strings.
- NS_T_RP = 17; // Responsible person.
- NS_T_AFSDB = 18; // AFS cell database.
- NS_T_X25 = 19; // X_25 calling address.
- NS_T_ISDN = 20; // ISDN calling address.
- NS_T_RT = 21; // Router.
- NS_T_NSAP = 22; // NSAP address.
- NS_T_NSAP_PTR = 23; // Reverse NSAP lookup (deprecated).
- NS_T_SIG = 24; // Security signature.
- NS_T_KEY = 25; // Security key.
- NS_T_PX = 26; // X.400 mail mapping.
- NS_T_GPOS = 27; // Geographical position (withdrawn).
- NS_T_AAAA = 28; // IPv6 Address.
- NS_T_LOC = 29; // Location Information.
- NS_T_NXT = 30; // Next domain (security).
- NS_T_EID = 31; // Endpoint identifier.
- NS_T_NIMLOC = 32; // Nimrod Locator.
- NS_T_SRV = 33; // Server Selection.
- NS_T_ATMA = 34; // ATM Address
- NS_T_NAPTR = 35; // Naming Authority PoinTeR
- NS_T_KX = 36; // Key Exchange
- NS_T_CERT = 37; // Certification record
- NS_T_A6 = 38; // IPv6 address (experimental)
- NS_T_DNAME = 39; // Non-terminal DNAME
- NS_T_SINK = 40; // Kitchen sink (experimentatl)
- NS_T_OPT = 41; // EDNS0 option (meta-RR)
- NS_T_APL = 42; // Address prefix list (RFC 3123)
- NS_T_DS = 43; // Delegation Signer
- NS_T_SSHFP = 44; // SSH Fingerprint
- NS_T_IPSECKEY = 45; // IPSEC Key
- NS_T_RRSIG = 46; // RRset Signature
- NS_T_NSEC = 47; // Negative security
- NS_T_DNSKEY = 48; // DNS Key
- NS_T_DHCID = 49; // Dynamic host configuratin identifier
- NS_T_NSEC3 = 50; // Negative security type 3
- NS_T_NSEC3PARAM = 51; // Negative security type 3 parameters
- NS_T_HIP = 55; // Host Identity Protocol
- NS_T_SPF = 99; // Sender Policy Framework
- NS_T_TKEY = 249; // Transaction key
- NS_T_TSIG = 250; // Transaction signature.
- NS_T_IXFR = 251; // Incremental zone transfer.
- NS_T_AXFR = 252; // Transfer zone of authority.
- NS_T_MAILB = 253; // Transfer mailbox records.
- NS_T_MAILA = 254; // Transfer mail agent records.
- NS_T_ANY = 255; // Wildcard match.
- NS_T_ZXFR = 256; // BIND-specific, nonstandard.
- NS_T_DLV = 32769; // DNSSEC look-aside validatation.
- NS_T_MAX = 65536;
-}
-
-enum IpVersion {
- IV_UNKNOWN = 0;
- IV_IPV4 = 1;
- IV_IPV6 = 2;
-}
-
-enum Protocol {
- PROTO_UNKNOWN = 0;
- PROTO_UDP = 1;
- PROTO_TCP = 2;
- PROTO_DOT = 3;
-}
-
-enum PrivateDnsModes {
- PDM_UNKNOWN = 0;
- PDM_OFF = 1;
- PDM_OPPORTUNISTIC = 2;
- PDM_STRICT = 3;
-}
-
-enum NetworkType {
- NT_UNKNOWN = 0;
- // Indicates this network uses a Cellular transport.
- NT_CELLULAR = 1;
- // Indicates this network uses a Wi-Fi transport.
- NT_WIFI = 2;
- // Indicates this network uses a Bluetooth transport.
- NT_BLUETOOTH = 3;
- // Indicates this network uses an Ethernet transport.
- NT_ETHERNET = 4;
- // Indicates this network uses a VPN transport, now deprecated.
- NT_VPN = 5 [deprecated=true];
- // Indicates this network uses a Wi-Fi Aware transport.
- NT_WIFI_AWARE = 6;
- // Indicates this network uses a LoWPAN transport.
- NT_LOWPAN = 7;
- // Indicates this network uses a Cellular+VPN transport.
- NT_CELLULAR_VPN = 8;
- // Indicates this network uses a Wi-Fi+VPN transport.
- NT_WIFI_VPN = 9;
- // Indicates this network uses a Bluetooth+VPN transport.
- NT_BLUETOOTH_VPN = 10;
- // Indicates this network uses an Ethernet+VPN transport.
- NT_ETHERNET_VPN = 11;
- // Indicates this network uses a Wi-Fi+Cellular+VPN transport.
- NT_WIFI_CELLULAR_VPN = 12;
-}
-
-enum CacheStatus{
- // the cache can't handle that kind of queries.
- // or the answer buffer is too small.
- CS_UNSUPPORTED = 0;
- // the cache doesn't know about this query.
- CS_NOTFOUND = 1;
- // the cache found the answer.
- CS_FOUND = 2;
- // Don't do anything on cache.
- CS_SKIP = 3;
-}
-
-// The enum LinuxErrno is defined in the following 2 files.
-// 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h
-// 2. bionic/libc/kernel/uapi/asm-generic/errno.h
-enum LinuxErrno {
- SYS_NO_ERROR = 0;
- SYS_EPERM = 1; // Not super-user
- SYS_ENOENT = 2; // No such file or directory
- SYS_ESRCH = 3; // No such process
- SYS_EINTR = 4; // Interrupted system call
- SYS_EIO = 5; // I/O error
- SYS_ENXIO = 6; // No such device or address
- SYS_E2BIG = 7; // Arg list too long
- SYS_ENOEXEC = 8; // Exec format error
- SYS_EBADF = 9; // Bad file number
- SYS_ECHILD = 10; // No children
- SYS_EAGAIN = 11; // No more processes
- SYS_ENOMEM = 12; // Not enough core
- SYS_EACCES = 13; // Permission denied
- SYS_EFAULT = 14; // Bad address
- SYS_ENOTBLK = 15; // Block device required
- SYS_EBUSY = 16; // Mount device busy
- SYS_EEXIST = 17; // File exists
- SYS_EXDEV = 18; // Cross-device link
- SYS_ENODEV = 19; // No such device
- SYS_ENOTDIR = 20; // Not a directory
- SYS_EISDIR = 21; // Is a directory
- SYS_EINVAL = 22; // Invalid argument
- SYS_ENFILE = 23; // Too many open files in system
- SYS_EMFILE = 24; // Too many open files
- SYS_ENOTTY = 25; // Not a typewriter
- SYS_ETXTBSY = 26; // Text file busy
- SYS_EFBIG = 27; // File too large
- SYS_ENOSPC = 28; // No space left on device
- SYS_ESPIPE = 29; // Illegal seek
- SYS_EROFS = 30; // Read only file system
- SYS_EMLINK = 31; // Too many links
- SYS_EPIPE = 32; // Broken pipe
- SYS_EDOM = 33; // Math arg out of domain of func
- SYS_ERANGE = 34; // Math result not representable
- SYS_EDEADLOCK = 35; // File locking deadlock error
- SYS_ENAMETOOLONG = 36; // File or path name too long
- SYS_ENOLCK = 37; // No record locks available
- SYS_ENOSYS = 38; // Function not implemented
- SYS_ENOTEMPTY = 39; // Directory not empty
- SYS_ELOOP = 40; // Too many symbolic links
- SYS_ENOMSG = 42; // No message of desired type
- SYS_EIDRM = 43; // Identifier removed
- SYS_ECHRNG = 44; // Channel number out of range
- SYS_EL2NSYNC = 45; // Level 2 not synchronized
- SYS_EL3HLT = 46; // Level 3 halted
- SYS_EL3RST = 47; // Level 3 reset
- SYS_ELNRNG = 48; // Link number out of range
- SYS_EUNATCH = 49; // rotocol driver not attached
- SYS_ENOCSI = 50; // No CSI structure available
- SYS_EL2HLT = 51; // Level 2 halted
- SYS_EBADE = 52; // Invalid exchange
- SYS_EBADR = 53; // Invalid request descriptor
- SYS_EXFULL = 54; // Exchange full
- SYS_ENOANO = 55; // No anode
- SYS_EBADRQC = 56; // Invalid request code
- SYS_EBADSLT = 57; // Invalid slot
- SYS_EBFONT = 59; // Bad font file fmt
- SYS_ENOSTR = 60; // Device not a stream
- SYS_ENODATA = 61; // No data (for no delay io)
- SYS_ETIME = 62; // Timer expired
- SYS_ENOSR = 63; // Out of streams resources
- SYS_ENONET = 64; // Machine is not on the network
- SYS_ENOPKG = 65; // Package not installed
- SYS_EREMOTE = 66; // The object is remote
- SYS_ENOLINK = 67; // The link has been severed
- SYS_EADV = 68; // Advertise error
- SYS_ESRMNT = 69; // Srmount error
- SYS_ECOMM = 70; // Communication error on send
- SYS_EPROTO = 71; // Protocol error
- SYS_EMULTIHOP = 72; // Multihop attempted
- SYS_EDOTDOT = 73; // Cross mount point (not really error)
- SYS_EBADMSG = 74; // Trying to read unreadable message
- SYS_EOVERFLOW = 75; // Value too large for defined data type
- SYS_ENOTUNIQ = 76; // Given log. name not unique
- SYS_EBADFD = 77; // f.d. invalid for this operation
- SYS_EREMCHG = 78; // Remote address changed
- SYS_ELIBACC = 79; // Can't access a needed shared lib
- SYS_ELIBBAD = 80; // Accessing a corrupted shared lib
- SYS_ELIBSCN = 81; // .lib section in a.out corrupted
- SYS_ELIBMAX = 82; // Attempting to link in too many libs
- SYS_ELIBEXEC = 83; // Attempting to exec a shared library
- SYS_EILSEQ = 84;
- SYS_ERESTART = 85;
- SYS_ESTRPIPE = 86;
- SYS_EUSERS = 87;
- SYS_ENOTSOCK = 88; // Socket operation on non-socket
- SYS_EDESTADDRREQ = 89; // Destination address required
- SYS_EMSGSIZE = 90; // Message too long
- SYS_EPROTOTYPE = 91; // Protocol wrong type for socket
- SYS_ENOPROTOOPT = 92; // Protocol not available
- SYS_EPROTONOSUPPORT = 93; // Unknown protocol
- SYS_ESOCKTNOSUPPORT = 94; // Socket type not supported
- SYS_EOPNOTSUPP = 95; // Operation not supported on transport endpoint
- SYS_EPFNOSUPPORT = 96; // Protocol family not supported
- SYS_EAFNOSUPPORT = 97; // Address family not supported by protocol family
- SYS_EADDRINUSE = 98; // Address already in use
- SYS_EADDRNOTAVAIL = 99; // Address not available
- SYS_ENETDOWN = 100; // Network interface is not configured
- SYS_ENETUNREACH = 101; // Network is unreachable
- SYS_ENETRESET = 102;
- SYS_ECONNABORTED = 103; // Connection aborted
- SYS_ECONNRESET = 104; // Connection reset by peer
- SYS_ENOBUFS = 105; // No buffer space available
- SYS_EISCONN = 106; // Socket is already connected
- SYS_ENOTCONN = 107; // Socket is not connected
- SYS_ESHUTDOWN = 108; // Can't send after socket shutdown
- SYS_ETOOMANYREFS = 109;
- SYS_ETIMEDOUT = 110; // Connection timed out
- SYS_ECONNREFUSED = 111; // Connection refused
- SYS_EHOSTDOWN = 112; // Host is down
- SYS_EHOSTUNREACH = 113; // Host is unreachable
- SYS_EALREADY = 114; // Socket already connected
- SYS_EINPROGRESS = 115; // Connection already in progress
- SYS_ESTALE = 116;
- SYS_EUCLEAN = 117;
- SYS_ENOTNAM = 118;
- SYS_ENAVAIL = 119;
- SYS_EISNAM = 120;
- SYS_EREMOTEIO = 121;
- SYS_EDQUOT = 122;
- SYS_ENOMEDIUM = 123; // No medium (in tape drive)
- SYS_EMEDIUMTYPE = 124;
- SYS_ECANCELED = 125;
- SYS_ENOKEY = 126;
- SYS_EKEYEXPIRED = 127;
- SYS_EKEYREVOKED = 128;
- SYS_EKEYREJECTED = 129;
- SYS_EOWNERDEAD = 130;
- SYS_ENOTRECOVERABLE = 131;
- SYS_ERFKILL = 132;
- SYS_EHWPOISON = 133;
-}
-
-message DnsQueryEvent {
- optional android.stats.dnsresolver.NsRcode rcode = 1;
-
- optional android.stats.dnsresolver.NsType type = 2;
-
- optional android.stats.dnsresolver.CacheStatus cache_hit = 3;
-
- optional android.stats.dnsresolver.IpVersion ip_version = 4;
-
- optional android.stats.dnsresolver.Protocol protocol = 5;
-
- // Number of DNS query retry times
- optional int32 retry_times = 6;
-
- // Ordinal number of name server.
- optional int32 dns_server_index = 7;
-
- // Used only by TCP and DOT. True for new connections.
- optional bool connected = 8;
-
- optional int32 latency_micros = 9;
-
- optional android.stats.dnsresolver.LinuxErrno linux_errno = 10;
-}
-
-message DnsQueryEvents {
- repeated DnsQueryEvent dns_query_event = 1;
-}
diff --git a/core/proto/android/stats/docsui/docsui_enums.proto b/core/proto/android/stats/docsui/docsui_enums.proto
deleted file mode 100644
index 5963f6a7f938..000000000000
--- a/core/proto/android/stats/docsui/docsui_enums.proto
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.docsui;
-option java_multiple_files = true;
-
-enum LaunchAction {
- UNKNOWN = 0;
- OPEN = 1;
- CREATE = 2;
- GET_CONTENT = 3;
- OPEN_TREE = 4;
- PICK_COPY_DEST = 5;
- BROWSE = 6;
- OTHER = 7;
-}
-
-enum MimeType {
- MIME_UNKNOWN = 0;
- MIME_NONE = 1;
- MIME_ANY = 2;
- MIME_APPLICATION = 3;
- MIME_AUDIO = 4;
- MIME_IMAGE = 5;
- MIME_MESSAGE = 6;
- MIME_MULTIPART = 7;
- MIME_TEXT = 8;
- MIME_VIDEO = 9;
- MIME_OTHER = 10;
-}
-
-enum Root {
- ROOT_UNKNOWN = 0;
- ROOT_NONE = 1;
- ROOT_OTHER_DOCS_PROVIDER = 2;
- ROOT_AUDIO = 3;
- ROOT_DEVICE_STORAGE = 4;
- ROOT_DOWNLOADS = 5;
- ROOT_HOME = 6;
- ROOT_IMAGES = 7;
- ROOT_RECENTS = 8;
- ROOT_VIDEOS = 9;
- ROOT_MTP = 10;
- ROOT_THIRD_PARTY_APP = 11;
- ROOT_DOCUMENTS = 12;
-}
-
-enum ContextScope {
- SCOPE_UNKNOWN = 0;
- SCOPE_FILES = 1;
- SCOPE_PICKER = 2;
-}
-
-enum Provider {
- PROVIDER_UNKNOWN = 0;
- PROVIDER_SYSTEM = 1;
- PROVIDER_EXTERNAL = 2;
-}
-
-enum FileOperation {
- OP_UNKNOWN = 0;
- OP_OTHER = 1;
- OP_COPY = 2;
- OP_COPY_INTRA_PROVIDER = 3;
- OP_COPY_SYSTEM_PROVIDER = 4;
- OP_COPY_EXTERNAL_PROVIDER = 5;
- OP_MOVE = 6;
- OP_MOVE_INTRA_PROVIDER = 7;
- OP_MOVE_SYSTEM_PROVIDER = 8;
- OP_MOVE_EXTERNAL_PROVIDER = 9;
- OP_DELETE = 10;
- OP_RENAME = 11;
- OP_CREATE_DIR = 12;
- OP_OTHER_ERROR = 13;
- OP_DELETE_ERROR = 14;
- OP_MOVE_ERROR = 15;
- OP_COPY_ERROR = 16;
- OP_RENAME_ERROR = 17;
- OP_CREATE_DIR_ERROR = 18;
- OP_COMPRESS_INTRA_PROVIDER = 19;
- OP_COMPRESS_SYSTEM_PROVIDER = 20;
- OP_COMPRESS_EXTERNAL_PROVIDER = 21;
- OP_EXTRACT_INTRA_PROVIDER = 22;
- OP_EXTRACT_SYSTEM_PROVIDER = 23;
- OP_EXTRACT_EXTERNAL_PROVIDER = 24;
- OP_COMPRESS_ERROR = 25;
- OP_EXTRACT_ERROR = 26;
-}
-
-enum SubFileOperation {
- SUB_OP_UNKNOWN = 0;
- SUB_OP_QUERY_DOC = 1;
- SUB_OP_QUERY_CHILD = 2;
- SUB_OP_OPEN_FILE = 3;
- SUB_OP_READ_FILE = 4;
- SUB_OP_CREATE_DOC = 5;
- SUB_OP_WRITE_FILE = 6;
- SUB_OP_DELETE_DOC = 7;
- SUB_OP_OBTAIN_STREAM_TYPE = 8;
- SUB_OP_QUICK_MOVE = 9;
- SUB_OP_QUICK_COPY = 10;
-}
-
-enum CopyMoveOpMode {
- MODE_UNKNOWN = 0;
- MODE_PROVIDER = 1;
- MODE_CONVERTED = 2;
- MODE_CONVENTIONAL = 3;
-}
-
-enum Authority {
- AUTH_UNKNOWN = 0;
- AUTH_OTHER = 1;
- AUTH_MEDIA = 2;
- AUTH_STORAGE_INTERNAL = 3;
- AUTH_STORAGE_EXTERNAL = 4;
- AUTH_DOWNLOADS = 5;
- AUTH_MTP = 6;
-}
-
-enum UserAction {
- ACTION_UNKNOWN = 0;
- ACTION_OTHER = 1;
- ACTION_GRID = 2;
- ACTION_LIST = 3;
- ACTION_SORT_NAME = 4;
- ACTION_SORT_DATE = 5;
- ACTION_SORT_SIZE = 6;
- ACTION_SORT_TYPE = 7;
- ACTION_SEARCH = 8;
- ACTION_SHOW_SIZE = 9;
- ACTION_HIDE_SIZE = 10;
- ACTION_SETTINGS = 11;
- ACTION_COPY_TO = 12;
- ACTION_MOVE_TO = 13;
- ACTION_DELETE = 14;
- ACTION_RENAME = 15;
- ACTION_CREATE_DIR = 16;
- ACTION_SELECT_ALL = 17;
- ACTION_SHARE = 18;
- ACTION_OPEN = 19;
- ACTION_SHOW_ADVANCED = 20;
- ACTION_HIDE_ADVANCED = 21;
- ACTION_NEW_WINDOW = 22;
- ACTION_PASTE_CLIPBOARD = 23;
- ACTION_COPY_CLIPBOARD = 24;
- ACTION_DRAG_N_DROP = 25;
- ACTION_DRAG_N_DROP_MULTI_WINDOW = 26;
- ACTION_CUT_CLIPBOARD = 27;
- ACTION_COMPRESS = 28;
- ACTION_EXTRACT_TO = 29;
- ACTION_VIEW_IN_APPLICATION = 30;
- ACTION_INSPECTOR = 31;
- ACTION_SEARCH_CHIP = 32;
- ACTION_SEARCH_HISTORY = 33;
-}
-
-enum InvalidScopedAccess {
- SCOPED_DIR_ACCESS_UNKNOWN = 0;
- SCOPED_DIR_ACCESS_INVALID_ARGUMENTS = 1;
- SCOPED_DIR_ACCESS_INVALID_DIRECTORY = 2;
- SCOPED_DIR_ACCESS_ERROR = 3;
- SCOPED_DIR_ACCESS_DEPRECATED = 4;
-}
-
-enum SearchType {
- TYPE_UNKNOWN = 0;
- TYPE_CHIP_IMAGES = 1;
- TYPE_CHIP_AUDIOS = 2;
- TYPE_CHIP_VIDEOS = 3;
- TYPE_CHIP_DOCS = 4;
- TYPE_SEARCH_HISTORY = 5;
- TYPE_SEARCH_STRING = 6;
- TYPE_CHIP_LARGE_FILES = 7;
- TYPE_CHIP_FROM_THIS_WEEK = 8;
-}
-
-enum SearchMode {
- SEARCH_UNKNOWN = 0;
- SEARCH_KEYWORD = 1;
- SEARCH_CHIPS = 2;
- SEARCH_KEYWORD_N_CHIPS = 3;
-}
diff --git a/core/proto/android/stats/enums.proto b/core/proto/android/stats/enums.proto
deleted file mode 100644
index 8f8055ed2451..000000000000
--- a/core/proto/android/stats/enums.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats;
-option java_outer_classname = "StatsEnums";
-
-enum EventType {
- // Unknown.
- TYPE_UNKNOWN = 0;
- CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_SUCCEEDED = 1;
- CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_FAILED = 2;
- CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_SUCCEEDED = 3;
- CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_FAILED = 4;
-}
diff --git a/core/proto/android/stats/intelligence/enums.proto b/core/proto/android/stats/intelligence/enums.proto
deleted file mode 100644
index 0c210e3fd08f..000000000000
--- a/core/proto/android/stats/intelligence/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.intelligence;
-option java_outer_classname = "IntelligenceStatsEnums";
-
-enum Status {
- // The value wasn't set.
- // protoc requires enum values to be unique by package rather than enum type.
- // This forces us to prefix the enum values.
- STATUS_UNKNOWN = 0;
- // The event succeeded.
- STATUS_SUCCEEDED = 1;
- // The event had an error.
- STATUS_FAILED = 2;
-}
-
-enum EventType {
- // The value wasn't set.
- EVENT_UNKNOWN = 0;
- // ContentSuggestionsService classifyContentSelections call.
- EVENT_CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL = 1;
- // ContentSuggestionsService suggestContentSelections call.
- EVENT_CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL = 2;
-}
diff --git a/core/proto/android/stats/launcher/Android.bp b/core/proto/android/stats/launcher/Android.bp
deleted file mode 100644
index 976a0b8634a3..000000000000
--- a/core/proto/android/stats/launcher/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "launcherprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
-
-java_library {
- name: "launcherprotoslite",
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto
deleted file mode 100644
index fc177d57b193..000000000000
--- a/core/proto/android/stats/launcher/launcher.proto
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.launcher;
-option java_multiple_files = true;
-
-enum LauncherAction {
- DEFAULT_ACTION = 0;
- LAUNCH_APP = 1;
- LAUNCH_TASK = 2;
- DISMISS_TASK = 3;
- LONGPRESS = 4;
- DRAGDROP = 5;
- SWIPE_UP = 6;
- SWIPE_DOWN = 7;
- SWIPE_LEFT = 8;
- SWIPE_RIGHT = 9;
-}
-
-enum LauncherState {
- LAUNCHER_STATE_UNSPECIFIED = 0;
- BACKGROUND = 1;
- HOME = 2;
- OVERVIEW = 3;
- ALLAPPS = 4;
- UNCHANGED = 5;
-}
-
-message LauncherTarget {
- enum Type {
- NONE = 0;
- ITEM_TYPE = 1;
- CONTROL_TYPE = 2;
- CONTAINER_TYPE = 3;
- }
- enum Item {
- DEFAULT_ITEM = 0;
- APP_ICON = 1;
- SHORTCUT = 2;
- WIDGET = 3;
- FOLDER_ICON = 4;
- DEEPSHORTCUT = 5;
- SEARCHBOX = 6;
- EDITTEXT = 7;
- NOTIFICATION = 8;
- TASK = 9;
- }
- enum Container {
- DEFAULT_CONTAINER = 0;
- HOTSEAT = 1;
- FOLDER = 2;
- PREDICTION = 3;
- SEARCHRESULT = 4;
- }
- enum Control {
- DEFAULT_CONTROL = 0;
- MENU = 1;
- UNINSTALL = 2;
- REMOVE = 3;
- }
- optional Type type = 1;
- optional Item item = 2;
- optional Container container = 3;
- optional Control control = 4;
- optional string launch_component = 5;
- optional int32 page_id = 6;
- optional int32 grid_x = 7;
- optional int32 grid_y = 8;
-}
-
-message LauncherExtension {
- repeated LauncherTarget src_target = 1;
- repeated LauncherTarget dst_target = 2;
-}
diff --git a/core/proto/android/stats/location/location_enums.proto b/core/proto/android/stats/location/location_enums.proto
deleted file mode 100644
index 553c01c5d0dd..000000000000
--- a/core/proto/android/stats/location/location_enums.proto
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.location;
-option java_outer_classname = "LocationStatsEnums";
-
-
-// APIs from LocationManagerService
-enum LocationManagerServiceApi {
- API_UNKNOWN = 0;
- API_REQUEST_LOCATION_UPDATES = 1;
- API_ADD_GNSS_MEASUREMENTS_LISTENER = 2;
- API_REGISTER_GNSS_STATUS_CALLBACK = 3;
- API_REQUEST_GEOFENCE = 4;
- API_SEND_EXTRA_COMMAND = 5;
-}
-
-enum UsageState {
- USAGE_STARTED = 0;
- USAGE_ENDED = 1;
-}
-
-// Type of location providers
-enum ProviderType {
- PROVIDER_UNKNOWN = 0;
- PROVIDER_NETWORK = 1;
- PROVIDER_GPS = 2;
- PROVIDER_PASSIVE = 3;
- PROVIDER_FUSED = 4;
-}
-
-// Type of Callback passed in for this API
-enum CallbackType {
- CALLBACK_UNKNOWN = 0;
- // Current API does not need a callback, e.g. sendExtraCommand
- CALLBACK_NOT_APPLICABLE = 1;
- CALLBACK_LISTENER = 2;
- CALLBACK_PENDING_INTENT = 3;
-}
-
-// Possible values for mQuality field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum LocationRequestQuality {
- QUALITY_UNKNOWN = 0;
- ACCURACY_FINE = 100;
- ACCURACY_BLOCK = 102;
- ACCURACY_CITY = 104;
- POWER_NONE = 200;
- POWER_LOW = 201;
- POWER_HIGH = 203;
-}
-
-// Bucketized values for interval field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum LocationRequestIntervalBucket {
- INTERVAL_UNKNOWN = 0;
- INTERVAL_BETWEEN_0_SEC_AND_1_SEC = 1;
- INTERVAL_BETWEEN_1_SEC_AND_5_SEC = 2;
- INTERVAL_BETWEEN_5_SEC_AND_1_MIN = 3;
- INTERVAL_BETWEEN_1_MIN_AND_10_MIN = 4;
- INTERVAL_BETWEEN_10_MIN_AND_1_HOUR = 5;
- INTERVAL_LARGER_THAN_1_HOUR = 6;
-}
-
-// Bucketized values for small displacement field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-// Value in meters.
-enum SmallestDisplacementBucket {
- DISTANCE_UNKNOWN = 0;
- DISTANCE_ZERO = 1;
- DISTANCE_BETWEEN_0_AND_100 = 2;
- DISTANCE_LARGER_THAN_100 = 3;
-}
-
-// Bucketized values for expire_in field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum ExpirationBucket {
- EXPIRATION_UNKNOWN = 0;
- EXPIRATION_BETWEEN_0_AND_20_SEC = 1;
- EXPIRATION_BETWEEN_20_SEC_AND_1_MIN = 2;
- EXPIRATION_BETWEEN_1_MIN_AND_10_MIN = 3;
- EXPIRATION_BETWEEN_10_MIN_AND_1_HOUR = 4;
- EXPIRATION_LARGER_THAN_1_HOUR = 5;
- EXPIRATION_NO_EXPIRY = 6;
-}
-
-// Bucketized values for radius field in
-// frameworks/base/location/java/android/location/Geofence.java
-// Value in meters.
-enum GeofenceRadiusBucket {
- RADIUS_UNKNOWN = 0;
- RADIUS_BETWEEN_0_AND_100 = 1;
- RADIUS_BETWEEN_100_AND_200 = 2;
- RADIUS_BETWEEN_200_AND_300 = 3;
- RADIUS_BETWEEN_300_AND_1000 = 4;
- RADIUS_BETWEEN_1000_AND_10000 = 5;
- RADIUS_LARGER_THAN_100000 = 6;
- RADIUS_NEGATIVE = 7;
-}
-
-// Caller Activity Importance.
-enum ActivityImportance {
- IMPORTANCE_UNKNOWN = 0;
- IMPORTANCE_TOP = 1;
- IMPORTANCE_FORGROUND_SERVICE = 2;
- IMPORTANCE_BACKGROUND = 3;
-}
diff --git a/core/proto/android/stats/mediametrics/mediametrics.proto b/core/proto/android/stats/mediametrics/mediametrics.proto
deleted file mode 100644
index 9f0ff591a506..000000000000
--- a/core/proto/android/stats/mediametrics/mediametrics.proto
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.mediametrics;
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp
- * Next Tag: 10
- */
-message AudioPolicyData {
- optional int32 status = 1;
- optional string request_source = 2;
- optional string request_package = 3;
- optional int32 request_session = 4;
- optional string request_device = 5;
- optional string active_source = 6;
- optional string active_package = 7;
- optional int32 active_session = 8;
- optional string active_device = 9;
-}
-
-/**
- * Track properties of audio recording
- * Logged from
- * frameworks/av/media/libaudioclient/AudioRecord.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp
- * Next Tag: 16
- */
-message AudioRecordData {
- optional string encoding = 1;
- optional string source = 2;
- optional int32 latency = 3;
- optional int32 samplerate = 4;
- optional int32 channels = 5;
- optional int64 created_millis = 6;
- optional int64 duration_millis = 7;
- optional int32 count = 8;
- optional int32 error_code = 9;
- optional string error_function = 10;
- optional int32 port_id = 11;
- optional int32 frame_count = 12;
- optional string attributes = 13;
- optional int64 channel_mask = 14;
- optional int64 start_count = 15;
-
-}
-
-/**
- * Track audio thread performance data
- * Logged from
- * frameworks/av/media/libnblog/ReportPerformance.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp
- * Next Tag: 28
- */
-message AudioThreadData {
- optional string type = 1;
- optional int32 framecount = 2;
- optional int32 samplerate = 3;
- optional string work_millis_hist = 4;
- optional string latency_millis_hist = 5;
- optional string warmup_millis_hist = 6;
- optional int64 underruns = 7;
- optional int64 overruns = 8;
- optional int64 active_millis = 9;
- optional int64 duration_millis = 10;
-
- optional int32 id = 11;
- optional int32 port_id = 12;
- optional int32 sample_rate = 13;
- optional int64 channel_mask = 14;
- optional string encoding = 15;
- optional int32 frame_count = 16;
- optional string output_device = 17;
- optional string input_device = 18;
- optional double io_jitter_mean_millis = 19;
- optional double io_jitter_stddev_millis = 20;
- optional double process_time_mean_millis = 21;
- optional double process_time_stddev_millis = 22;
- optional double timestamp_jitter_mean_millis = 23;
- optional double timestamp_jitter_stddev_millis = 24;
- optional double latency_mean_millis = 25;
- optional double latency_stddev_millis = 26;
-
-}
-
-/**
- * Track audio track playback data
- * Logged from
- * frameworks/av/media/libaudioclient/AudioTrack.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp
- * Next Tag: 12
- */
-message AudioTrackData {
- optional string stream_type = 1;
- optional string content_type = 2;
- optional string track_usage = 3;
- optional int32 sample_rate = 4;
- optional int64 channel_mask = 5;
-
- optional int32 underrun_frames = 6;
- optional int32 startup_glitch = 7;
-
- optional int32 port_id = 8;
- optional string encoding = 9;
- optional int32 frame_count = 10;
- optional string attributes = 11;
-
-
-}
-
-/**
- * Track Media Codec usage
- * Logged from:
- * frameworks/av/media/libstagefright/MediaCodec.cpp
- * frameworks/av/services/mediaanalytics/statsd_codec.cpp
- * Next Tag: 26
- */
-message CodecData {
- optional string codec = 1;
- optional string mime = 2;
- optional string mode = 3;
- optional int32 encoder = 4;
- optional int32 secure = 5;
- optional int32 width = 6;
- optional int32 height = 7;
- optional int32 rotation = 8;
- optional int32 crypto = 9;
- optional int32 profile = 10;
- optional int32 level = 11;
- optional int32 max_width = 12;
- optional int32 max_height = 13;
- optional int32 error_code = 14;
- optional string error_state = 15;
- optional int64 latency_max = 16;
- optional int64 latency_min = 17;
- optional int64 latency_avg = 18;
- optional int64 latency_count = 19;
- optional int64 latency_unknown = 20;
- optional int32 queue_input_buffer_error = 21;
- optional int32 queue_secure_input_buffer_error = 22;
- optional string bitrate_mode = 23;
- optional int32 bitrate = 24;
- optional int64 lifetime_millis = 25;
-}
-
-/**
- * Track Media Extractor (pulling video/audio streams out of containers) usage
- * Logged from:
- * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp
- * frameworks/av/services/mediaanalytics/statsd_extractor.cpp
- * Next Tag: 4
- */
-message ExtractorData {
- optional string format = 1;
- optional string mime = 2;
- optional int32 tracks = 3;
-}
-
-/**
- * Track Media Player usage
- * this handles both nuplayer and nuplayer2
- * Logged from:
- * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
- * frameworks/av/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
- * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp
- * Next Tag: 21
- */
-message NuPlayerData {
- optional string whichPlayer = 1;
-
- optional string video_mime = 2;
- optional string video_codec = 3;
- optional int32 width = 4;
- optional int32 height = 5;
- optional int64 frames = 6;
- optional int64 frames_dropped = 7;
- optional double framerate = 8;
- optional string audio_mime = 9;
- optional string audio_codec = 10;
- optional int64 duration_millis = 11;
- optional int64 playing_millis = 12;
- optional int32 error = 13;
- optional int32 error_code = 14;
- optional string error_state = 15;
- optional string data_source_type = 16;
- optional int64 rebuffering_millis = 17;
- optional int32 rebuffers = 18;
- optional int32 rebuffer_at_exit = 19;
- optional int64 frames_dropped_startup = 20;
-}
-
-/**
- * Track information about recordings (e.g. camcorder)
- * Logged from
- * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp
- * frameworks/av/services/mediaanalytics/if_statsd.cpp
- * Next Tag: 22
- */
-message RecorderData {
- optional string audio_mime = 1;
- optional string video_mime = 2;
- optional int32 video_profile = 3;
- optional int32 video_level = 4;
- optional int32 width = 5;
- optional int32 height = 6;
- optional int32 rotation = 7;
- optional int32 framerate = 8;
- optional int32 capture_fps = 9;
- optional double capture_fps_enable = 10;
- optional int64 duration_millis = 11;
- optional int64 paused_millis = 12;
- optional int32 paused_count = 13;
- optional int32 audio_bitrate = 14;
- optional int32 audio_channels = 15;
- optional int32 audio_samplerate = 16;
- optional int32 movie_timescale = 17;
- optional int32 audio_timescale = 18;
- optional int32 video_timescale = 19;
- optional int32 video_bitrate = 20;
- optional int32 iframe_interval = 21;
-}
diff --git a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto b/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
deleted file mode 100644
index 138782bf5d19..000000000000
--- a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.mediaprovider;
-option java_multiple_files = true;
-
-enum VolumeType {
- // Volume is unknown
- UNKNOWN = 0;
- // Volume is MediaStore.VOLUME_INTERNAL
- INTERNAL = 1;
- // Volume is MediaStore.VOLUME_EXTERNAL_PRIMARY
- EXTERNAL_PRIMARY = 2;
- // Volume is non-primary external storage
- EXTERNAL_OTHER = 3;
-}
diff --git a/core/proto/android/stats/otaupdate/updateengine_enums.proto b/core/proto/android/stats/otaupdate/updateengine_enums.proto
deleted file mode 100644
index a6e9919ba606..000000000000
--- a/core/proto/android/stats/otaupdate/updateengine_enums.proto
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.otaupdate;
-
-// The payload type of an OTA update attempt on A/B devices.
-enum PayloadType {
- FULL = 10000;
- DELTA = 10001;
-}
-
-// The attempt result reported by the update engine for an OTA update.
-enum AttemptResult {
- UPDATE_SUCCEEDED = 10000;
- INTERNAL_ERROR = 10001;
- PAYLOAD_DOWNLOAD_ERROR = 10002;
- METADATA_MALFORMED = 10003;
- OPERATION_MALFORMED = 10004;
- OPERATION_EXECUTION_ERROR = 10005;
- METADATA_VERIFICATION_FAILED = 10006;
- PAYLOAD_VERIFICATION_FAILED = 10007;
- VERIFICATION_FAILED = 10008;
- POSTINSTALL_FAILED = 10009;
- ABNORMAL_TERMINATION = 10010;
- UPDATE_CANCELED = 10011;
- UPDATE_SUCCEEDED_NOT_ACTIVE = 10012;
-}
-
-// The error code reported by the update engine after an OTA update attempt
-// on A/B devices. More details in system/update_engine/common/error_code.h
-enum ErrorCode {
- SUCCESS = 10000;
- ERROR = 10001;
- FILESYSTEM_COPIER_ERROR = 10004;
- POST_INSTALL_RUNNER_ERROR = 10005;
- PAYLOAD_MISMATCHED_TYPE_ERROR = 10006;
- INSTALL_DEVICE_OPEN_ERROR = 10007;
- KERNEL_DEVICE_OPEN_ERROR = 10008;
- DOWNLOAD_TRANSFER_ERROR = 10009;
- PAYLOAD_HASH_MISMATCH_ERROR = 10010;
- PAYLOAD_SIZE_MISMATCH_ERROR = 10011;
- DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 10012;
- DOWNLOAD_NEW_PARTITION_INFO_ERROR = 10013;
- DOWNLOAD_WRITE_ERROR = 10014;
- NEW_ROOTFS_VERIFICATION_ERROR = 10015;
- SIGNED_DELTA_PAYLOAD_EXPECTED_ERROR = 10017;
- DOWNLOAD_PAYLOAD_PUB_KEY_VERIFICATION_ERROR = 10018;
- DOWNLOAD_STATE_INITIALIZATION_ERROR = 10020;
- DOWNLOAD_INVALID_METADATA_MAGIC_STRING = 10021;
- DOWNLOAD_SIGNATURE_MISSING_IN_MANIFEST = 10022;
- DOWNLOAD_MANIFEST_PARSE_ERROR = 10023;
- DOWNLOAD_METADATA_SIGNATURE_ERROR = 10024;
- DOWNLOAD_METADATA_SIGNATURE_VERIFICATION_ERROR = 10025;
- DOWNLOAD_METADATA_SIGNATURE_MISMATCH = 10026;
- DOWNLOAD_OPERATION_HASH_VERIFICATION_ERROR = 10027;
- DOWNLOAD_OPERATION_EXECUTION_ERROR = 10028;
- DOWNLOAD_OPERATION_HASH_MISMATCH = 10029;
- DOWNLOAD_INVALID_METADATA_SIZE = 10032;
- DOWNLOAD_INVALID_METADATA_SIGNATURE = 10033;
- DOWNLOAD_OPERATION_HASH_MISSING_ERROR = 10038;
- DOWNLOAD_METADATA_SIGNATURE_MISSING_ERROR = 10039;
- UNSUPPORTED_MAJOR_PAYLOAD_VERSION = 10044;
- UNSUPPORTED_MINOR_PAYLOAD_VERSION = 10045;
- FILESYSTEM_VERIFIER_ERROR = 10047;
- USER_CANCELED = 10048;
- PAYLOAD_TIMESTAMP_ERROR = 10051;
- UPDATED_BUT_NOT_ACTIVE = 10052;
-}
diff --git a/core/proto/android/stats/storage/storage_enums.proto b/core/proto/android/stats/storage/storage_enums.proto
deleted file mode 100644
index 6892e287472f..000000000000
--- a/core/proto/android/stats/storage/storage_enums.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.storage;
-
-enum ExternalStorageType {
- UNKNOWN = 0;
- SD_CARD = 1;
- USB = 2;
- OTHER = 3;
-}
diff --git a/core/proto/android/stats/style/Android.bp b/core/proto/android/stats/style/Android.bp
deleted file mode 100644
index f085a52f8cdb..000000000000
--- a/core/proto/android/stats/style/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "styleprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
diff --git a/core/proto/android/stats/style/style_enums.proto b/core/proto/android/stats/style/style_enums.proto
deleted file mode 100644
index f3f491ff34cd..000000000000
--- a/core/proto/android/stats/style/style_enums.proto
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.style;
-option java_multiple_files = true;
-
-enum Action {
- DEFAULT_ACTION = 0;
- ONRESUME = 1;
- ONSTOP = 2;
- PICKER_SELECT = 3;
- PICKER_APPLIED = 4;
- WALLPAPER_OPEN_CATEGORY = 5;
- WALLPAPER_SELECT = 6;
- WALLPAPER_APPLIED = 7;
- WALLPAPER_EXPLORE = 8;
- WALLPAPER_DOWNLOAD = 9;
- WALLPAPER_REMOVE = 10;
- LIVE_WALLPAPER_DOWNLOAD_SUCCESS = 11;
- LIVE_WALLPAPER_DOWNLOAD_FAILED = 12;
- LIVE_WALLPAPER_DOWNLOAD_CANCELLED = 13;
- LIVE_WALLPAPER_DELETE_SUCCESS = 14;
- LIVE_WALLPAPER_DELETE_FAILED = 15;
- LIVE_WALLPAPER_APPLIED = 16;
- LIVE_WALLPAPER_INFO_SELECT = 17;
- LIVE_WALLPAPER_CUSTOMIZE_SELECT = 18;
-}
-
-enum LocationPreference {
- LOCATION_PREFERENCE_UNSPECIFIED = 0;
- LOCATION_UNAVAILABLE = 1;
- LOCATION_CURRENT = 2;
- LOCATION_MANUAL = 3;
-}
diff --git a/core/proto/android/stats/sysui/notification_enums.proto b/core/proto/android/stats/sysui/notification_enums.proto
deleted file mode 100644
index 30bdecae07d1..000000000000
--- a/core/proto/android/stats/sysui/notification_enums.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.sysui;
-
-// Enum used in NotificationReported and NotificationChannelModified atoms
-enum NotificationImportance { // Constants from NotificationManager.java
- IMPORTANCE_UNSPECIFIED = -1000; // Should not occur for real notifications.
- IMPORTANCE_NONE = 0; // No importance: does not show in the shade.
- IMPORTANCE_MIN = 1; // Minimum to show in the shade.
- IMPORTANCE_LOW = 2; // Shows in shade, maybe status bar, no buzz/beep.
- IMPORTANCE_DEFAULT = 3; // Shows everywhere, makes noise, no heads-up.
- IMPORTANCE_HIGH = 4; // Shows everywhere, makes noise, heads-up, may full-screen.
- IMPORTANCE_IMPORTANT_CONVERSATION = 5; // High + isImportantConversation().
-}
diff --git a/core/proto/android/stats/textclassifier/Android.bp b/core/proto/android/stats/textclassifier/Android.bp
deleted file mode 100644
index bf9022711206..000000000000
--- a/core/proto/android/stats/textclassifier/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "textclassifierprotoslite",
- proto: {
- type: "lite",
- },
- srcs: [
- "*.proto",
- ],
-} \ No newline at end of file
diff --git a/core/proto/android/stats/textclassifier/textclassifier_enums.proto b/core/proto/android/stats/textclassifier/textclassifier_enums.proto
deleted file mode 100644
index 4be7b7c2df7c..000000000000
--- a/core/proto/android/stats/textclassifier/textclassifier_enums.proto
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.textclassifier;
-option java_multiple_files = true;
-
-enum EventType {
- TYPE_UNKNOWN = 0;
- // User started a new selection.
- SELECTION_STARTED = 1;
- // User modified an existing selection.
- SELECTION_MODIFIED = 2;
- // Smart selection triggered for a single token (word).
- SMART_SELECTION_SINGLE = 3;
- // Smart selection triggered spanning multiple tokens (words).
- SMART_SELECTION_MULTI = 4;
- // Something else other than user or the default TextClassifier triggered a selection.
- AUTO_SELECTION = 5;
- // Smart actions shown to the user.
- ACTIONS_SHOWN = 6;
- // User clicked a link.
- LINK_CLICKED = 7;
- // User typed over the selection.
- OVERTYPE = 8;
- // User clicked on Copy action.
- COPY_ACTION = 9;
- // User clicked on Paste action.
- PASTE_ACTION = 10;
- // User clicked on Cut action.
- CUT_ACTION = 11;
- // User clicked on Share action.
- SHARE_ACTION = 12;
- // User clicked on a Smart action.
- SMART_ACTION = 13;
- // User dragged+dropped the selection.
- SELECTION_DRAG = 14;
- // Selection is destroyed.
- SELECTION_DESTROYED = 15;
- // User clicked on a custom action.
- OTHER_ACTION = 16;
- // User clicked on Select All action
- SELECT_ALL = 17;
- // User reset the smart selection.
- SELECTION_RESET = 18;
- // User composed a reply.
- MANUAL_REPLY = 19;
- // TextClassifier generated some actions
- ACTIONS_GENERATED = 20;
- // Some text links were generated
- LINKS_GENERATED = 21;
-}
-
-enum WidgetType {
- WIDGET_TYPE_UNKNOWN = 0;
- // Standard TextView
- WIDGET_TYPE_TEXTVIEW = 1;
- // EditText
- WIDGET_TYPE_EDITTEXT = 2;
- // Not selectable textview
- WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = 3;
- // Standard Webview
- WIDGET_TYPE_WEBVIEW = 4;
- // Editable TextView
- WIDGET_TYPE_EDIT_WEBVIEW = 5;
- // Custom text widget
- WIDGET_TYPE_CUSTOM_TEXTVIEW = 6;
- // Custom editable text widget.
- WIDGET_TYPE_CUSTOM_EDITTEXT = 7;
- // Non-selectable text widget.
- WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = 8;
- // Notification
- WIDGET_TYPE_NOTIFICATION = 9;
-}
diff --git a/core/proto/android/telecomm/enums.proto b/core/proto/android/telecomm/enums.proto
deleted file mode 100644
index 5ca4a85f7c6a..000000000000
--- a/core/proto/android/telecomm/enums.proto
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.telecom;
-
-option java_outer_classname = "TelecomProtoEnums";
-option java_multiple_files = true;
-
-/**
- * Call states, primarily used in CallState.java,
- * Call.java, and CallsManager.java in packages/services.
- */
-enum CallStateEnum {
- /**
- * Indicates that a call is new and not connected. This is used as the default state internally
- * within Telecom and should not be used between Telecom and call services. Call services are
- * not expected to ever interact with NEW calls, but {@link android.telecom.InCallService}s will
- * see calls in this state.
- */
- NEW = 0;
-
- /**
- * The initial state of an outgoing {@code Call}.
- * Common transitions are to {@link #DIALING} state for a successful call or
- * {@link #DISCONNECTED} if it failed.
- */
- CONNECTING = 1;
-
- /**
- * The state of an outgoing {@code Call} when waiting on user to select a
- * {@link android.telecom.PhoneAccount} through which to place the call.
- */
- SELECT_PHONE_ACCOUNT = 2;
-
- /**
- * Indicates that a call is outgoing and in the dialing state. A call transitions to this state
- * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this
- * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED}
- * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user).
- */
- DIALING = 3;
-
- /**
- * Indicates that a call is incoming and the user still has the option of answering, rejecting,
- * or doing nothing with the call. This state is usually associated with some type of audible
- * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED}
- * otherwise.
- */
- RINGING = 4;
-
- /**
- * Indicates that a call is currently connected to another party and a communication channel is
- * open between them. The normal transition to this state is by the user answering a
- * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party.
- */
- ACTIVE = 5;
-
- /**
- * Indicates that the call is currently on hold. In this state, the call is not terminated
- * but no communication is allowed until the call is no longer on hold. The typical transition
- * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing
- * an action, such as clicking the hold button.
- */
- ON_HOLD = 6;
-
- /**
- * Indicates that a call is currently disconnected. All states can transition to this state
- * by the call service giving notice that the connection has been severed. When the user
- * explicitly ends a call, it will not transition to this state until the call service confirms
- * the disconnection or communication was lost to the call service currently responsible for
- * this call (e.g., call service crashes).
- */
- DISCONNECTED = 7;
-
- /**
- * Indicates that the call was attempted (mostly in the context of outgoing, at least at the
- * time of writing) but cancelled before it was successfully connected.
- */
- ABORTED = 8;
-
- /**
- * Indicates that the call is in the process of being disconnected and will transition next
- * to a {@link #DISCONNECTED} state.
- * <p>
- * This state is not expected to be communicated from the Telephony layer, but will be reported
- * to the InCall UI for calls where disconnection has been initiated by the user but the
- * ConnectionService has confirmed the call as disconnected.
- */
- DISCONNECTING = 9;
-
- /**
- * Indicates that the call is in the process of being pulled to the local device.
- * <p>
- * This state should only be set on a call with
- * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL} and
- * {@link android.telecom.Connection#CAPABILITY_CAN_PULL_CALL}.
- */
- PULLING = 10;
-
- /**
- * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet
- * set the call to active.
- */
- ANSWERED = 11;
-
- /**
- * Indicates that the call is undergoing audio processing by a different app in the background.
- * @see android.telecom.Call#STATE_AUDIO_PROCESSING
- */
- AUDIO_PROCESSING = 12;
-
- /**
- * Indicates that the call is in a fake ringing state.
- * @see android.telecom.Call#STATE_SIMULATED_RINGING
- */
- SIMULATED_RINGING = 13;
-}
-
-// Disconnect causes for a call. Primarily used by android/telecom/DisconnectCause.java
-enum DisconnectCauseEnum {
- /**
- * Disconnected because of an unknown or unspecified reason.
- */
- UNKNOWN = 0;
-
- /**
- * Disconnected because there was an error, such as a problem with the network.
- */
- ERROR = 1;
-
- /**
- * Disconnected because of a local user-initiated action, such as hanging up.
- */
- LOCAL = 2;
-
- /**
- * Disconnected because of a remote user-initiated action, such as the other party hanging up
- * up.
- */
- REMOTE = 3;
-
- /**
- * Disconnected because it has been canceled.
- */
- CANCELED = 4;
-
- /**
- * Disconnected because there was no response to an incoming call.
- */
- MISSED = 5;
-
- /**
- * Disconnected because the user rejected an incoming call.
- */
- REJECTED = 6;
-
- /**
- * Disconnected because the other party was busy.
- */
- BUSY = 7;
-
- /**
- * Disconnected because of a restriction on placing the call, such as dialing in airplane
- * mode.
- */
- RESTRICTED = 8;
-
- /**
- * Disconnected for reason not described by other disconnect codes.
- */
- OTHER = 9;
-
- /**
- * Disconnected because the connection manager did not support the call. The call will be tried
- * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
- */
- CONNECTION_MANAGER_NOT_SUPPORTED = 10;
-
- /**
- * Disconnected because the user did not locally answer the incoming call, but it was answered
- * on another device where the call was ringing.
- */
- ANSWERED_ELSEWHERE = 11;
-
- /**
- * Disconnected because the call was pulled from the current device to another device.
- */
- CALL_PULLED = 12;
-}
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
deleted file mode 100644
index f14e3ed1872d..000000000000
--- a/core/proto/android/telephony/enums.proto
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.telephony;
-
-option java_outer_classname = "TelephonyProtoEnums";
-option java_multiple_files = true;
-
-enum CallBearerEnum {
- /** Call bearer is unknown or invalid */
- CALL_BEARER_UNKNOWN = 0;
-
- /** Call bearer is legacy CS */
- CALL_BEARER_CS = 1;
-
- /** Call bearer is IMS */
- CALL_BEARER_IMS = 2;
-}
-
-enum CallDirectionEnum {
- /** Call direction: unknown or invalid */
- CALL_DIRECTION_UNKNOWN = 0;
-
- /** Call direction: mobile originated (outgoing for this device) */
- CALL_DIRECTION_MO = 1;
-
- /** Call direction: mobile terminated (incoming for this device) */
- CALL_DIRECTION_MT = 2;
-}
-
-// Call setup duration buckets.
-// See com.android.internal.telephony.metrics.VoiceCallSessionStats for definition.
-enum CallSetupDurationEnum {
- CALL_SETUP_DURATION_UNKNOWN = 0;
- CALL_SETUP_DURATION_EXTREMELY_FAST = 1;
- CALL_SETUP_DURATION_ULTRA_FAST = 2;
- CALL_SETUP_DURATION_VERY_FAST = 3;
- CALL_SETUP_DURATION_FAST = 4;
- CALL_SETUP_DURATION_NORMAL = 5;
- CALL_SETUP_DURATION_SLOW = 6;
- CALL_SETUP_DURATION_VERY_SLOW = 7;
- CALL_SETUP_DURATION_ULTRA_SLOW = 8;
- CALL_SETUP_DURATION_EXTREMELY_SLOW = 9;
-}
-
-// Data conn. power states, primarily used by android/telephony/DataConnectionRealTimeInfo.java.
-enum DataConnectionPowerStateEnum {
- DATA_CONNECTION_POWER_STATE_LOW = 1;
- DATA_CONNECTION_POWER_STATE_MEDIUM = 2;
- DATA_CONNECTION_POWER_STATE_HIGH = 3;
- DATA_CONNECTION_POWER_STATE_UNKNOWN = 2147483647; // Java Integer.MAX_VALUE;
-}
-
-// Network type enums, primarily used by android/telephony/TelephonyManager.java.
-// Do not add negative types.
-enum NetworkTypeEnum {
- NETWORK_TYPE_UNKNOWN = 0;
- NETWORK_TYPE_GPRS = 1;
- NETWORK_TYPE_EDGE = 2;
- NETWORK_TYPE_UMTS = 3;
- NETWORK_TYPE_CDMA = 4;
- NETWORK_TYPE_EVDO_0 = 5;
- NETWORK_TYPE_EVDO_A = 6;
- NETWORK_TYPE_1XRTT = 7;
- NETWORK_TYPE_HSDPA = 8;
- NETWORK_TYPE_HSUPA = 9;
- NETWORK_TYPE_HSPA = 10;
- NETWORK_TYPE_IDEN = 11;
- NETWORK_TYPE_EVDO_B = 12;
- NETWORK_TYPE_LTE = 13;
- NETWORK_TYPE_EHRPD = 14;
- NETWORK_TYPE_HSPAP = 15;
- NETWORK_TYPE_GSM = 16;
- NETWORK_TYPE_TD_SCDMA = 17;
- NETWORK_TYPE_IWLAN = 18;
- NETWORK_TYPE_LTE_CA = 19;
- NETWORK_TYPE_NR = 20;
-}
-
-// Signal strength levels, primarily used by android/telephony/SignalStrength.java.
-enum SignalStrengthEnum {
- SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- SIGNAL_STRENGTH_POOR = 1;
- SIGNAL_STRENGTH_MODERATE = 2;
- SIGNAL_STRENGTH_GOOD = 3;
- SIGNAL_STRENGTH_GREAT = 4;
-}
-
-enum ServiceStateEnum {
- /**
- * Normal operation condition, the phone is registered
- * with an operator either in home network or in roaming.
- */
- SERVICE_STATE_IN_SERVICE = 0;
-
- /**
- * Phone is not registered with any operator, the phone
- * can be currently searching a new operator to register to, or not
- * searching to registration at all, or registration is denied, or radio
- * signal is not available.
- */
- SERVICE_STATE_OUT_OF_SERVICE = 1;
-
- /**
- * The phone is registered and locked. Only emergency numbers are allowed. {@more}
- */
- SERVICE_STATE_EMERGENCY_ONLY = 2;
-
- /**
- * Radio of telephony is explicitly powered off.
- */
- SERVICE_STATE_POWER_OFF = 3;
-}
-
-enum SimStateEnum {
- SIM_STATE_UNKNOWN = 0;
- /** SIM card state: no SIM card is available in the device */
- SIM_STATE_ABSENT = 1;
- /** SIM card state: Locked: requires the user's SIM PIN to unlock */
- SIM_STATE_PIN_REQUIRED = 2;
- /** SIM card state: Locked: requires the user's SIM PUK to unlock */
- SIM_STATE_PUK_REQUIRED = 3;
- /** SIM card state: Locked: requires a network PIN to unlock */
- SIM_STATE_NETWORK_LOCKED = 4;
- /** SIM card state: Ready */
- SIM_STATE_READY = 5;
- /** SIM card state: SIM Card is NOT READY */
- SIM_STATE_NOT_READY = 6;
- /** SIM card state: SIM Card Error, permanently disabled */
- SIM_STATE_PERM_DISABLED = 7;
- /** SIM card state: SIM Card Error, present but faulty */
- SIM_STATE_CARD_IO_ERROR = 8;
- /** SIM card state: SIM Card restricted, present but not usable due to
- * carrier restrictions.
- */
- SIM_STATE_CARD_RESTRICTED = 9;
- /**
- * SIM card state: Loaded: SIM card applications have been loaded
- * @hide
- */
- SIM_STATE_LOADED = 10;
- /**
- * SIM card state: SIM Card is present
- * @hide
- */
- SIM_STATE_PRESENT = 11;
-}
diff --git a/core/proto/android/view/enums.proto b/core/proto/android/view/enums.proto
deleted file mode 100644
index 0172e7899a18..000000000000
--- a/core/proto/android/view/enums.proto
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.view;
-
-option java_outer_classname = "ViewProtoEnums";
-option java_multiple_files = true;
-
-// Screen states, primarily used by android/view/Display.java.
-enum DisplayStateEnum {
- // The display state is unknown.
- DISPLAY_STATE_UNKNOWN = 0;
- // The display state is off.
- DISPLAY_STATE_OFF = 1;
- // The display state is on.
- DISPLAY_STATE_ON = 2;
- // The display is dozing in a low power state; it is still on but is
- // optimized for showing system-provided content while the device is
- // non-interactive.
- DISPLAY_STATE_DOZE = 3;
- // The display is dozing in a suspended low power state; it is still on
- // but is optimized for showing static system-provided content while the
- // device is non-interactive.
- DISPLAY_STATE_DOZE_SUSPEND = 4;
- // The display is on and optimized for VR mode.
- DISPLAY_STATE_VR = 5;
- // The display is in a suspended full power state; it is still on but the
- // CPU is not updating it.
- DISPLAY_STATE_ON_SUSPEND = 6;
-}
-
-// Constants found in android.view.WindowManager.
-enum TransitionTypeEnum {
- TRANSIT_NONE = 0;
- TRANSIT_UNSET = -1;
- TRANSIT_ACTIVITY_OPEN = 6;
- TRANSIT_ACTIVITY_CLOSE = 7;
- TRANSIT_TASK_OPEN = 8;
- TRANSIT_TASK_CLOSE = 9;
- TRANSIT_TASK_TO_FRONT = 10;
- TRANSIT_TASK_TO_BACK = 11;
- TRANSIT_WALLPAPER_CLOSE = 12;
- TRANSIT_WALLPAPER_OPEN = 13;
- TRANSIT_WALLPAPER_INTRA_OPEN = 14;
- TRANSIT_WALLPAPER_INTRA_CLOSE = 15;
- TRANSIT_TASK_OPEN_BEHIND = 16;
- TRANSIT_TASK_IN_PLACE = 17;
- TRANSIT_ACTIVITY_RELAUNCH = 18;
- TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
- TRANSIT_KEYGUARD_GOING_AWAY = 20;
- TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
- TRANSIT_KEYGUARD_OCCLUDE = 22;
- TRANSIT_KEYGUARD_UNOCCLUDE = 23;
- TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = 24;
- TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
- TRANSIT_CRASHING_ACTIVITY_CLOSE = 26;
-}
diff --git a/core/proto/android/wifi/enums.proto b/core/proto/android/wifi/enums.proto
deleted file mode 100644
index 315c5792c1de..000000000000
--- a/core/proto/android/wifi/enums.proto
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.net.wifi;
-
-option java_outer_classname = "WifiProtoEnums";
-option java_multiple_files = true;
-
-/**
- * Wifi Lock modes, primarily used in
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiLockManager.java.
- */
-enum WifiModeEnum {
- /**
- * Deprecated.
- * Wi-Fi will be kept active, and will behave normally.
- */
- WIFI_MODE_FULL = 1 [deprecated=true];
-
- /**
- * Deprecated.
- * Wi-Fi will be kept active, but the only operation that will be supported is initiation of
- * scans, and the subsequent reporting of scan results.
- */
- WIFI_MODE_SCAN_ONLY = 2 [deprecated=true];
-
- /**
- * Wi-Fi will not go to power save.
- */
- WIFI_MODE_FULL_HIGH_PERF = 3;
-
- /**
- * Wi-Fi will operate with a priority to achieve low latency.
- */
- WIFI_MODE_FULL_LOW_LATENCY = 4;
-}
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5eb271e754a6..54a002db3c2f 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1216,7 +1216,7 @@
<string name="dump_heap_ready_text" msgid="5849618132123045516">"የ<xliff:g id="PROC">%1$s</xliff:g> ሂደት ተራጋፊ ክምር ለማጋራት ለእርስዎ ይገኛል። ይጠንቀቁ፦ ይህ ተራጋፊ ክምር ሂደቱ ሊደርስባቸው የሚችለው ማንኛውም የግል መረጃ ሊኖረው ይችላል፣ ይህ እርስዎ የተየቧቸውን ነገሮች ሊያካትት ይችላል።"</string>
<string name="sendText" msgid="493003724401350724">"ለፅሁፍ ድርጊት ምረጥ"</string>
<string name="volume_ringtone" msgid="134784084629229029">"የስልክ ጥሪ ድምፅ"</string>
- <string name="volume_music" msgid="7727274216734955095">" ማህደረ መረጃ ክፍልፍል"</string>
+ <string name="volume_music" msgid="7727274216734955095">"የማህደረ መረጃ ድምጽ መጠን"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"በብሉቱዝ በኩል ማጫወት"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"የፀጥታ የስልክ የደውል ድምፅ ተዘጋጅቷል"</string>
<string name="volume_call" msgid="7625321655265747433">"የጥሪ ላይ ድም ፅ መጨመሪያ/መቀነሻ"</string>
@@ -1227,7 +1227,7 @@
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"የብሉቱዝ ድምፅ መጠን"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"የስልክ ጥሪ ድምፅ መጠን"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"የስልክ ጥሪ ድምፅ መጠን"</string>
- <string name="volume_icon_description_media" msgid="4997633254078171233">"የማህደረ መረጃ ክፍልፍል"</string>
+ <string name="volume_icon_description_media" msgid="4997633254078171233">"የማህደረ መረጃ ድምጽ መጠን"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"የማሳወቂያ ክፍልፍል"</string>
<string name="ringtone_default" msgid="9118299121288174597">"ነባሪ የስልክ ላይ ጥሪ"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"ነባሪ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1966a223c680..7564ae779471 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -270,9 +270,9 @@
<string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"وضع صامت"</string>
<string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"الصوت متوقف"</string>
<string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"الصوت قيد التفعيل"</string>
- <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"وضع الطائرة"</string>
- <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"وضع الطائرة قيد التفعيل"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"وضع الطائرة متوقف"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"وضع الطيران"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"وضع الطيران قيد التفعيل"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"وضع الطيران متوقف"</string>
<string name="global_action_settings" msgid="4671878836947494217">"الإعدادات"</string>
<string name="global_action_assist" msgid="2517047220311505805">"مساعدة"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"المساعد الصوتي"</string>
@@ -398,7 +398,7 @@
<string name="permlab_getPackageSize" msgid="375391550792886641">"قياس مساحة تخزين التطبيق"</string>
<string name="permdesc_getPackageSize" msgid="742743530909966782">"للسماح للتطبيق باسترداد شفرته وبياناته وأحجام ذاكرات التخزين المؤقت"</string>
<string name="permlab_writeSettings" msgid="8057285063719277394">"تعديل إعدادات النظام"</string>
- <string name="permdesc_writeSettings" msgid="8293047411196067188">"للسماح للتطبيق بتعديل بيانات إعدادات النظام. يمكن أن تتلف التطبيقات الضارة تهيئة نظامك."</string>
+ <string name="permdesc_writeSettings" msgid="8293047411196067188">"للسماح للتطبيق بتعديل بيانات إعدادات النظام. يمكن أن تتلف التطبيقات الضارة إعداد نظامك."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"العمل عند بدء التشغيل"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"للسماح للتطبيق ببدء تشغيل نفسه عقب انتهاء النظام من التشغيل. قد يؤدي ذلك إلى استغراق المزيد من الوقت عند بدء الجهاز اللوحي والسماح للتطبيق بإبطاء الأداء الإجمالي للجهاز اللوحي من خلال تشغيله دائمًا."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"‏للسماح بتشغيل التطبيق تلقائيًا بعد الانتهاء من بدء تشغيل النظام. وقد يؤدي ذلك إلى إطالة فترة بدء تشغيل جهاز Android TV، بالإضافة إلى أنه يسمح للتطبيق بإبطاء أداء الجهاز بشكل عام لأنه يتم تشغيله بشكل دائم."</string>
@@ -507,15 +507,15 @@
<string name="permlab_accessWifiState" msgid="5552488500317911052">"‏عرض اتصالات Wi-Fi"</string>
<string name="permdesc_accessWifiState" msgid="6913641669259483363">"‏للسماح للتطبيق بعرض معلومات حول شبكات Wi-Fi، كعرض معلومات حول ما إذا تم تفعيل Wi-Fi واسم أجهزة Wi-Fi المتصلة."</string>
<string name="permlab_changeWifiState" msgid="7947824109713181554">"‏التوصيل والفصل من Wi-Fi"</string>
- <string name="permdesc_changeWifiState" msgid="7170350070554505384">"‏للسماح للتطبيق بالاتصال بنقاط الوصول إلى Wi-Fi وقطع الاتصال بها، وإجراء تغييرات على تهيئة الجهاز لشبكات Wi-Fi."</string>
+ <string name="permdesc_changeWifiState" msgid="7170350070554505384">"‏للسماح للتطبيق بالاتصال بنقاط الوصول إلى Wi-Fi وقطع الاتصال بها، وإجراء تغييرات على إعداد الجهاز لشبكات Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"‏السماح باستقبال بث Wi-Fi متعدد"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"‏للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهازك اللوحي فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"‏للسماح للتطبيق بتلقّي الحِزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهاز Android TV فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق ما يتم استهلاكه في وضع البث غير المتعدد."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"‏للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"الدخول إلى إعدادات بلوتوث"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"للسماح للتطبيق بإعداد لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"‏للسماح للتطبيق بضبط البلوتوث على جهاز Android TV واكتشاف الأجهزة البعيدة والاقتران بها."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"للسماح للتطبيق بإعداد هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"‏الاتصال بـشبكة WiMAX وقطع الاتصال بها"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"‏للسماح للتطبيق بتحديد ما إذا تم تفعيل WiMAX وتحديد معلومات حول أي شبكات WiMAX متصلة."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"‏تغيير حالة WiMAX"</string>
@@ -523,9 +523,9 @@
<string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"‏للسماح للتطبيق بتوصيل جهاز Android TV بشبكات WiMAX وقطع اتصاله بها."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"‏للسماح للتطبيق بتوصيل الهاتف بشبكات WiMAX وقطع اتصاله بها."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"الاتصال بأجهزة بلوتوث"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"للسماح للتطبيق بعرض تهيئة البلوتوث على الجهاز اللوحي وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"للسماح للتطبيق بعرض إعداد البلوتوث على الجهاز اللوحي وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"‏للسماح للتطبيق بعرض بيانات ضبط البلوتوث على جهاز Android TV وإجراء اتصالات مع الأجهزة المقترنة وقبولها."</string>
- <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"للسماح للتطبيق بعرض تهيئة البلوتوث على الهاتف وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"للسماح للتطبيق بعرض إعداد البلوتوث على الهاتف وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
@@ -661,8 +661,8 @@
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"للسماح للمالك بالربط بواجهة المستوى العلوي لخدمة موفر الحالة. لن تكون هناك حاجة إلى هذا الإعداد مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"‏الالتزام بخدمة dream"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"‏للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة dream. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"استدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"للسماح للمالك باستدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"استدعاء تطبيق الإعداد الذي يوفره مشغل شبكة الجوال"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"للسماح للمالك باستدعاء تطبيق الإعداد الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"الاستماع إلى ملاحظات حول أحوال الشبكة"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"تغيير معايرة أجهزة الإدخال"</string>
@@ -678,7 +678,7 @@
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"الالتزام بخدمات مشغل شبكة الجوال"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"للسماح للمالك بالالتزام بخدمات مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"الوصول إلى إعداد \"عدم الإزعاج\""</string>
- <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"للسماح للتطبيق بقراءة تهيئة \"عدم الإزعاج\" وكتابتها."</string>
+ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"للسماح للتطبيق بقراءة إعداد \"عدم الإزعاج\" وكتابتها."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"بدء استخدام إذن العرض"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"للسماح للمالك ببدء استخدام الإذن لأحد التطبيقات. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"تعيين قواعد كلمة المرور"</string>
@@ -1298,7 +1298,7 @@
<string name="volume_ringtone" msgid="134784084629229029">"مستوى صوت الرنين"</string>
<string name="volume_music" msgid="7727274216734955095">"مستوى صوت الوسائط"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"تشغيل من خلال البلوتوث"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"تم تعيين نغمة الرنين الصامتة"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"تم ضبط نغمة الرنين الصامتة"</string>
<string name="volume_call" msgid="7625321655265747433">"مستوى صوت المكالمات الواردة"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"مستوى صوت المكالمة الواردة بالبلوتوث"</string>
<string name="volume_alarm" msgid="4486241060751798448">"مستوى صوت المنبّه"</string>
@@ -1409,7 +1409,7 @@
<string name="select_input_method" msgid="3971267998568587025">"اختيار أسلوب الإدخال"</string>
<string name="show_ime" msgid="6406112007347443383">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
<string name="hardware" msgid="1800597768237606953">"إظهار لوحة المفاتيح الافتراضية"</string>
- <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"تهيئة لوحة المفاتيح الفعلية"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"إعداد لوحة المفاتيح الفعلية"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"انقر لاختيار لغة وتنسيق"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
@@ -1462,7 +1462,7 @@
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"تالف"</string>
<string name="ext_media_status_unsupported" msgid="5460509911660539317">"غير متوافق"</string>
<string name="ext_media_status_ejecting" msgid="7532403368044013797">"جارٍ إنهاء التحميل…"</string>
- <string name="ext_media_status_formatting" msgid="774148701503179906">"جارٍ التهيئة…"</string>
+ <string name="ext_media_status_formatting" msgid="774148701503179906">"تجري التهيئة..."</string>
<string name="ext_media_status_missing" msgid="6520746443048867314">"لم يتم الإدخال"</string>
<string name="activity_list_empty" msgid="4219430010716034252">"لم يتم العثور على أي أنشطة متطابقة."</string>
<string name="permlab_route_media_output" msgid="8048124531439513118">"توجيه إخراج الوسائط"</string>
@@ -2155,7 +2155,7 @@
<string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"جدول بيانات: <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
<string name="mime_type_presentation" msgid="1145384236788242075">"عرض تقديمي"</string>
<string name="mime_type_presentation_ext" msgid="8761049335564371468">"عرض تقديمي: <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
- <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطائرة\"."</string>
+ <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطيران\"."</string>
<string name="car_loading_profile" msgid="8219978381196748070">"جارٍ التحميل"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="zero"><xliff:g id="FILE_NAME_2">%s</xliff:g> و<xliff:g id="COUNT_3">%d</xliff:g> ملف</item>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index f2c7c4551de8..8f9c179417f8 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"স্পেচ"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"লিখক"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"মচক"</string>
- <string name="search_go" msgid="2141477624421347086">"অনুসন্ধান কৰক"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"অনুসন্ধান কৰক…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"অনুসন্ধান কৰক"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"প্ৰশ্নৰ সন্ধান কৰক"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"প্ৰশ্ন মচক"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"প্ৰশ্ন দাখিল কৰক"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্ৰণ কৰিবলৈ দুবাৰ টিপক"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ৱিজেট যোগ কৰিব পৰা নগ\'ল।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যাওক"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"অনুসন্ধান কৰক"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"পঠিয়াওক"</string>
<string name="ime_action_next" msgid="4169702997635728543">"পৰৱৰ্তী"</string>
<string name="ime_action_done" msgid="6299921014822891569">"সম্পন্ন হ’ল"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"প্ৰস্তাৱিত"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"সকলো ভাষা"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"সকলো অঞ্চল"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"অনুসন্ধান কৰক"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"এপটো নাই"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"এই মুহূৰ্তত <xliff:g id="APP_NAME_0">%1$s</xliff:g> উপলব্ধ নহয়। ইয়াক <xliff:g id="APP_NAME_1">%2$s</xliff:g>এ পৰিচালনা কৰে।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"অধিক জানক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 3fb5131ba763..f1b9743ea99e 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -701,7 +701,7 @@
<string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Bəzi ekran kilidi funksiyalarını deaktiv edin"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"Bəzi ekran funksiyaları istifadəsinin qarşısını alın."</string>
<string-array name="phoneTypes">
- <item msgid="8996339953292723951">"Əsas səhifə"</item>
+ <item msgid="8996339953292723951">"Ev"</item>
<item msgid="7740243458912727194">"Mobil"</item>
<item msgid="8526146065496663766">"İş"</item>
<item msgid="8150904584178569699">"İş Faksı"</item>
@@ -711,19 +711,19 @@
<item msgid="6216981255272016212">"Şəxsi"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="7786349763648997741">"Ana səhifə"</item>
+ <item msgid="7786349763648997741">"Ev"</item>
<item msgid="435564470865989199">"İş"</item>
<item msgid="4199433197875490373">"Digər"</item>
<item msgid="3233938986670468328">"Fərdi"</item>
</string-array>
<string-array name="postalAddressTypes">
- <item msgid="3861463339764243038">"Əsas səhifə"</item>
+ <item msgid="3861463339764243038">"Ev"</item>
<item msgid="5472578890164979109">"İş"</item>
<item msgid="5718921296646594739">"Digər"</item>
<item msgid="5523122236731783179">"Düzənləyin"</item>
</string-array>
<string-array name="imAddressTypes">
- <item msgid="588088543406993772">"Əsas səhifə"</item>
+ <item msgid="588088543406993772">"Ev"</item>
<item msgid="5503060422020476757">"İş"</item>
<item msgid="2530391194653760297">"Digər"</item>
<item msgid="7640927178025203330">"Fərdi"</item>
@@ -769,16 +769,16 @@
<string name="eventTypeAnniversary" msgid="4684702412407916888">"İldönümü"</string>
<string name="eventTypeOther" msgid="530671238533887997">"Digər"</string>
<string name="emailTypeCustom" msgid="1809435350482181786">"Fərdi"</string>
- <string name="emailTypeHome" msgid="1597116303154775999">"Əsas səhifə"</string>
+ <string name="emailTypeHome" msgid="1597116303154775999">"Şəxsi"</string>
<string name="emailTypeWork" msgid="2020095414401882111">"İş"</string>
<string name="emailTypeOther" msgid="5131130857030897465">"Digər"</string>
<string name="emailTypeMobile" msgid="787155077375364230">"Mobil"</string>
<string name="postalTypeCustom" msgid="5645590470242939129">"Fərdi"</string>
- <string name="postalTypeHome" msgid="7562272480949727912">"Əsas səhifə"</string>
+ <string name="postalTypeHome" msgid="7562272480949727912">"Ev"</string>
<string name="postalTypeWork" msgid="8553425424652012826">"İş"</string>
<string name="postalTypeOther" msgid="7094245413678857420">"Digər"</string>
<string name="imTypeCustom" msgid="5653384545085765570">"Fərdi"</string>
- <string name="imTypeHome" msgid="6996507981044278216">"Ana səhifə"</string>
+ <string name="imTypeHome" msgid="6996507981044278216">"Ev"</string>
<string name="imTypeWork" msgid="2099668940169903123">"İş"</string>
<string name="imTypeOther" msgid="8068447383276219810">"Digər"</string>
<string name="imProtocolCustom" msgid="4437878287653764692">"Şəxsi"</string>
@@ -810,7 +810,7 @@
<string name="relationTypeSister" msgid="3721676005094140671">"Bacı"</string>
<string name="relationTypeSpouse" msgid="6916682664436031703">"Həyat yoldaşı"</string>
<string name="sipAddressTypeCustom" msgid="6283889809842649336">"Fərdi"</string>
- <string name="sipAddressTypeHome" msgid="5918441930656878367">"Əsas səhifə"</string>
+ <string name="sipAddressTypeHome" msgid="5918441930656878367">"Ev"</string>
<string name="sipAddressTypeWork" msgid="7873967986701216770">"İş"</string>
<string name="sipAddressTypeOther" msgid="6317012577345187275">"Digər"</string>
<string name="quick_contacts_not_available" msgid="1262709196045052223">"Bu kontakta baxmaq üçün heç bir tətbiq tapılmadı."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ecbe6d0ed2ab..001267180f35 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -94,7 +94,7 @@
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status mobilnih podataka"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS-ovi"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Poruke govorne pošte"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Pozivanje preko Wi-Fi mreže"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Pozivanje preko WiFi mreže"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"Status SIM-a"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Obaveštenja SIM kartice sa statusom „visok prioritet“"</string>
<string name="peerTtyModeFull" msgid="337553730440832160">"Korisnik zahteva POTPUN režim TTY"</string>
@@ -123,30 +123,30 @@
<string name="roamingText11" msgid="5245687407203281407">"Baner rominga je uključen"</string>
<string name="roamingText12" msgid="673537506362152640">"Baner rominga je isključen"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Pretraživanje usluge"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Podešavanje pozivanja preko Wi-Fi-ja nije uspelo"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Podešavanje pozivanja preko WiFi-a nije uspelo"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"Da biste upućivali pozive i slali poruke preko WiFi-a, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko WiFi-a. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"Problem u vezi sa registrovanjem pozivanja preko Wi‑Fi-ja kod mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko Wi-Fi-ja"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko Wi-Fi-ja"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko WiFi-a"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko WiFi-a"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN poziv"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
- <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Pozivanje preko Wi-Fi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
+ <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Pozivanje preko WiFi-a | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Pozivanje preko Wi-Fi-ja"</string>
- <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko Wi-Fi-ja"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Pozivanje preko WiFi-a"</string>
+ <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko WiFi-a"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
- <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko Wi-Fi-ja"</string>
+ <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko WiFi-a"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Poziv preko mobilne mreže"</string>
- <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo Wi-Fi"</string>
+ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo WiFi"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> nakon <xliff:g id="TIME_DELAY">{2}</xliff:g> sekunde/i"</string>
@@ -241,7 +241,7 @@
<string name="global_action_power_off" msgid="4404936470711393203">"Isključi"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"Napajanje"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Restartuj"</string>
- <string name="global_action_emergency" msgid="1387617624177105088">"Hitni poziv"</string>
+ <string name="global_action_emergency" msgid="1387617624177105088">"Hitan poziv"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Izveštaj o grešci"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snimak ekrana"</string>
@@ -495,14 +495,14 @@
<string name="permdesc_changeNetworkState" msgid="649341947816898736">"Dozvoljava aplikaciji da menja status povezivanja sa mrežom."</string>
<string name="permlab_changeTetherState" msgid="9079611809931863861">"promena povezivanja privezivanjem"</string>
<string name="permdesc_changeTetherState" msgid="3025129606422533085">"Dozvoljava aplikaciji da menja status veze sa privezanom mrežom."</string>
- <string name="permlab_accessWifiState" msgid="5552488500317911052">"pregled Wi-Fi veza"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Dozvoljava aplikaciji da pregleda informacije o Wi-Fi umrežavanju, kao što su informacije o tome da li je Wi-Fi omogućen i nazivi povezanih Wi-Fi uređaja."</string>
- <string name="permlab_changeWifiState" msgid="7947824109713181554">"povezivanje i prekid veze sa Wi-Fi mrežom"</string>
- <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Dozvoljava aplikaciji da se povezuje sa pristupnim tačkama za Wi-Fi i prekida vezu sa njima, kao i da unosi promene u konfiguraciju uređaja za Wi-Fi mreže."</string>
- <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"omogućavanje prijema višesmernog Wi-Fi saobraćaja"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na Wi-Fi mreži pomoću višesmernih adresa, a ne samo na tablet. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na Wi-Fi mreži pomoću višesmernih adresa, a ne samo na Android TV uređaj. Koristi više energije od režima bez višesmernog slanja."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na Wi-Fi mreži pomoću višesmernih adresa, a ne samo na telefon. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
+ <string name="permlab_accessWifiState" msgid="5552488500317911052">"pregled WiFi veza"</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Dozvoljava aplikaciji da pregleda informacije o WiFi umrežavanju, kao što su informacije o tome da li je WiFi omogućen i nazivi povezanih WiFi uređaja."</string>
+ <string name="permlab_changeWifiState" msgid="7947824109713181554">"povezivanje i prekid veze sa WiFi mrežom"</string>
+ <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Dozvoljava aplikaciji da se povezuje sa pristupnim tačkama za WiFi i prekida vezu sa njima, kao i da unosi promene u konfiguraciju uređaja za WiFi mreže."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"omogućavanje prijema višesmernog WiFi saobraćaja"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na tablet. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na Android TV uređaj. Koristi više energije od režima bez višesmernog slanja."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Dozvoljava aplikaciji da prima pakete koji se šalju na sve uređaje na WiFi mreži pomoću višesmernih adresa, a ne samo na telefon. Koristi više napajanja od režima jednosmernog saobraćaja."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"pristup Bluetooth podešavanjima"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Dozvoljava aplikaciji da konfiguriše lokalni Bluetooth tablet, kao i da otkrije daljinske uređaje i upari se sa njima."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Dozvoljava aplikaciji da konfiguriše Bluetooth na Android TV uređaju i da otkrije udaljene uređaje i upari se sa njima."</string>
@@ -1256,7 +1256,7 @@
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Zvuci alarma"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Zvuci obaveštenja"</string>
<string name="ringtone_unknown" msgid="5059495249862816475">"Nepoznato"</string>
- <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na Wi-Fi mrežu"</string>
+ <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
<string name="network_available_sign_in" msgid="1520342291829283114">"Prijavite se na mrežu"</string>
<!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
<skip />
@@ -1272,7 +1272,7 @@
<string name="network_switch_metered_toast" msgid="501662047275723743">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
<string-array name="network_switch_type_name">
<item msgid="2255670471736226365">"mobilni podaci"</item>
- <item msgid="5520925862115353992">"Wi-Fi"</item>
+ <item msgid="5520925862115353992">"WiFi"</item>
<item msgid="1055487873974272842">"Bluetooth"</item>
<item msgid="1616528372438698248">"Eternet"</item>
<item msgid="9177085807664964627">"VPN"</item>
@@ -1538,10 +1538,10 @@
<string name="data_usage_warning_title" msgid="9034893717078325845">"Upozorenje na potrošnju podataka"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"Potrošili ste <xliff:g id="APP">%s</xliff:g> podataka"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Dostigli ste ograničenje podataka"</string>
- <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Nema više Wi-Fi podataka"</string>
+ <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Nema više WiFi podataka"</string>
<string name="data_usage_limit_body" msgid="3567699582000085710">"Podaci su pauzirani tokom ostatka ciklusa"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Potrošili ste mobilne podatke"</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Potrošili ste Wi-Fi podatke"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Potrošili ste WiFi podatke"</string>
<string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Prekoračili ste <xliff:g id="SIZE">%s</xliff:g> od podešenog ograničenja"</string>
<string name="data_usage_restricted_title" msgid="126711424380051268">"Pozadinski podaci su ograničeni"</string>
<string name="data_usage_restricted_body" msgid="5338694433686077733">"Dodirnite za uklanjanje ograničenja."</string>
@@ -1815,7 +1815,7 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Da bi se produžilo trajanje baterije, Ušteda baterije:\n\n•uključuje tamnu temu\n•isključuje ili ograničava aktivnosti u pozadini, neke vizuelne efekte i druge funkcije, na primer, „Ok Google“\n\n"<annotation id="url">"Saznajte više"</annotation></string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Da bi se produžilo trajanje baterije, Ušteda baterije:\n\n•uključuje tamnu temu\n•isključuje ili ograničava aktivnosti u pozadini, neke vizuelne efekte i druge funkcije, na primer „Ok Google“\n\n"<annotation id="url">"Saznajte više"</annotation></string>
<string name="battery_saver_description" msgid="8587408568232177204">"Da bi se produžilo trajanje baterije, Ušteda baterije:\n\n•uključuje tamnu temu\n•isključuje ili ograničava aktivnosti u pozadini, neke vizuelne efekte i druge funkcije, na primer, „Ok Google“"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Želite da uključite Uštedu podataka?"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 67c6ab36723d..ddee07c8d5ee 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -98,9 +98,9 @@
<string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi-тэлефанія"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"Статус SIM-карты"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Стан SIM-карты з высокім прыярытэтам"</string>
- <string name="peerTtyModeFull" msgid="337553730440832160">"Аднарангавая прылада запытала рэжым TTY FULL"</string>
- <string name="peerTtyModeHco" msgid="5626377160840915617">"Аднарангавая прылада запытала рэжым TTY НСО"</string>
- <string name="peerTtyModeVco" msgid="572208600818270944">"Аднарангавая прылада запытала рэжым TTY VCO"</string>
+ <string name="peerTtyModeFull" msgid="337553730440832160">"Аднарангавая прылада запытала рэжым поўнафункцыянальнага TTY"</string>
+ <string name="peerTtyModeHco" msgid="5626377160840915617">"Аднарангавая прылада запытала рэжым TTY з магчымасцю чуць суразмоўніка"</string>
+ <string name="peerTtyModeVco" msgid="572208600818270944">"Аднарангавая прылада запытала рэжым TTY з магчымасцю чуць суразмоўніка"</string>
<string name="peerTtyModeOff" msgid="2420380956369226583">"Аднарангавая прылада запытала рэжым TTY OFF"</string>
<string name="serviceClassVoice" msgid="2065556932043454987">"Голас"</string>
<string name="serviceClassData" msgid="4148080018967300248">"Дадзеныя"</string>
@@ -717,10 +717,10 @@
<item msgid="6216981255272016212">"Асаблівы"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="7786349763648997741">"Хатні"</item>
- <item msgid="435564470865989199">"Працоўны"</item>
- <item msgid="4199433197875490373">"Іншы"</item>
- <item msgid="3233938986670468328">"Карыстальніцкі"</item>
+ <item msgid="7786349763648997741">"Асабістая"</item>
+ <item msgid="435564470865989199">"Працоўная"</item>
+ <item msgid="4199433197875490373">"Іншая"</item>
+ <item msgid="3233938986670468328">"Карыстальніцкая"</item>
</string-array>
<string-array name="postalAddressTypes">
<item msgid="3861463339764243038">"На Галоўную старонку"</item>
@@ -770,14 +770,14 @@
<string name="phoneTypeWorkPager" msgid="3748332310638505234">"Працоўны пэйджар"</string>
<string name="phoneTypeAssistant" msgid="757550783842231039">"Асістэнт"</string>
<string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
- <string name="eventTypeCustom" msgid="3257367158986466481">"Карыстальніцкі"</string>
+ <string name="eventTypeCustom" msgid="3257367158986466481">"Карыстальніцкае"</string>
<string name="eventTypeBirthday" msgid="7770026752793912283">"Дзень нараджэння"</string>
<string name="eventTypeAnniversary" msgid="4684702412407916888">"Гадавіна"</string>
<string name="eventTypeOther" msgid="530671238533887997">"Іншае"</string>
- <string name="emailTypeCustom" msgid="1809435350482181786">"Карыстальніцкі"</string>
+ <string name="emailTypeCustom" msgid="1809435350482181786">"Карыстальніцкая"</string>
<string name="emailTypeHome" msgid="1597116303154775999">"Хатні"</string>
- <string name="emailTypeWork" msgid="2020095414401882111">"Працоўны"</string>
- <string name="emailTypeOther" msgid="5131130857030897465">"Іншы"</string>
+ <string name="emailTypeWork" msgid="2020095414401882111">"Працоўная"</string>
+ <string name="emailTypeOther" msgid="5131130857030897465">"Іншая"</string>
<string name="emailTypeMobile" msgid="787155077375364230">"Мабільны"</string>
<string name="postalTypeCustom" msgid="5645590470242939129">"Карыстальніцкі"</string>
<string name="postalTypeHome" msgid="7562272480949727912">"Хатні"</string>
@@ -800,19 +800,19 @@
<string name="orgTypeWork" msgid="8684458700669564172">"Працоўная"</string>
<string name="orgTypeOther" msgid="5450675258408005553">"Іншая"</string>
<string name="orgTypeCustom" msgid="1126322047677329218">"Карыстальніцкі"</string>
- <string name="relationTypeCustom" msgid="282938315217441351">"Карыстальніцкі"</string>
+ <string name="relationTypeCustom" msgid="282938315217441351">"Карыстальніцкае"</string>
<string name="relationTypeAssistant" msgid="4057605157116589315">"Памочнік"</string>
<string name="relationTypeBrother" msgid="7141662427379247820">"Брат"</string>
<string name="relationTypeChild" msgid="9076258911292693601">"Дзіця"</string>
- <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Унутраны Партнёр"</string>
+ <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Сужыцель/сужыцелька"</string>
<string name="relationTypeFather" msgid="3856225062864790596">"Бацька"</string>
<string name="relationTypeFriend" msgid="3192092625893980574">"Сябар/сяброўка"</string>
<string name="relationTypeManager" msgid="2272860813153171857">"Кіраўнік"</string>
<string name="relationTypeMother" msgid="2331762740982699460">"Маці"</string>
- <string name="relationTypeParent" msgid="4177920938333039882">"Бацька"</string>
+ <string name="relationTypeParent" msgid="4177920938333039882">"Бацька/маці"</string>
<string name="relationTypePartner" msgid="4018017075116766194">"Партнёр"</string>
- <string name="relationTypeReferredBy" msgid="5285082289602849400">"Запрошаны"</string>
- <string name="relationTypeRelative" msgid="3396498519818009134">"Адносны"</string>
+ <string name="relationTypeReferredBy" msgid="5285082289602849400">"Рэкамендацыя"</string>
+ <string name="relationTypeRelative" msgid="3396498519818009134">"Радня"</string>
<string name="relationTypeSister" msgid="3721676005094140671">"Сястра"</string>
<string name="relationTypeSpouse" msgid="6916682664436031703">"Муж/жонка"</string>
<string name="sipAddressTypeCustom" msgid="6283889809842649336">"Карыстальніцкі"</string>
@@ -967,13 +967,13 @@
<string name="permlab_addVoicemail" msgid="4770245808840814471">"дадаць галасавое паведамленне"</string>
<string name="permdesc_addVoicemail" msgid="5470312139820074324">"Дазваляе прыкладанням дадаваць паведамленні ў вашу скрыню галасавой пошты."</string>
<string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"змяніць дазволы геапазіцыянавання для браўзэра"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Дазваляе прыкладанням змяняць дазволы геалакацыі браўзэра. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб дазваляць адпраўку інфармацыі аб месцазнаходжанні выпадковым вэб-сайтам."</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Дазваляе праграме змяняць дазволы геалакацыі браўзера. Шкодныя праграмы могуць выкарыстоўваць гэта, каб адпраўляць даныя аб месцазнаходжанні на любыя вэб-сайты."</string>
<string name="save_password_message" msgid="2146409467245462965">"Вы хочаце, каб браўзэр запомніў гэты пароль?"</string>
<string name="save_password_notnow" msgid="2878327088951240061">"Не зараз"</string>
<string name="save_password_remember" msgid="6490888932657708341">"Запомніць"</string>
<string name="save_password_never" msgid="6776808375903410659">"Ніколі"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"У вас няма дазволу на адкрыццё гэтай старонкі."</string>
- <string name="text_copied" msgid="2531420577879738860">"Тэкст скапіяваны ў буфер абмену."</string>
+ <string name="text_copied" msgid="2531420577879738860">"Тэкст скапіраваны ў буфер абмену."</string>
<string name="copied" msgid="4675902854553014676">"Скапіравана"</string>
<string name="more_item_label" msgid="7419249600215749115">"Больш"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Меню+"</string>
@@ -1342,8 +1342,8 @@
<string name="usb_tether_notification_title" msgid="8828527870612663771">"Рэжым USB-мадэма"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI праз USB"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-прылада падключана"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"Дакраніцеся, каб атрымаць іншыя параметры."</string>
- <string name="usb_power_notification_message" msgid="7284765627437897702">"Зарадка падключанай прылады. Націсніце, каб убачыць іншыя параметры."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"Дакраніцеся, каб убачыць іншыя параметры."</string>
+ <string name="usb_power_notification_message" msgid="7284765627437897702">"Падключаная прылада зараджаецца. Дакраніцеся, каб убачыць іншыя параметры."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Выяўлены аксесуар аналагавага аўдыя"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Далучаная прылада не сумяшчальная з гэтым тэлефонам. Націсніце, каб даведацца больш."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Адладка па USB падключана"</string>
@@ -1542,7 +1542,7 @@
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Не атрымалася запусціць <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="shareactionprovider_share_with" msgid="2753089758467748982">"Апублікаваць з дапамогай"</string>
<string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Адправiць з дапамогай прыкладання <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="content_description_sliding_handle" msgid="982510275422590757">"Ручка для перасоўвання. Націсніце і ўтрымлівайце."</string>
+ <string name="content_description_sliding_handle" msgid="982510275422590757">"Маркер для перасоўвання. Дакраніцеся і ўтрымлівайце."</string>
<string name="description_target_unlock_tablet" msgid="7431571180065859551">"Прагартайце, каб разблакаваць."</string>
<string name="action_bar_home_description" msgid="1501655419158631974">"Перайсці да пачатковай старонкі"</string>
<string name="action_bar_up_description" msgid="6611579697195026932">"Перайсці ўверх"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index eed2a0091adb..b95cab1aa3ae 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -795,7 +795,7 @@
<string name="orgTypeOther" msgid="5450675258408005553">"অন্যান্য"</string>
<string name="orgTypeCustom" msgid="1126322047677329218">"কাস্টম"</string>
<string name="relationTypeCustom" msgid="282938315217441351">"কাস্টম"</string>
- <string name="relationTypeAssistant" msgid="4057605157116589315">"Assistant"</string>
+ <string name="relationTypeAssistant" msgid="4057605157116589315">"অ্যাসিস্ট্যান্ট"</string>
<string name="relationTypeBrother" msgid="7141662427379247820">"ভাই"</string>
<string name="relationTypeChild" msgid="9076258911292693601">"সন্তান"</string>
<string name="relationTypeDomesticPartner" msgid="7825306887697559238">"জীবনসাথি"</string>
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"স্পেস"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"মুছুন"</string>
- <string name="search_go" msgid="2141477624421347086">"খুঁজুন"</string>
+ <string name="search_go" msgid="2141477624421347086">"সার্চ"</string>
<string name="search_hint" msgid="455364685740251925">"সার্চ করুন..."</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"খুঁজুন"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"সার্চ"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"সার্চ ক্যোয়ারী"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ক্যোয়ারী সাফ করুন"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ক্যোয়ারী জমা দিন"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"উইজেট যোগ করা যায়নি৷"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যান"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"খুঁজুন"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"সার্চ"</string>
<string name="ime_action_send" msgid="8456843745664334138">"পাঠান"</string>
<string name="ime_action_next" msgid="4169702997635728543">"পরবর্তী"</string>
<string name="ime_action_done" msgid="6299921014822891569">"সম্পন্ন হয়েছে"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"প্রস্তাবিত"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"সকল ভাষা"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"সমস্ত অঞ্চল"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"খুঁজুন"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"সার্চ"</string>
<string name="app_suspended_title" msgid="888873445010322650">"অ্যাপটি উপলভ্য নয়"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> এখন উপলভ্য নয়। এই অ্যাপটিকে <xliff:g id="APP_NAME_1">%2$s</xliff:g> অ্যাপ ম্যানেজ করে।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"আরও জানুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 6e334b8ebb49..079eb56a4377 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -590,7 +590,7 @@
<string name="face_acquired_not_detected" msgid="2945945257956443257">"Postavite lice direktno ispred telefona"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Previše pokreta. Držite telefon mirno."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ponovo registrirajte lice."</string>
- <string name="face_acquired_too_different" msgid="4699657338753282542">"Nije više moguće prepoznati lice. Pokušajte opet."</string>
+ <string name="face_acquired_too_different" msgid="4699657338753282542">"Više nije moguće prepoznati lice. Pokušajte opet."</string>
<string name="face_acquired_too_similar" msgid="7684650785108399370">"Previše slično, promijenite položaj."</string>
<string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Malo manje zakrenite glavu."</string>
<string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Malo manje zakrenite glavu."</string>
@@ -970,7 +970,7 @@
<string name="save_password_remember" msgid="6490888932657708341">"Zapamti"</string>
<string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemate odobrenje za otvaranje ove stranice."</string>
- <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međuspremnik."</string>
+ <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međumemoriju."</string>
<string name="copied" msgid="4675902854553014676">"Kopirano"</string>
<string name="more_item_label" msgid="7419249600215749115">"Više"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
@@ -1280,7 +1280,7 @@
<string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznata vrsta mreže"</string>
<string name="accept" msgid="5447154347815825107">"Prihvati"</string>
<string name="decline" msgid="6490507610282145874">"Odbijte"</string>
- <string name="select_character" msgid="3352797107930786979">"Umetni karakter"</string>
+ <string name="select_character" msgid="3352797107930786979">"Umetni znak"</string>
<string name="sms_control_title" msgid="4748684259903148341">"Slanje SMS poruka"</string>
<string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; šalje veliki broj SMS poruka. Da li želite dozvoliti ovoj aplikaciji da nastavi slanje poruka?"</string>
<string name="sms_control_yes" msgid="4858845109269524622">"Dozvoli"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3e15e1301c83..6fefb23f185b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -312,7 +312,7 @@
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registres de trucades"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"llegir i editar el registre de trucades del telèfon"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telèfon"</string>
- <string name="permgroupdesc_phone" msgid="270048070781478204">"fer i gestionar trucades"</string>
+ <string name="permgroupdesc_phone" msgid="270048070781478204">"fer i gestionar trucades telefòniques"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"Sensors corporals"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"accedir a les dades del sensor sobre els signes vitals"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Recuperar el contingut de la finestra"</string>
@@ -325,7 +325,7 @@
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Controla el nivell i la posició del zoom de la pantalla."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Fer gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Permet tocar, lliscar, pinçar i fer altres gestos."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos d\'empremtes dactilars"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos d\'empremtes digitals"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Captura gestos realitzats en el sensor d\'empremtes dactilars del dispositiu."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fes una captura de pantalla"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pots fer una captura de la pantalla."</string>
@@ -341,8 +341,8 @@
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet que l\'aplicació suprimeixi les dreceres de la pantalla d\'inici sense la intervenció de l\'usuari."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"desviació de les trucades sortints"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permet que l\'aplicació vegi el número que s\'està marcant durant una trucada sortint, amb l\'opció de redirigir la trucada a un altre número o bé de cancel·lar-la completament."</string>
- <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"contestar a trucades"</string>
- <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permet que l\'aplicació contesti a una trucada entrant."</string>
+ <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"contestar a trucades telefòniques"</string>
+ <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permet que l\'aplicació contesti a una trucada telefònica entrant."</string>
<string name="permlab_receiveSms" msgid="505961632050451881">"recepció de missatges de text (SMS)"</string>
<string name="permdesc_receiveSms" msgid="1797345626687832285">"Permet que l\'aplicació rebi i processi missatges SMS. Això vol dir que l\'aplicació pot controlar o suprimir missatges que s\'han enviat al teu dispositiu sense mostrar-te\'ls."</string>
<string name="permlab_receiveMms" msgid="4000650116674380275">"recepció de missatges de text (MMS)"</string>
@@ -468,10 +468,10 @@
<string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Permet que l\'aplicació impedeixi que la tauleta entri en repòs."</string>
<string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Permet que l\'aplicació impedeixi que el dispositiu Android TV entri en repòs."</string>
<string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Permet que l\'aplicació impedeixi que el telèfon entri en repòs."</string>
- <string name="permlab_transmitIr" msgid="8077196086358004010">"transmissió d\'infraroigs"</string>
- <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet que l\'aplicació utilitzi el transmissor d\'infraroigs de la tauleta."</string>
- <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet que l\'aplicació faci servir el transmissor d\'infraroigs del dispositiu Android TV."</string>
- <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet que l\'aplicació utilitzi el transmissor d\'infraroigs del telèfon."</string>
+ <string name="permlab_transmitIr" msgid="8077196086358004010">"transmissió d\'infrarojos"</string>
+ <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet que l\'aplicació utilitzi el transmissor d\'infrarojos de la tauleta."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet que l\'aplicació faci servir el transmissor d\'infrarojos del dispositiu Android TV."</string>
+ <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet que l\'aplicació utilitzi el transmissor d\'infrarojos del telèfon."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"establir fons de pantalla"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"Permet que l\'aplicació estableixi el fons de pantalla del sistema."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"ajustament de la mida del fons de pantalla"</string>
@@ -947,7 +947,7 @@
<string name="autofill_district" msgid="6428712062213557327">"Districte"</string>
<string name="autofill_department" msgid="9047276226873531529">"Departament"</string>
<string name="autofill_prefecture" msgid="7267397763720241872">"Prefectura"</string>
- <string name="autofill_parish" msgid="6847960518334530198">"Districte"</string>
+ <string name="autofill_parish" msgid="6847960518334530198">"Parròquia"</string>
<string name="autofill_area" msgid="8289022370678448983">"Àrea"</string>
<string name="autofill_emirate" msgid="2544082046790551168">"Emirat"</string>
<string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"lectura dels marcadors i l\'historial web"</string>
@@ -988,8 +988,8 @@
<string name="searchview_description_submit" msgid="6771060386117334686">"Envia la consulta"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"Cerca per veu"</string>
<string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Vols activar l\'exploració tàctil?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interactuar amb la tauleta."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració per tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interactuar amb el telèfon."</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interaccionar amb la tauleta."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració per tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interaccionar amb el telèfon."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"Fa 1 mes"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Fa més d\'1 mes"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1219,9 +1219,9 @@
<string name="volume_music" msgid="7727274216734955095">"Volum de multimèdia"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"S\'està reproduint per Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"S\'ha establert el so de silenci"</string>
- <string name="volume_call" msgid="7625321655265747433">"Volum en trucada"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"Volum en trucada per Bluetooth"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Volum de l\'alarma"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Volum a la trucada"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"Volum a la trucada per Bluetooth"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Volum d\'alarma"</string>
<string name="volume_notification" msgid="6864412249031660057">"Volum de notificacions"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Volum"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Volum del Bluetooth"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 3ce57233cc09..fb893c9922ae 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1258,7 +1258,7 @@
<string name="volume_ringtone" msgid="134784084629229029">"Hlasitost vyzvánění"</string>
<string name="volume_music" msgid="7727274216734955095">"Hlasitost médií"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Přehrávání pomocí rozhraní Bluetooth"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Je nastaven tichý vyzváněcí tón"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Je nastaven tichý vyzvánění"</string>
<string name="volume_call" msgid="7625321655265747433">"Hlasitost hovoru"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Hlasitost příchozích hovorů při připojení Bluetooth"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Hlasitost budíku"</string>
@@ -1269,10 +1269,10 @@
<string name="volume_icon_description_incall" msgid="4491255105381227919">"Hlasitost hovoru"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"Hlasitost médií"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"Hlasitost oznámení"</string>
- <string name="ringtone_default" msgid="9118299121288174597">"Výchozí vyzváněcí tón"</string>
+ <string name="ringtone_default" msgid="9118299121288174597">"Výchozí vyzvánění"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Výchozí (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="397111123930141876">"Žádný"</string>
- <string name="ringtone_picker_title" msgid="667342618626068253">"Vyzváněcí tóny"</string>
+ <string name="ringtone_picker_title" msgid="667342618626068253">"Vyzvánění"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Zvuky budíku"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Zvuky upozornění"</string>
<string name="ringtone_unknown" msgid="5059495249862816475">"Neznámé"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index bd5a0d37dd85..eedf0d58dcf1 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -654,7 +654,7 @@
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"observer netværksforhold"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"skift kalibrering for inputenheden"</string>
- <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Tillader, at appen ændrer kalibreringsparametrene for berøringsskærmen. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Tillader, at appen ændrer kalibreringsparametrene for touchskærmen. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"få adgang til DRM-certifikater"</string>
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Tillader, at en applikation provisionerer og anvender DRM-certifikater. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"modtag status for Android Beam-overførsler"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index c4d944fe176b..c309749d27f2 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -325,7 +325,7 @@
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Legt die Zoom-Stufe und -Position auf dem Display fest."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Touch-Gesten möglich"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Tippen, Wischen, Zusammenziehen und andere Touch-Gesten möglich."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerabdrucksensor-Gesten"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gesten auf dem Fingerabdrucksensor"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Erfasst Touch-Gesten auf dem Fingerabdrucksensor des Geräts."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot erstellen"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Es kann ein Screenshot des Displays erstellt werden."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 4d3ca94b9c91..1cf59047aba9 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1120,8 +1120,8 @@
<string name="loading" msgid="3138021523725055037">"Loading…"</string>
<string name="capital_on" msgid="2770685323900821829">"ON"</string>
<string name="capital_off" msgid="7443704171014626777">"OFF"</string>
- <string name="checked" msgid="9179896827054513119">"ticked"</string>
- <string name="not_checked" msgid="7972320087569023342">"not ticked"</string>
+ <string name="checked" msgid="9179896827054513119">"checked"</string>
+ <string name="not_checked" msgid="7972320087569023342">"not checked"</string>
<string name="whichApplication" msgid="5432266899591255759">"Complete action using"</string>
<string name="whichApplicationNamed" msgid="6969946041713975681">"Complete action using %1$s"</string>
<string name="whichApplicationLabel" msgid="7852182961472531728">"Complete action"</string>
@@ -2023,7 +2023,7 @@
<string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> spreadsheet"</string>
<string name="mime_type_presentation" msgid="1145384236788242075">"Presentation"</string>
<string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> presentation"</string>
- <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth will stay on during aeroplane mode"</string>
+ <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth will stay on in Airplane mode"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Loading"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6439172d025c..38cbde6ef9c5 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -421,7 +421,7 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Esta app puede agregar, quitar o cambiar eventos del calendario en tu teléfono. Puede enviar mensajes que parecen proceder de propietarios del calendario o cambiar eventos sin notificarlos."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acceder a comandos adicionales del proveedor del lugar"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que la aplicación acceda a comandos adicionales del proveedor de ubicación. Esto puede permitirle a la aplicación interferir con el funcionamiento del GPS o de otras fuentes de ubicación."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder a la ubicación exacta solo en primer plano"</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder a la ubicación precisa solo en primer plano"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Mientras la usas, esta app puede obtener tu ubicación exacta mediante los Servicios de ubicación, siempre y cuando el dispositivo los tenga activados. Es posible que esto aumente el uso de batería."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acceder a la ubicación aproximada solo en primer plano"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Mientras la usas, esta app puede obtener tu ubicación aproximada mediante los Servicios de ubicación, siempre y cuando el dispositivo los tenga activados."</string>
@@ -1937,7 +1937,7 @@
<item quantity="one">Una sugerencia de Autocompletar</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"¿Quieres guardar en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_type" msgid="3002460014579799605">"¿Quieres guardar <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_type" msgid="3002460014579799605">"¿Quieres guardar la <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"¿Quieres guardar <xliff:g id="TYPE_0">%1$s</xliff:g> y <xliff:g id="TYPE_1">%2$s</xliff:g> en "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_3types" msgid="6598228952100102578">"¿Quieres guardar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <xliff:g id="TYPE_2">%3$s</xliff:g> en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_update_title" msgid="3630695947047069136">"¿Quieres actualizar en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
@@ -2044,7 +2044,7 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector del acceso directo de accesibilidad en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
<string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el depósito RESTRICTED"</string>
+ <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el bucket RESTRICTED"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"envió una imagen"</string>
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Conversación"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 5e245de3376e..d2a16e348b62 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -325,7 +325,7 @@
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Controla el posicionamiento y el nivel de zoom de la pantalla."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Realizar gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Puedes tocar y pellizcar la pantalla, deslizar el dedo y hacer otros gestos."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos de huellas digitales"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos de huella digital"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Puede capturar los gestos realizados en el sensor de huellas digitales del dispositivo."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Hacer captura"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede hacer capturas de la pantalla."</string>
@@ -1629,7 +1629,7 @@
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Al mantener pulsadas ambas teclas de volumen durante unos segundos se activa <xliff:g id="SERVICE">%1$s</xliff:g>, una función de accesibilidad. Esta función puede modificar el funcionamiento del dispositivo.\n\nPuedes asignar este acceso directo a otra función en Ajustes &gt; Accesibilidad."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Activar"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"No activar"</string>
- <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SÍ"</string>
+ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVADO"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NO"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"¿Permitir que <xliff:g id="SERVICE">%1$s</xliff:g> pueda controlar totalmente tu dispositivo?"</string>
<string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si activas <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositivo no utilizará el bloqueo de pantalla para mejorar el cifrado de datos."</string>
@@ -1770,7 +1770,7 @@
<item quantity="other">Vuelve a intentarlo en <xliff:g id="COUNT">%d</xliff:g> segundos</item>
<item quantity="one">Vuelve a intentarlo en 1 segundo</item>
</plurals>
- <string name="restr_pin_try_later" msgid="5897719962541636727">"Volver a intentar más tarde"</string>
+ <string name="restr_pin_try_later" msgid="5897719962541636727">"Reintentar más tarde"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Modo de pantalla completa"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo de arriba abajo."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 6b5741cb6913..d26bccda3647 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1216,7 +1216,7 @@
<string name="dump_heap_ready_text" msgid="5849618132123045516">"Protsessi <xliff:g id="PROC">%1$s</xliff:g> mälutõmmis on jagamiseks saadaval. Olge ettevaatlik: see mälutõmmis võib sisaldada tundlikke isiklikke andmeid, millele protsessil on juurdepääs. See võib hõlmata teie sisestatud teavet."</string>
<string name="sendText" msgid="493003724401350724">"Valige teksti jaoks toiming"</string>
<string name="volume_ringtone" msgid="134784084629229029">"Helina helitugevus"</string>
- <string name="volume_music" msgid="7727274216734955095">"Meediumi helitugevus"</string>
+ <string name="volume_music" msgid="7727274216734955095">"Meedia helitugevus"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Esitatakse Bluetoothi kaudu"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Valitud on hääletu märguanne"</string>
<string name="volume_call" msgid="7625321655265747433">"Kõne helitugevus"</string>
@@ -1227,7 +1227,7 @@
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetoothi maht"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"Helina tugevus"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"Kõne helitugevus"</string>
- <string name="volume_icon_description_media" msgid="4997633254078171233">"Meediumi helitugevus"</string>
+ <string name="volume_icon_description_media" msgid="4997633254078171233">"Meedia helitugevus"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"Teatise helitugevus"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Vaikehelin"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Vaikimisi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 8c8e89b886e4..5c763f456de3 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -482,8 +482,8 @@
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Telefonoaren ordu-zona aldatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_getAccounts" msgid="5304317160463582791">"bilatu gailuko kontuak"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Tabletak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dauzkazun aplikazioek sortutako kontuak har daitezke barnean."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Android TV gailuak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Kontu horien artean, instalatuta dituzun aplikazioek sortutako kontuak egon litezke."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Telefonoak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dituzun aplikazioek sortutako kontuak har daitezke barnean."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Android TV gailuak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Kontu horien artean, instalatuta dauzkazun aplikazioek sortutako kontuak egon litezke."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Telefonoak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dauzkazun aplikazioek sortutako kontuak har daitezke barnean."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"ikusi sareko konexioak"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Sareko konexioei buruzko informazioa ikusteko baimena ematen die aplikazioei; adibidez, zer sare dauden eta zeintzuk dauden konektatuta."</string>
<string name="permlab_createNetworkSockets" msgid="3224420491603590541">"izan sarerako sarbide osoa"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b5574aed8b6f..0903e00640aa 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -156,9 +156,9 @@
<string name="httpErrorOk" msgid="6206751415788256357">"تأیید"</string>
<string name="httpError" msgid="3406003584150566720">"خطایی در شبکه وجود داشت."</string>
<string name="httpErrorLookup" msgid="3099834738227549349">"نشانی اینترنتی پیدا نشد."</string>
- <string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"‏طرح کلی احراز هویت سایت پشتیبانی نمی‌‎شود."</string>
+ <string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"‏طرح کلی اصالت‌سنجی سایت پشتیبانی نمی‌‎شود."</string>
<string name="httpErrorAuth" msgid="469553140922938968">"راستی‌آزمایی ناموفق بود."</string>
- <string name="httpErrorProxyAuth" msgid="7229662162030113406">"احراز هویت از طریق سرور پروکسی انجام نشد."</string>
+ <string name="httpErrorProxyAuth" msgid="7229662162030113406">"اصالت‌سنجی از طریق سرور پروکسی انجام نشد."</string>
<string name="httpErrorConnect" msgid="3295081579893205617">"اتصال به سرور انجام نشد."</string>
<string name="httpErrorIO" msgid="3860318696166314490">"برقراری ارتباط با سرور ممکن نبود. بعداً دوباره امتحان کنید."</string>
<string name="httpErrorTimeout" msgid="7446272815190334204">"زمان اتصال به سرور تمام شده است."</string>
@@ -523,11 +523,11 @@
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"درخواست پیچیدگی قفل صفحه"</string>
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"به برنامه اجازه می‌دهد سطح پیچیدگی قفل صفحه (بالا، متوسط، پایین، یا هیچ‌کدام) را بیاموزد که نشان‌دهنده بازه ممکن طول و نوع قفل صفحه است. همچنین برنامه می‌تواند به کاربران پیشنهاد دهد قفل صفحه را به سطح خاصی به‌روزرسانی کنند، اما کاربران می‌توانند آزادانه این پیشنهاد را نادیده بگیرند و به سطح دیگری بروند. توجه داشته باشید که قفل صفحه در قالب نوشتار ساده ذخیره نمی‌شود، بنابراین برنامه گذرواژه دقیق را نمی‌داند."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"استفاده از سخت‌افزار بیومتریک"</string>
- <string name="permdesc_useBiometric" msgid="7502858732677143410">"به برنامه امکان می‌دهد از سخت‌افزار بیومتریک برای احراز هویت استفاده کند"</string>
+ <string name="permdesc_useBiometric" msgid="7502858732677143410">"به برنامه امکان می‌دهد از سخت‌افزار بیومتریک برای اصالت‌سنجی استفاده کند"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"مدیریت سخت‌افزار اثر انگشت"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"به برنامه امکان می‌دهد روش‌هایی را برای افزودن و حذف الگوهای اثر انگشت جهت استفاده، فعال کند."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"استفاده از سخت‌افزار اثر انگشت"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"به برنامه امکان می‌دهد از سخت‌افزار اثر انگشت برای احراز هویت استفاده کند"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"به برنامه امکان می‌دهد از سخت‌افزار اثر انگشت برای اصالت‌سنجی استفاده کند"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"تغییر مجموعه موسیقی شما"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"به برنامه اجازه می‌دهد مجموعه موسیقی‌تان را تغییر دهد."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"تغییر مجموعه ویدیوی شما"</string>
@@ -538,9 +538,9 @@
<string name="permdesc_mediaLocation" msgid="597912899423578138">"به برنامه اجازه می‌دهد مکان‌ها را از مجموعه رسانه‌تان بخواند."</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شما هستید"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"سخت‌افزار زیست‌سنجی دردسترس نیست"</string>
- <string name="biometric_error_user_canceled" msgid="6732303949695293730">"احراز هویت لغو شد"</string>
+ <string name="biometric_error_user_canceled" msgid="6732303949695293730">"اصالت‌سنجی لغو شد"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"شناسایی نشد"</string>
- <string name="biometric_error_canceled" msgid="8266582404844179778">"احراز هویت لغو شد"</string>
+ <string name="biometric_error_canceled" msgid="8266582404844179778">"اصالت‌سنجی لغو شد"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"پین، الگو یا گذرواژه‌ای تنظیم نشده است"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"بخشی از اثر انگشت شناسایی شد. لطفاً دوباره امتحان کنید."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string>
@@ -549,9 +549,9 @@
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"حرکت انگشت خیلی آهسته بود. لطفاً دوباره امتحان کنید."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت احراز هویت شد"</string>
- <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چهره احراز هویت شد"</string>
- <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره احراز هویت شد، لطفاً تأیید را فشار دهید"</string>
+ <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالت‌سنجی شد"</string>
+ <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چهره اصالت‌سنجی شد"</string>
+ <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالت‌سنجی شد، لطفاً تأیید را فشار دهید"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"سخت‌افزار اثرانگشت در دسترس نیست."</string>
<string name="fingerprint_error_no_space" msgid="6126456006769817485">"ذخیره اثر انگشت ممکن نیست. لطفاً یک اثر انگشت موجود را حذف کنید."</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"درنگ ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
@@ -570,7 +570,7 @@
<string name="permlab_manageFace" msgid="4569549381889283282">"مدیریت سخت‌افزار «بازگشایی با چهره»"</string>
<string name="permdesc_manageFace" msgid="6204569688492710471">"به برنامه امکان می‌دهد روش‌هایی را برای افزودن و حذف الگوهای چهره جهت استفاده فرابخواند."</string>
<string name="permlab_useFaceAuthentication" msgid="1011430526454859030">"استفاده از سخت‌افزار «بازگشایی با چهره»"</string>
- <string name="permdesc_useFaceAuthentication" msgid="3115697017684668012">"به برنامه امکان می‌دهد از سخت‌افزار «بازگشایی با چهره» برای احراز هویت استفاده کند"</string>
+ <string name="permdesc_useFaceAuthentication" msgid="3115697017684668012">"به برنامه امکان می‌دهد از سخت‌افزار «بازگشایی با چهره» برای اصالت‌سنجی استفاده کند"</string>
<string name="face_recalibrate_notification_name" msgid="6006095897989257026">"بازگشایی با چهره"</string>
<string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ثبت مجدد چهره"</string>
<string name="face_recalibrate_notification_content" msgid="892757485125249962">"برای بهبود تشخیص، لطفاً چهره‌تان را دوباره ثبت کنید"</string>
@@ -589,9 +589,9 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"لطفاً چهره‌تان را مجدداً ثبت کنید."</string>
<string name="face_acquired_too_different" msgid="4699657338753282542">"دیگر چهره را تشخیص نمی‌دهد. دوباره امتحان کنید."</string>
<string name="face_acquired_too_similar" msgid="7684650785108399370">"بسیار شبیه قبلی است، لطفاً قیافه دیگری بگیرید."</string>
- <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"سرتان را کمی پایین آورید."</string>
- <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"سرتان را کمی پایین آورید."</string>
- <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"سرتان را کمی پایین آورید."</string>
+ <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"سرتان را کمی صاف بگیرید."</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"سرتان را کمی صاف بگیرید."</string>
+ <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"سرتان را کمی صاف بگیرید."</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"هرچیزی را که حائل چهره‌تان است بردارید."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"بالای صفحه و همچنین نوار مشکی را تمیز کنید."</string>
<string-array name="face_acquired_vendor">
@@ -1264,7 +1264,7 @@
<string name="sms_control_title" msgid="4748684259903148341">"درحال ارسال پیامک‌ها"</string>
<string name="sms_control_message" msgid="6574313876316388239">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; درحال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
<string name="sms_control_yes" msgid="4858845109269524622">"مجاز است"</string>
- <string name="sms_control_no" msgid="4845717880040355570">"اجازه ندارد"</string>
+ <string name="sms_control_no" msgid="4845717880040355570">"مجاز نبودن"</string>
<string name="sms_short_code_confirm_message" msgid="1385416688897538724">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; مایل است پیامی به &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ارسال کند."</string>
<string name="sms_short_code_details" msgid="2723725738333388351">"این مورد "<b>"شاید هزینه‌ای"</b>" را به حساب دستگاه همراهتان بگذارد."</string>
<string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"این مورد هزینه‌ای را به حساب دستگاه همراهتان می‌گذارد."</b></string>
@@ -1410,7 +1410,7 @@
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"می‌خواهید به این درخواست اجازه دهید؟"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"درخواست دسترسی"</string>
<string name="allow" msgid="6195617008611933762">"ارزیابی‌شده"</string>
- <string name="deny" msgid="6632259981847676572">"اجازه ندارد"</string>
+ <string name="deny" msgid="6632259981847676572">"مجاز نبودن"</string>
<string name="permission_request_notification_title" msgid="1810025922441048273">"مجوز درخواست شد"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"مجوز\nبرای حساب <xliff:g id="ACCOUNT">%s</xliff:g> درخواست شد."</string>
<string name="forward_intent_to_owner" msgid="4620359037192871015">"شما از این برنامه در خارج از نمایه کاری‌تان استفاده می‌کنید"</string>
@@ -1639,7 +1639,7 @@
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"مشاهده و انجام کنش‌ها"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"این عملکرد می‌تواند با برنامه یا حسگری سخت‌افزاری تعاملاتتان را ردیابی کند و ازطرف شما با برنامه‌ها تعامل داشته باشد."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"مجاز"</string>
- <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"رد کردن"</string>
+ <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مجاز نبودن"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن ضربه بزنید:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"انتخاب ویژگی‌های موردنظر برای استفاده با دکمه دسترس‌پذیری"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"انتخاب ویژگی‌های موردنظر برای استفاده با میان‌بر کلید میزان صدا"</string>
@@ -1654,11 +1654,11 @@
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"برای استفاده از <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ویژگی را انتخاب کنید که هنگام ضربه زدن روی دکمه دسترس‌پذیری استفاده می‌شود:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ویژگی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند به بالا بکشید):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ویزگی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند به بالا بکشید):"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ویژگی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند به‌بالا بکشید):"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ویزگی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند به‌بالا بکشید):"</string>
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"برای جابه‌جایی بین ویژگی‌ها، دکمه دسترس‌پذیری را لمس کنید و نگه دارید."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"برای جابه‌جایی بین ویژگی‌ها، با دو انگشت صفحه را تند به بالا بکشید و نگه دارید."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"برای جابه‌جایی بین ویژگی‌ها، با سه انگشت صفحه را تند به بالا بکشید و نگه دارید."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"برای جابه‌جایی بین ویژگی‌ها، با دو انگشت صفحه را تند به‌بالا بکشید و نگه دارید."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"برای جابه‌جایی بین ویژگی‌ها، با سه انگشت صفحه را تند به‌بالا بکشید و نگه دارید."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"درشت‌نمایی"</string>
<string name="user_switched" msgid="7249833311585228097">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index bba11bcd4245..2294a6979d57 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -302,7 +302,7 @@
<string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string>
<string name="permgrouplab_storage" msgid="1938416135375282333">"Tiedostot ja media"</string>
- <string name="permgroupdesc_storage" msgid="6351503740613026600">"käyttää laitteellesi tallennettuja valokuvia, mediatiedostoja ja muita tiedostoja"</string>
+ <string name="permgroupdesc_storage" msgid="6351503740613026600">"käyttää laitteellesi tallennettuja kuvia, mediatiedostoja ja muita tiedostoja"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa ääntä"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Liikkuminen"</string>
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Hei Google).\n\n"<annotation id="url">"Lue lisää"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Hei Google)."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. OK Google).\n\n"<annotation id="url">"Lue lisää"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"Parantaakseen akunkestoa Virransäästö\n\n•·laittaa tumman teeman päälle\n•·laittaa pois päältä tai rajoittaa taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. OK Google)."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Data Saver estää joitakin sovelluksia lähettämästä tai vastaanottamasta tietoja taustalla, jotta datan käyttöä voidaan vähentää. Käytössäsi oleva sovellus voi yhä käyttää dataa, mutta se saattaa tehdä niin tavallista harvemmin. Tämä voi tarkoittaa esimerkiksi sitä, että kuva ladataan vasta, kun kosketat sitä."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Otetaanko Data Saver käyttöön?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ota käyttöön"</string>
@@ -1914,7 +1914,7 @@
<string name="app_category_game" msgid="4534216074910244790">"Pelit"</string>
<string name="app_category_audio" msgid="8296029904794676222">"Musiikki ja ääni"</string>
<string name="app_category_video" msgid="2590183854839565814">"Elokuvat ja videot"</string>
- <string name="app_category_image" msgid="7307840291864213007">"Kuvat ja valokuvat"</string>
+ <string name="app_category_image" msgid="7307840291864213007">"Kuvat ja kuvat"</string>
<string name="app_category_social" msgid="2278269325488344054">"Some ja viestintä"</string>
<string name="app_category_news" msgid="1172762719574964544">"Uutiset ja lehdet"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartat ja navigointi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2b42c12a9fea..9d6105f25802 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -52,6 +52,7 @@
<string name="enablePin" msgid="2543771964137091212">"Opération infructueuse. Activez le verrouillage SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM soit verrouillée.</item>
+ <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
<item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM soit verrouillée.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"Code IIEM"</string>
@@ -179,6 +180,7 @@
<string name="low_memory" product="default" msgid="2539532364144025569">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="one">Autorité de certification installée</item>
+ <item quantity="many">Certificate authorities installed</item>
<item quantity="other">Autorités de certification installées</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Par un tiers inconnu"</string>
@@ -251,6 +253,7 @@
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilisez cette option pour qu\'il y ait le moins d\'interférences système possible lorsque votre appareil ne répond pas ou qu\'il est trop lent, ou lorsque vous avez besoin de toutes les sections du rapport de bogue. Aucune capture d\'écran supplémentaire ne peut être capturée, et vous ne pouvez entrer aucune autre information."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
<item quantity="one">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde.</item>
+ <item quantity="many">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
<item quantity="other">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes.</item>
</plurals>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Capture d\'écran prise avec le rapport de bogue"</string>
@@ -683,9 +686,9 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Verrouiller l\'écran"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Gérer le mode et les conditions de verrouillage de l\'écran"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Effacer toutes les données"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Effacer les données de la tablette sans avertissement, en rétablissant la configuration d\'usine"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Effacer les données de la tablette sans avertissement, en rétablissant les paramètres par défaut"</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Effacez les données de votre appareil Android TV sans avertissement en effectuant une réinitialisation des paramètres d\'usine."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Effacer les données du téléphone sans avertissement, en rétablissant la configuration d\'usine"</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Effacer les données du téléphone sans avertissement en rétablissant les paramètres par défaut"</string>
<string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"Effacer les données de l\'utilisateur"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Effacer les données de l\'utilisateur sur cette tablette sans avertissement."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Effacez les données de cet utilisateur sur cet appareil Android TV sans avertissement."</string>
@@ -863,12 +866,12 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Vous avez dessiné votre schéma de déverrouillage incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), vous devrez déverrouiller votre appareil Android TV en vous connectant à votre compte Google.\n\n Réessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), votre appareil Android TV sera réinitialisé à ses valeurs d\'usine et toutes les données personnelles seront supprimées."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER">%d</xliff:g> reprise(s). Votre appareil Android TV sera maintenant réinitialisé à ses valeurs d\'usine."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Veuillez réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Schéma oublié?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Déverrouillage du compte"</string>
@@ -994,6 +997,7 @@
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Il y a plus d\'un mois"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
<item quantity="one">Le dernier <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">Le dernier <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<string name="last_month" msgid="1528906781083518683">"Le mois dernier"</string>
@@ -1016,66 +1020,82 @@
<string name="now_string_shortest" msgid="3684914126941650330">"maintenant"</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest" formatted="false" msgid="8299112348723640338">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest_future" formatted="false" msgid="814754627092787227">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest_future" formatted="false" msgid="7683731800140202145">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
<item quantity="one">il y a<xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
<item quantity="other">il y a<xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative" formatted="false" msgid="2179998228861172159">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<plurals name="duration_minutes_relative_future" formatted="false" msgid="5759885720917567723">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative_future" formatted="false" msgid="8963511608507707959">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative_future" formatted="false" msgid="1964709470979250702">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problème vidéo"</string>
@@ -1446,6 +1466,7 @@
<string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
<plurals name="matches_found" formatted="false" msgid="1101758718194295554">
<item quantity="one"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
+ <item quantity="many"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
</plurals>
<string name="action_mode_done" msgid="2536182504764803222">"Terminé"</string>
@@ -1582,6 +1603,7 @@
<string name="kg_wrong_pin" msgid="3680925703673166482">"NIP incorrect."</string>
<plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
<item quantity="one">Réessayer dans <xliff:g id="NUMBER">%d</xliff:g> seconde.</item>
+ <item quantity="many">Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds.</item>
<item quantity="other">Réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes.</item>
</plurals>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Dessinez votre schéma."</string>
@@ -1608,12 +1630,12 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), votre appareil Android TV sera réinitialisé à ses valeurs d\'usine et toutes les données personnelles seront supprimées."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ses paramètres par défaut seront rétablis, et toutes les données d\'utilisateur seront perdues."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Vous avez tenté de déverrouiller votre appareil Android TV incorrectement à <xliff:g id="NUMBER">%d</xliff:g> reprise(s). Votre appareil Android TV sera maintenant réinitialisé à ses valeurs d\'usine."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ses paramètres par défaut vont être rétablis."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Vous avez dessiné votre schéma de déverrouillage incorrectement à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprise(s). Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autre(s) tentative(s) incorrecte(s), vous devrez déverrouiller votre appareil Android TV à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
@@ -1768,6 +1790,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le NIP est trop court. Il doit comporter au moins 4 chiffres."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="one">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> seconde</item>
+ <item quantity="many">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="other">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> secondes</item>
</plurals>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Réessayez plus tard"</string>
@@ -1799,34 +1822,42 @@
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
<item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312">
<item quantity="one">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
<item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
<item quantity="one">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="1148568456958944998">
<item quantity="one">Pendant %d minute</item>
+ <item quantity="many">For %d minutes</item>
<item quantity="other">Pendant %d minutes</item>
</plurals>
<plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859">
<item quantity="one">Pendant %d min</item>
+ <item quantity="many">For %d min</item>
<item quantity="other">Pendant %d min</item>
</plurals>
<plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
<item quantity="one">Pendant %d heure</item>
+ <item quantity="many">For %d hours</item>
<item quantity="other">Pendant %d heures</item>
</plurals>
<plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
<item quantity="one">Pendant %d h</item>
+ <item quantity="many">For %d hr</item>
<item quantity="other">Pendant %d h</item>
</plurals>
<string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1842,7 +1873,7 @@
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Événement"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sommeil"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string>
- <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à sa configuration d\'usine."</string>
+ <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string>
<string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"La demande USSD a été remplacée par une demande d\'appel régulier"</string>
<string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"La demande USSD a été remplacée par une demande SS"</string>
@@ -1867,6 +1898,7 @@
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
</plurals>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
@@ -1934,6 +1966,7 @@
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Aucune suggestion de remplissage automatique"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
<item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> suggestion de remplissage automatique</item>
+ <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de remplissage automatique</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer sous "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
@@ -2027,6 +2060,7 @@
<string name="car_loading_profile" msgid="8219978381196748070">"Chargement en cours…"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item>
+ <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item>
</plurals>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1032da246d89..6441b04dcb74 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -52,6 +52,7 @@
<string name="enablePin" msgid="2543771964137091212">"Échec de l\'opération. Veuillez activer le verrouillage de la carte SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne soit verrouillée.</item>
+ <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
<item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne soit verrouillée.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"Code IMEI"</string>
@@ -179,6 +180,7 @@
<string name="low_memory" product="default" msgid="2539532364144025569">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="one">Autorité de certification installée</item>
+ <item quantity="many">Certificate authorities installed</item>
<item quantity="other">Autorités de certification installées</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Par un tiers inconnu"</string>
@@ -251,6 +253,7 @@
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilisez cette option pour qu\'il y ait le moins d\'interférences système possible lorsque votre appareil ne répond pas ou qu\'il est trop lent, ou lorsque vous avez besoin de toutes les sections du rapport de bug. Aucune capture d\'écran supplémentaire ne peut être prise, et vous ne pouvez saisir aucune autre information."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
<item quantity="one">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde</item>
+ <item quantity="many">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
<item quantity="other">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes</item>
</plurals>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Capture d\'écran avec rapport de bug effectuée"</string>
@@ -325,7 +328,7 @@
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Contrôle le niveau de zoom et le positionnement de l\'écran."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Effectuer des gestes"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Permet d\'appuyer sur l\'écran, de le balayer, de le pincer et d\'effectuer d\'autres gestes."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestes avec l\'empreinte digitale"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestes d\'empreinte digitale"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut enregistrer des gestes effectués sur le lecteur d\'empreinte digitale de l\'appareil."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Prendre une capture d\'écran"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Peut prendre des captures d\'écran."</string>
@@ -994,6 +997,7 @@
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Il y a plus d\'un mois"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
<item quantity="one">Le dernier jour (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="many">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">Les <xliff:g id="COUNT_1">%d</xliff:g> derniers jours</item>
</plurals>
<string name="last_month" msgid="1528906781083518683">"Le mois dernier"</string>
@@ -1016,66 +1020,82 @@
<string name="now_string_shortest" msgid="3684914126941650330">"mainten."</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest" formatted="false" msgid="8299112348723640338">
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest_future" formatted="false" msgid="814754627092787227">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
</plurals>
<plurals name="duration_years_shortest_future" formatted="false" msgid="7683731800140202145">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative" formatted="false" msgid="2179998228861172159">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
<item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<plurals name="duration_minutes_relative_future" formatted="false" msgid="5759885720917567723">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative_future" formatted="false" msgid="8963511608507707959">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
</plurals>
<plurals name="duration_days_relative_future" formatted="false" msgid="1964709470979250702">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
</plurals>
<plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
</plurals>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problème vidéo"</string>
@@ -1231,7 +1251,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Volume des notifications"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Sonnerie par défaut"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Aucun(e)"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Aucun"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Sonneries"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Sons de l\'alarme"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Sons de notification"</string>
@@ -1446,6 +1466,7 @@
<string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
<plurals name="matches_found" formatted="false" msgid="1101758718194295554">
<item quantity="one"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
+ <item quantity="many"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
</plurals>
<string name="action_mode_done" msgid="2536182504764803222">"OK"</string>
@@ -1582,6 +1603,7 @@
<string name="kg_wrong_pin" msgid="3680925703673166482">"Code PIN incorrect."</string>
<plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
<item quantity="one">Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> seconde.</item>
+ <item quantity="many">Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds.</item>
<item quantity="other">Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes.</item>
</plurals>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Dessinez votre schéma."</string>
@@ -1768,6 +1790,7 @@
<string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="one">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> seconde</item>
+ <item quantity="many">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="other">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> secondes</item>
</plurals>
<string name="restr_pin_try_later" msgid="5897719962541636727">"Veuillez réessayer ultérieurement."</string>
@@ -1799,34 +1822,42 @@
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
<item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312">
<item quantity="one">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
<item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
<item quantity="one">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="many">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="1148568456958944998">
<item quantity="one">Pendant %d minute</item>
+ <item quantity="many">For %d minutes</item>
<item quantity="other">Pendant %d minutes</item>
</plurals>
<plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859">
<item quantity="one">Pendant %d min</item>
+ <item quantity="many">For %d min</item>
<item quantity="other">Pendant %d min</item>
</plurals>
<plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
<item quantity="one">Pendant %d heure</item>
+ <item quantity="many">For %d hours</item>
<item quantity="other">Pendant %d heures</item>
</plurals>
<plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
<item quantity="one">Pendant %d h</item>
+ <item quantity="many">For %d hr</item>
<item quantity="other">Pendant %d h</item>
</plurals>
<string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1867,6 +1898,7 @@
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
</plurals>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
@@ -1934,6 +1966,7 @@
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Aucune suggestion de saisie automatique"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
<item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> suggestion de saisie automatique</item>
+ <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de saisie automatique</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer dans "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ?"</string>
@@ -2027,6 +2060,7 @@
<string name="car_loading_profile" msgid="8219978381196748070">"Chargement…"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item>
+ <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item>
</plurals>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 1732d0846961..b3259e52c20f 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -849,7 +849,7 @@
<string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pausar"</string>
<string name="lockscreen_transport_play_description" msgid="106868788691652733">"Reproducir"</string>
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Deter"</string>
- <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Rebobinar"</string>
+ <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Retroceder"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Avance rápido"</string>
<string name="emergency_calls_only" msgid="3057351206678279851">"Só chamadas de emerxencia"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Bloqueada pola rede"</string>
@@ -1587,7 +1587,7 @@
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Debuxa o teu padrón"</string>
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Introduce o PIN da tarxeta SIM"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"Introduce o PIN"</string>
- <string name="kg_password_instructions" msgid="7179782578809398050">"Insire o teu contrasinal"</string>
+ <string name="kg_password_instructions" msgid="7179782578809398050">"Escribe o teu contrasinal"</string>
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"Agora a tarxeta SIM está desactivada. Introduce o código PUK para continuar. Ponte en contacto co operador para obter información detallada."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Introduce o código PIN desexado"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirma o código PIN desexado"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index e559fe14cef9..c81f90ca91bf 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -189,7 +189,7 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"પાસવર્ડના ઘણા વધુ પ્રયત્નો"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"વ્યવસ્થાપકે ડિવાઇસ વ્યક્તિગત ઉપયોગ માટે આપી દીધું છે"</string>
- <string name="network_logging_notification_title" msgid="554983187553845004">"ઉપકરણ સંચાલિત છે"</string>
+ <string name="network_logging_notification_title" msgid="554983187553845004">"ડિવાઇસ મેનેજ થયેલ છે"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ઍપ તમારા સ્થાનને ઍક્સેસ કરી શકે છે"</string>
<string name="location_changed_notification_text" msgid="7158423339982706912">"વધુ જાણવા માટે તમારા IT વ્યવસ્થાપકનો સંપર્ક કરો"</string>
@@ -312,7 +312,7 @@
<string name="permgrouplab_calllog" msgid="7926834372073550288">"કૉલ લૉગ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ફોન કૉલ લૉગ વાંચો અને લખો"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ફોન"</string>
- <string name="permgroupdesc_phone" msgid="270048070781478204">"ફોન કૉલ કરો અને સંચાલિત કરો"</string>
+ <string name="permgroupdesc_phone" msgid="270048070781478204">"ફોન કૉલ કરો અને મેનેજ કરો"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"બૉડી સેન્સર"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"વિંડો કન્ટેન્ટ પુનઃપ્રાપ્ત કરો"</string>
@@ -363,7 +363,7 @@
<string name="permdesc_receiveWapPush" msgid="1638677888301778457">"એપ્લિકેશનને WAP સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આ પરવાનગીમાં તમને દર્શાવ્યા વિના તમને મોકલેલ સંદેશાઓનું નિરીક્ષણ કરવાની અને કાઢી નાખવાની ક્ષમતાનો સમાવેશ થાય છે."</string>
<string name="permlab_getTasks" msgid="7460048811831750262">"ચાલુ ઍપ્લિકેશનો પુનઃપ્રાપ્ત કરો"</string>
<string name="permdesc_getTasks" msgid="7388138607018233726">"એપ્લિકેશનને વર્તમાનમાં અને તાજેતરમાં ચાલી રહેલ Tasks વિશેની વિગતવાર માહિતી પુનઃપ્રાપ્ત કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને ઉપકરણ પર કઈ એપ્લિકેશન્સનો ઉપયોગ થાય છે તેના વિશેની માહિતી શોધવાની મંજૂરી આપી શકે છે."</string>
- <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"પ્રોફાઇલ અને ઉપકરણ માલિકોને સંચાલિત કરો"</string>
+ <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"પ્રોફાઇલ અને ડિવાઇસ માલિકોને મેનેજ કરો"</string>
<string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"એપ્લિકેશન્સને પ્રોફાઇલ માલિકો અને ઉપકરણ માલિકો સેટ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_reorderTasks" msgid="7598562301992923804">"ચાલુ એપ્લિકેશન્સને ફરી ગોઠવો"</string>
<string name="permdesc_reorderTasks" msgid="8796089937352344183">"ઍપ્લિકેશનને અગ્રભૂમિ અને પૃષ્ટભૂમિમાં Tasks ખસેડવાની મંજૂરી આપે છે. તમારા ઇનપુટ વિના ઍપ્લિકેશન આ કરી શકે છે."</string>
@@ -524,7 +524,7 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ઍપને સ્ક્રીન લૉકની જટિલતાનું લેવલ (ઊંચું, મધ્યમ, નીચું અથવા કોઈ નહીં) જાણવાની મંજૂરી આપે છે, જે સ્ક્રીન લૉકના પ્રકાર અને લંબાઈની સંભવિત શ્રેણી સૂચવે છે. ઍપ વપરાશકર્તાઓને સ્ક્રીન લૉકને ચોક્કસ લેવલ સુધી અપડેટ કરવાનું સૂચન પણ કરી શકે છે, પરંતુ વપરાશકર્તાઓ મુક્ત રીતે અવગણીને નૅવિગેટ કરી શકે છે. નોંધી લો કે સ્ક્રીન લૉકનો plaintextમાં સંગ્રહ કરવામાં આવતો નથી, તેથી ઍપને ચોક્કસ પાસવર્ડની જાણ હોતી નથી."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
- <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string>
+ <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ફિંગરપ્રિન્ટ હાર્ડવેરને મેનેજ કરો"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"ઍપને ઉપયોગ માટે ફિંગરપ્રિન્ટ નમૂના ઉમેરવા અને કાઢી નાખવા માટે પદ્ધતિઓની વિનંતી કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરો"</string>
<string name="permdesc_useFingerprint" msgid="412463055059323742">"ઍપને પ્રમાણીકરણ માટે ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
@@ -627,8 +627,8 @@
<string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"એપ્લિકેશનને નવા ટેલિકોમ સિમ કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"નવા ટેલિકોમ કનેક્શન્સની નોંધણી કરો"</string>
<string name="permdesc_register_call_provider" msgid="4201429251459068613">"એપ્લિકેશનને નવા ટેલિકોમ કનેક્શન્સની નોંધણી કરવાની મંજૂરી આપે છે."</string>
- <string name="permlab_connection_manager" msgid="3179365584691166915">"ટેલિકોમ કનેક્શન્સ સંચાલિત કરો"</string>
- <string name="permdesc_connection_manager" msgid="1426093604238937733">"એપ્લિકેશનને ટેલીકોમ કનેક્શન્સને સંચાલિત કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_connection_manager" msgid="3179365584691166915">"ટેલિકોમ કનેક્શનને મેનેજ કરો"</string>
+ <string name="permdesc_connection_manager" msgid="1426093604238937733">"ઍપને ટેલિકોમ કનેક્શનને મેનેજ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_bind_incall_service" msgid="5990625112603493016">"ઇન-કૉલ સ્ક્રીન વડે ક્રિયાપ્રતિક્રિયા કરો"</string>
<string name="permdesc_bind_incall_service" msgid="4124917526967765162">"વપરાશકર્તા ઇન-કૉલ સ્ર્કીન ક્યારે અને કેવી રીતે જુએ છે તે નિયંત્રિત કરવાની એપ્લિકેશનને મંજૂરી આપે છે."</string>
<string name="permlab_bind_connection_service" msgid="5409268245525024736">"ટેલિફોની સેવાઓ સાથે વાર્તાલાપ કરો"</string>
@@ -637,8 +637,8 @@
<string name="permdesc_control_incall_experience" msgid="5896723643771737534">"એપ્લિકેશનને કૉલમાં વપરાશકર્તા અનુભવ પ્રદાન કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"ઐતિહાસિક નેટવર્ક ઉપયોગ વાંચો"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"એપ્લિકેશનને ચોક્કસ નેટવર્ક્સ અને ઍપ્લિકેશનો માટે ઐતિહાસિક નેટવર્ક વપરાશ વાંચવાની મંજૂરી આપે છે."</string>
- <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"નેટવર્ક નીતિ સંચાલિત કરો"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"ઍપ્લિકેશનને નેટવર્ક નીતિઓ સંચાલિત કરવાની અને ઍપ્લિકેશન-વિશિષ્ટ નિયમો નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"નેટવર્ક નીતિ મેનેજ કરો"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"ઍપને નેટવર્ક નીતિઓ મેનેજ કરવાની અને ઍપ-વિશિષ્ટ નિયમો નિર્ધારિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"નેટવર્ક વપરાશ એકાઉન્ટિંગ સંશોધિત કરો"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"એપ્લિકેશનને કેવી રીતે ઍપ્લિકેશનો સામે નેટવર્ક વપરાશ ગણવામાં આવે છે તે સંશોધિત કરવાની મંજૂરી આપે છે. સામાન્ય ઍપ્લિકેશનો દ્વારા ઉપયોગમાં લેવા માટે નથી."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"ઍક્સેસ સૂચનાઓ"</string>
@@ -933,7 +933,7 @@
<string name="double_tap_toast" msgid="7065519579174882778">"ટિપ: ઝૂમ વધારવા અને ઘટાડવા માટે બે વાર ટેપ કરો."</string>
<string name="autofill_this_form" msgid="3187132440451621492">"સ્વતઃભરણ"</string>
<string name="setup_autofill" msgid="5431369130866618567">"સ્વતઃભરણ સેટ કરો"</string>
- <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> સાથે આપમેળે ભરો"</string>
+ <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> સાથે ઑટોમૅટિક રીતે ભરો"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
<string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="760522655085707045">", "</string>
@@ -982,7 +982,7 @@
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ડિલીટ કરો"</string>
<string name="search_go" msgid="2141477624421347086">"શોધો"</string>
<string name="search_hint" msgid="455364685740251925">"શોધો…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"શોધ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"શોધો"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"શોધ ક્વેરી"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ક્વેરી સાફ કરો"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ક્વેરી સબમિટ કરો"</string>
@@ -1135,7 +1135,7 @@
<string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"ઍક્સેસ આપો"</string>
<string name="whichEditApplication" msgid="6191568491456092812">"આનાથી સંપાદિત કરો"</string>
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$s સાથે સંપાદિત કરો"</string>
- <string name="whichEditApplicationLabel" msgid="1463288652070140285">"સંપાદિત કરો"</string>
+ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ફેરફાર કરો"</string>
<string name="whichSendApplication" msgid="4143847974460792029">"શેર કરો"</string>
<string name="whichSendApplicationNamed" msgid="4470386782693183461">"%1$s સાથે શેર કરો"</string>
<string name="whichSendApplicationLabel" msgid="7467813004769188515">"શેર કરો"</string>
@@ -1221,7 +1221,7 @@
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"સાઇલેન્ટ રિંગટોન સેટ કરી"</string>
<string name="volume_call" msgid="7625321655265747433">"ઇન-કૉલ વૉલ્યૂમ"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"બ્લૂટૂથ ઇન-કૉલ વૉલ્યૂમ"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"એલાર્મ વૉલ્યૂમ"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"અલાર્મ વૉલ્યૂમ"</string>
<string name="volume_notification" msgid="6864412249031660057">"સૂચના વૉલ્યૂમ"</string>
<string name="volume_unknown" msgid="4041914008166576293">"વૉલ્યૂમ"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"બ્લૂટૂથ વૉલ્યૂમ"</string>
@@ -1426,8 +1426,8 @@
<string name="notification_ranker_binding_label" msgid="432708245635563763">"સૂચના રેંકર સેવા"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN સક્રિય કર્યું"</string>
<string name="vpn_title_long" msgid="6834144390504619998">"<xliff:g id="APP">%s</xliff:g> દ્વારા VPN સક્રિય થયું"</string>
- <string name="vpn_text" msgid="2275388920267251078">"નેટવર્કને સંચાલિત કરવા માટે ટૅપ કરો."</string>
- <string name="vpn_text_long" msgid="278540576806169831">"<xliff:g id="SESSION">%s</xliff:g> થી કનેક્ટ થયાં. નેટવર્કને સંચાલિત કરવા માટે ટૅપ કરો."</string>
+ <string name="vpn_text" msgid="2275388920267251078">"નેટવર્કને મેનેજ કરવા માટે ટૅપ કરો."</string>
+ <string name="vpn_text_long" msgid="278540576806169831">"<xliff:g id="SESSION">%s</xliff:g> થી કનેક્ટ થયાં. નેટવર્કને મેનેજ કરવા માટે ટૅપ કરો."</string>
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"હંમેશા-ચાલુ VPN કનેક્ટ થઈ રહ્યું છે…"</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"હંમેશા-ચાલુ VPN કનેક્ટ થયું"</string>
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"હંમેશાં-ચાલુ VPN થી ડિસ્કનેક્ટ થયું"</string>
@@ -1513,7 +1513,7 @@
<string name="storage_usb_drive" msgid="448030813201444573">"USB ડ્રાઇવ"</string>
<string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ડ્રાઇવ"</string>
<string name="storage_usb" msgid="2391213347883616886">"USB સ્ટોરેજ"</string>
- <string name="extract_edit_menu_button" msgid="63954536535863040">"સંપાદિત કરો"</string>
+ <string name="extract_edit_menu_button" msgid="63954536535863040">"ફેરફાર કરો"</string>
<string name="data_usage_warning_title" msgid="9034893717078325845">"ડેટા ચેતવણી"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"તમે <xliff:g id="APP">%s</xliff:g> ડેટા વાપર્યો છે"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"મોબાઇલ ડેટાની મર્યાદા આવી ગઈ"</string>
@@ -1904,7 +1904,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g>ને પિન કરો"</string>
<string name="unpin_target" msgid="3963318576590204447">"અનપિન કરો"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g>ને અનપિન કરો"</string>
- <string name="app_info" msgid="6113278084877079851">"ઍપ્લિકેશન માહિતી"</string>
+ <string name="app_info" msgid="6113278084877079851">"ઍપની માહિતી"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ડેમો પ્રારંભ કરી રહ્યાં છે…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"ઉપકરણ ફરીથી સેટ કરી રહ્યાં છે…"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6b442137da18..a2b04e33b0cd 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -307,7 +307,7 @@
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"hanganyag rögzítése"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Testmozgás"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"hozzáférés a testmozgási adatokhoz"</string>
- <string name="permgrouplab_camera" msgid="9090413408963547706">"Fényképezőgép"</string>
+ <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotók és videók készítése"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Hívásnaplók"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"hívásnapló olvasása és írása"</string>
@@ -1900,8 +1900,8 @@
<string name="profile_encrypted_message" msgid="1128512616293157802">"A feloldáshoz koppintson rá"</string>
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Csatlakoztatva a(z) <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> eszközhöz"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Koppintson ide a fájlok megtekintéséhez"</string>
- <string name="pin_target" msgid="8036028973110156895">"Rögzítés"</string>
- <string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> rögzítése"</string>
+ <string name="pin_target" msgid="8036028973110156895">"Kitűzés"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> kitűzése"</string>
<string name="unpin_target" msgid="3963318576590204447">"Feloldás"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> rögzítésének feloldása"</string>
<string name="app_info" msgid="6113278084877079851">"Alkalmazásinformáció"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 6f676fd7af80..4ae96f6b9932 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -48,7 +48,7 @@
<string name="invalidPin" msgid="7542498253319440408">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string>
<string name="invalidPuk" msgid="8831151490931907083">"Մուտքագրեք PUK, որն 8 կամ ավել թիվ ունի:"</string>
<string name="needPuk" msgid="7321876090152422918">"Ձեր SIM քարտը PUK-ով կողպված է: Մուտքագրեք PUK կոդը այն ապակողպելու համար:"</string>
- <string name="needPuk2" msgid="7032612093451537186">"Մուտքագրեք PUK2-ը` SIM քարտն արգելահանելու համար:"</string>
+ <string name="needPuk2" msgid="7032612093451537186">"Մուտքագրեք PUK2-ը՝ SIM քարտն արգելահանելու համար:"</string>
<string name="enablePin" msgid="2543771964137091212">"Ձախողվեց: Միացրեք SIM/RUIM կողպումը:"</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="one">Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն արգելափակվելու է:</item>
@@ -409,7 +409,7 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Թույլ է տալիս հավելվածին փոփոխել ձեր պլանշետի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Թույլ է տալիս հավելվածին փոփոխել Android TV սարքի զանգերի մատյանը, այդ թվում՝ մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել՝ ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Թույլ է տալիս հավելվածին փոփոխել ձեր հեռախոսի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"օգտագործել մարմնի սենսորները (օրինակ` սրտի կծկումների հաճախականության չափիչ)"</string>
+ <string name="permlab_bodySensors" msgid="3411035315357380862">"օգտագործել մարմնի սենսորները (օրինակ՝ սրտի կծկումների հաճախականության չափիչ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"Հավելվածին թույլ է տալիս մուտք ունենալ սենսորների տվյալներին, որոնք վերահսկում են ձեր ֆիզիկական վիճակը, օրինակ՝ ձեր սրտի զարկերը:"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Կարդալ օրացույցի միջոցառումները և տվյալները"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր պլանշետում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string>
@@ -428,7 +428,7 @@
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"տեղադրության մասին տվյալների հասանելիություն ֆոնային ռեժիմում"</string>
<string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Այս հավելվածը ցանկացած ժամանակ կարող է տեսնել տեղադրության տվյալները, նույնիսկ երբ այն ակտիվ չէ։"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"փոխել ձեր աուդիո կարգավորումները"</string>
- <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Թույլ է տալիս հավելվածին փոփոխել ձայնանյութի գլոբալ կարգավորումները, ինչպես օրինակ` ձայնը և թե որ խոսափողն է օգտագործված արտածման համար:"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Թույլ է տալիս հավելվածին փոփոխել ձայնանյութի գլոբալ կարգավորումները, ինչպես օրինակ՝ ձայնը և թե որ խոսափողն է օգտագործված արտածման համար:"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ձայնագրել աուդիո ֆայլ"</string>
<string name="permdesc_recordAudio" msgid="3976213377904701093">"Այս հավելվածը ցանկացած պահի կարող է ձայնագրել խոսափողի օգնությամբ:"</string>
<string name="permlab_sim_communication" msgid="176788115994050692">"ուղարկել հրամաններ SIM քարտին"</string>
@@ -493,7 +493,7 @@
<string name="permlab_changeTetherState" msgid="9079611809931863861">"փոխել միացված կապը"</string>
<string name="permdesc_changeTetherState" msgid="3025129606422533085">"Թույլ է տալիս հավելվածին փոխել կապված ցանցի միացման կարգավիճակը:"</string>
<string name="permlab_accessWifiState" msgid="5552488500317911052">"դիտել Wi-Fi կապերը"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Թույլ է տալիս հավելվածին տեսնել Wi-Fi ցանցի տեղեկություններ, ինչպես օրինակ` արդյոք Wi-Fi-ը միացված է, թե` ոչ, և միացված Wi-Fi սարքի անունը:"</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Թույլ է տալիս հավելվածին տեսնել Wi-Fi ցանցի տեղեկություններ, ինչպես օրինակ՝ արդյոք Wi-Fi-ը միացված է, թե` ոչ, և միացված Wi-Fi սարքի անունը:"</string>
<string name="permlab_changeWifiState" msgid="7947824109713181554">"միանալ Wi-Fi-ին և անջատվել դրանից"</string>
<string name="permdesc_changeWifiState" msgid="7170350070554505384">"Թույլ է տալիս հավելվածին միանալ Wi-Fi մուտքի կետերին և անջատվել այդ կետերից, ինչպես նաև կատարել սարքի կարգավորման փոփոխություններ Wi-Fi ցանցերի համար:"</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"թույլատրել Բազմասփյուռ Wi-Fi-ի ընդունումը"</string>
@@ -612,7 +612,7 @@
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Դեմքի պատկերակ"</string>
<string name="permlab_readSyncSettings" msgid="6250532864893156277">"կարդալ համաժամացման կարգավորումները"</string>
- <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Թույլ է տալիս հավելվածին կարդալ համաժամացման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամացված է հաշվի հետ:"</string>
+ <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Թույլ է տալիս հավելվածին կարդալ համաժամացման կարգավորումները հաշվի համար: Օրինակ՝ այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամացված է հաշվի հետ:"</string>
<string name="permlab_writeSyncSettings" msgid="6583154300780427399">"համաժամացումը փոխարկել միացվածի և անջատվածի"</string>
<string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Թույլ է տալիս հավելվածին փոփոխել համաժամացման կարգավորումները հաշվի համար: Օրինակ, այն կարող է օգտագործվել` միացնելու Մարդիկ հավելվածի համաժամացումը հաշվի հետ:"</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"կարդալ համաժամացման վիճակագրությունը"</string>
@@ -873,7 +873,7 @@
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Մոռացե՞լ եք սխեման:"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Հաշվի ապակողպում"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Չափից շատ սխեմայի փորձեր"</string>
- <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Ապակողպելու համար` մուտք գործեք ձեր Google հաշվով:"</string>
+ <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Ապակողպելու համար՝ մուտք գործեք ձեր Google հաշվով:"</string>
<string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Օգտանուն (էլփոստ)"</string>
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Գաղտնաբառ"</string>
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Մուտք գործել"</string>
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Մեդիա ձայնի բարձրություն"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Նվագարկում է Bluetooth-ի միջոցով"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Սահմանվել է անձայն զանգերանգ"</string>
- <string name="volume_call" msgid="7625321655265747433">"Մուտքային զանգի ձայնի ուժգնությունը"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Խոսակցություն"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth-ի ներզանգի բարձրություն"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Զարթուցիչի ձայնը"</string>
<string name="volume_notification" msgid="6864412249031660057">"Ծանուցումների ձայնի ուժգնությունը"</string>
@@ -1404,7 +1404,7 @@
<string name="ime_action_done" msgid="6299921014822891569">"Պատրաստ է"</string>
<string name="ime_action_previous" msgid="6548799326860401611">"Նախորդ"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Կատարել"</string>
- <string name="dial_number_using" msgid="6060769078933953531">"Հավաքել հեռախոսահամարը`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
+ <string name="dial_number_using" msgid="6060769078933953531">"Հավաքել հեռախոսահամարը՝\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
<string name="create_contact_using" msgid="6200708808003692594">"Ստեղծել կոնտակտ`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
<string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Հետևյալ մեկ կամ մի քանի հավելվածներին թույլտվություն է անհրաժեշտ՝ այժմ և հետագայում ձեր հաշվի տվյալներն օգտագործելու համար։"</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Թույլատրե՞լ"</string>
@@ -1474,7 +1474,7 @@
<string name="number_picker_increment_button" msgid="7621013714795186298">"Ավելացնել"</string>
<string name="number_picker_decrement_button" msgid="5116948444762708204">"Նվազեցնել"</string>
<string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> հպեք և պահեք:"</string>
- <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Սահեցրեք վերև` ավելացնելու համար, և ներքև` նվազեցնելու համար:"</string>
+ <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Սահեցրեք վերև՝ ավելացնելու համար, և ներքև՝ նվազեցնելու համար:"</string>
<string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Աճեցնել րոպեն"</string>
<string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Նվազեցնել րոպեն"</string>
<string name="time_picker_increment_hour_button" msgid="3063572723197178242">"Աճեցնել ժամը"</string>
@@ -1598,7 +1598,7 @@
<string name="kg_invalid_puk" msgid="4809502818518963344">"Վերամուտքագրեք ճիշտ PUK ծածկագիրը: Կրկնվող փորձերը ընդմիշտ կկասեցնեն SIM քարտը:"</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN ծածկագրերը չեն համընկնում"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"Չափից շատ սխեմայի փորձեր"</string>
- <string name="kg_login_instructions" msgid="3619844310339066827">"Ապակողպելու համար` մուտք գործեք ձեր Google հաշվով:"</string>
+ <string name="kg_login_instructions" msgid="3619844310339066827">"Ապակողպելու համար՝ մուտք գործեք ձեր Google հաշվով:"</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"Օգտանուն (էլփոստ)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"Գաղտնաբառը"</string>
<string name="kg_login_submit_button" msgid="893611277617096870">"Մուտք գործել"</string>
@@ -1894,7 +1894,7 @@
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Այս հավելվածը ստեղծվել է Android-ի ավելի հին տարբերակի համար և կարող է պատշաճ չաշխատել: Ստուգեք թարմացումների առկայությունը կամ դիմեք մշակողին:"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Ստուգել նոր տարբերակի առկայությունը"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Դուք ունեք նոր հաղորդագրություններ"</string>
- <string name="new_sms_notification_content" msgid="3197949934153460639">"Դիտելու համար բացել SMS հավելվածը"</string>
+ <string name="new_sms_notification_content" msgid="3197949934153460639">"Դիտելու համար բացել SMS-ների փոխանակման հավելվածը"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Որոշ գործառույթներ կարող են չաշխատել"</string>
<string name="profile_encrypted_detail" msgid="5279730442756849055">"Աշխատանքային պրոֆիլը կողպված է"</string>
<string name="profile_encrypted_message" msgid="1128512616293157802">"Հպեք՝ այն ապակողպելու համար"</string>
@@ -1907,7 +1907,7 @@
<string name="app_info" msgid="6113278084877079851">"Հավելվածի մասին"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Ցուցադրական օգտատերը գործարկվում է…"</string>
- <string name="demo_restarting_message" msgid="1160053183701746766">"Սարաքը վերակայվում է…"</string>
+ <string name="demo_restarting_message" msgid="1160053183701746766">"Սարքը վերակայվում է…"</string>
<string name="suspended_widget_accessibility" msgid="6331451091851326101">"Անջատած <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="5731633152336490471">"Կոնֆերանս զանգ"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"Հուշակ"</string>
@@ -1979,7 +1979,7 @@
<string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Չհաջողվեց վերականգնել դյուրանցումը, քանի որ հավելվածների ստորագրությունները տարբեր են"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Չհաջողվեց վերականգնել դյուրանցումը"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Դյուրանցումն անջատված է"</string>
- <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ՀԵՌԱՑՆԵԼ"</string>
+ <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ԱՊԱՏԵՂԱԴՐԵԼ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ԲԱՑԵԼ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Հայտնաբերվել է վնասաբեր հավելված"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> հավելվածն ուզում է ցուցադրել հատվածներ <xliff:g id="APP_2">%2$s</xliff:g> հավելվածից"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index af462305f5f0..7616372bf77d 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -863,12 +863,12 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda salah menggambar pola pembuka kunci. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci perangkat Android TV menggunakan login Google.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, tablet akan direset ke setelan default pabrik dan semua data pengguna hilang."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal membuka kunci perangkat Android TV. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, perangkat Android TV akan direset ke default pabrik dan semua data pengguna akan hilang."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, ponsel akan direset ke setelan default pabrik dan semua data pengguna hilang."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan direset ke setelan default pabrik."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal membuka kunci perangkat Android TV. Perangkat Android TV sekarang akan direset ke default pabrik."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan direset ke setelan default pabrik."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Lupa pola?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Pembuka kunci akun"</string>
@@ -942,7 +942,7 @@
<string name="autofill_postal_code" msgid="7034789388968295591">"Kode pos"</string>
<string name="autofill_state" msgid="3341725337190434069">"Negara Bagian"</string>
<string name="autofill_zip_code" msgid="1315503730274962450">"Kode pos"</string>
- <string name="autofill_county" msgid="7781382735643492173">"Wilayah"</string>
+ <string name="autofill_county" msgid="7781382735643492173">"County"</string>
<string name="autofill_island" msgid="5367139008536593734">"Pulau"</string>
<string name="autofill_district" msgid="6428712062213557327">"Distrik"</string>
<string name="autofill_department" msgid="9047276226873531529">"Departemen"</string>
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Volume media"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Memutar melalui Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Nada dering senyap disetel"</string>
- <string name="volume_call" msgid="7625321655265747433">"Volume saat-memanggil"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Volume dalam panggilan"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Volume saat-memanggil bluetooth"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Volume alarm"</string>
<string name="volume_notification" msgid="6864412249031660057">"Volume pemberitahuan"</string>
@@ -1231,7 +1231,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Volume pemberitahuan"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Nada dering default"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Tidak Ada"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Tidak ada"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Nada dering"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Suara alarm"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Suara notifikasi"</string>
@@ -1435,7 +1435,7 @@
<string name="vpn_lockdown_config" msgid="8331697329868252169">"Ubah setelan jaringan atau VPN"</string>
<string name="upload_file" msgid="8651942222301634271">"Pilih file"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"Tidak ada file yang dipilih"</string>
- <string name="reset" msgid="3865826612628171429">"Setel ulang"</string>
+ <string name="reset" msgid="3865826612628171429">"Reset"</string>
<string name="submit" msgid="862795280643405865">"Kirim"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Aplikasi mengemudi sedang berjalan"</string>
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Ketuk untuk keluar dari aplikasi mengemudi."</string>
@@ -1608,12 +1608,12 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, tablet akan direset ke setelan default pabrik dan semua data pengguna akan hilang."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal membuka kunci perangkat Android TV. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, perangkat Android TV akan direset ke default pabrik dan semua data pengguna akan hilang."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, ponsel akan direset ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan direset ke setelan default pabrik."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal membuka kunci perangkat Android TV. Perangkat Android TV sekarang akan direset ke default pabrik."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan direset ke setelan default pabrik."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci perangkat Android TV menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
@@ -1907,7 +1907,7 @@
<string name="app_info" msgid="6113278084877079851">"Info aplikasi"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Memulai demo..."</string>
- <string name="demo_restarting_message" msgid="1160053183701746766">"Menyetel ulang perangkat..."</string>
+ <string name="demo_restarting_message" msgid="1160053183701746766">"Mereset perangkat..."</string>
<string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> dinonaktifkan"</string>
<string name="conference_call" msgid="5731633152336490471">"Konferensi Telepon"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"Keterangan alat"</string>
@@ -2034,7 +2034,7 @@
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Aplikasi ini tidak diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Beranda"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Kembali"</string>
- <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplikasi yang Baru Dipakai"</string>
+ <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplikasi Terbaru"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifikasi"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Setelan Cepat"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialog Daya"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index de4de72b0e6c..89da9dd3592e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1231,7 +1231,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Volume notifiche"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Suoneria predefinita"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Predefinita (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Nessuna"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Nessuno"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Suonerie"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Suoni delle sveglie"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Suoni di notifica"</string>
@@ -1937,7 +1937,7 @@
<item quantity="one">Un suggerimento di Compilazione automatica</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Vuoi salvare su "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
- <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Vuoi salvare <xliff:g id="TYPE">%1$s</xliff:g> su "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+ <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Vuoi salvare la <xliff:g id="TYPE">%1$s</xliff:g> su "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Vuoi salvare <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> su "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Vuoi salvare <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g> su "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_update_title" msgid="3630695947047069136">"Vuoi aggiornare su "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index eaea3bdcecd0..519ca02ccb2f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1199,7 +1199,7 @@
<string name="aerr_application_repeated" msgid="7804378743218496566">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> נעצרת שוב ושוב"</string>
<string name="aerr_process_repeated" msgid="1153152413537954974">"האפליקציה <xliff:g id="PROCESS">%1$s</xliff:g> נעצרת שוב ושוב"</string>
<string name="aerr_restart" msgid="2789618625210505419">"פתח שוב את האפליקציה"</string>
- <string name="aerr_report" msgid="3095644466849299308">"משוב"</string>
+ <string name="aerr_report" msgid="3095644466849299308">"שליחת משוב"</string>
<string name="aerr_close" msgid="3398336821267021852">"סגירה"</string>
<string name="aerr_mute" msgid="2304972923480211376">"השתק עד הפעלה מחדש של המכשיר"</string>
<string name="aerr_wait" msgid="3198677780474548217">"המתן"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index c55946e88ae9..33e517680dbe 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -61,7 +61,7 @@
<string name="ColpMmi" msgid="4736462893284419302">"Қосылған желі идентификаторы"</string>
<string name="ColrMmi" msgid="5889782479745764278">"Қосылған желі идентификаторын шектеу"</string>
<string name="CfMmi" msgid="8390012691099787178">"Қоңырауды басқа нөмірге бағыттау"</string>
- <string name="CwMmi" msgid="3164609577675404761">"Күтудегі қоңырау"</string>
+ <string name="CwMmi" msgid="3164609577675404761">"Қоңырауды ұстап тұру"</string>
<string name="BaMmi" msgid="7205614070543372167">"Қоңырауды бөгеу"</string>
<string name="PwdMmi" msgid="3360991257288638281">"Құпия сөз өзгерту"</string>
<string name="PinMmi" msgid="7133542099618330959">"PIN өзгерту"</string>
@@ -317,7 +317,7 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ағза күйінің көрсеткіштері туралы сенсор деректеріне қатынасу"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Терезе мазмұнын оқып отыру"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Ашық тұрған терезе мазмұнын тексеру."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Explore by Touch функциясын қосу"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Түртілген элементтерді дыбыстау функциясын қосу"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Түртілген элементтер дауыстап айтылады және экранды қимылдар арқылы зерттеуге болады."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Терілген мәтінді тексеру"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Несиелік карта нөмірі және құпия сөздер сияқты жеке деректі қоса."</string>
@@ -987,9 +987,9 @@
<string name="searchview_description_clear" msgid="1989371719192982900">"Сұрақты өшіру"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"Сұрақ жіберу"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"Дауыс арқылы іздеу"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Explore by Touch функциясы қосылсын ба?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Explore by Touch мүмкіндігін қосқысы келеді. Explore by Touch мүмкіндігі қосылған кезде, саусағыңыздың астындағы нәрсенің сипаттамаларын естисіз не көресіз немесе планшетпен өзара байланысу үшін қимылдайсыз."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Explore by Touch мүмкіндігін қосқысы келеді. Explore by Touch мүмкіндігі қосылған кезде, саусағыңыздың астындағы нәрсенің сипаттамаларын естисіз не көресіз немесе телефонмен өзара байланысу үшін қимылдайсыз."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Түртілген элементтерді дыбыстау функциясы қосылсын ба?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Түртілген элементтерді дыбыстау функциясын қосуға рұқсат сұрап тұр. Ол қосылған кезде, саусағыңыздың астындағы элементтің сипаттамасын естіп не көріп тұрасыз немесе планшетті қимылмен басқарасыз."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> қызметі Түртілген элементтерді дыбыстау функциясын қосуға рұқсат сұрап тұр. Ол қосылған кезде, саусағыңыздың астындағы элементтің сипаттамасын естіп не көріп тұрасыз немесе телефонды қимылмен басқарасыз."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"1 ай бұрын"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Осыған дейін 1 ай бұрын"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1219,9 +1219,9 @@
<string name="volume_music" msgid="7727274216734955095">"Mультимeдиа дыбыс деңгейі"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth арқылы ойнату"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Үнсіз қоңырау әуенін орнату"</string>
- <string name="volume_call" msgid="7625321655265747433">"Келетін қоңырау дыбысының қаттылығы"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Сөйлесу кезіндегі дыбыс деңгейі"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth қоңырауының қаттылығы"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Дабыл дыбысының қаттылығы"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Дабыл дыбысының деңгейі"</string>
<string name="volume_notification" msgid="6864412249031660057">"Хабар дыбысының қаттылығы"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Дыбыс қаттылығы"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetooth дыбысының қаттылығы"</string>
@@ -1307,7 +1307,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Аналогтық аудиожабдық анықталды"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Жалғанған құрылғы бұл телефонмен үйлесімсіз. Қосымша ақпарат алу үшін түртіңіз."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB арқылы түзету қосылған"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB арқылы түзетуді өшіру үшін түртіңіз"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"USB арқылы түзетуді өшіру үшін түртіңіз."</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB арқылы түзетуді өшіру үшін таңдаңыз."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Сымсыз түзету байланыстырылды"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Сымсыз түзетуді өшіру үшін түртіңіз."</string>
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Әкімші жаңартқан"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Әкімші жойған"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Жарайды"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Батарея жұмысының ұзақтығын арттыру үшін Battery Saver:\n\n•қараңғы тақырыпты іске қосады;\n•фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді немесе шектейді.\n\n"<annotation id="url">"Толығырақ"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"Батарея жұмысының ұзақтығын арттыру үшін Battery Saver:\n\n•қараңғы тақырыпты іске қосады;\n•фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді немесе шектейді."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Батарея жұмысының ұзақтығын арттыру үшін Батареяны үнемдеу режимі:\n\n•қараңғы тақырыпты іске қосады;\n•фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді немесе шектейді.\n\n"<annotation id="url">"Толығырақ"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"Батарея жұмысының ұзақтығын арттыру үшін Батареяны үнемдеу режимі:\n\n•қараңғы тақырыпты іске қосады;\n•фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді немесе шектейді."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Дерек шығынын азайту үшін Data Saver функциясы кейбір қолданбаларға деректерді фондық режимде жіберуге және алуға жол бермейді. Ашық тұрған қолданба деректерді пайдаланады, бірақ шектеулі шамада (мысалы, кескіндер оларды түрткенге дейін көрсетілмейді)."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Data Saver функциясын қосу керек пе?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Қосу"</string>
@@ -1912,7 +1912,7 @@
<string name="conference_call" msgid="5731633152336490471">"Конференциялық қоңырау"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"Қалқыма сөзкөмек"</string>
<string name="app_category_game" msgid="4534216074910244790">"Ойындар"</string>
- <string name="app_category_audio" msgid="8296029904794676222">"Музыка және аудиомазмұн"</string>
+ <string name="app_category_audio" msgid="8296029904794676222">"Музыка және аудио"</string>
<string name="app_category_video" msgid="2590183854839565814">"Фильм және бейне"</string>
<string name="app_category_image" msgid="7307840291864213007">"Суреттер және кескіндер"</string>
<string name="app_category_social" msgid="2278269325488344054">"Әлеуметтік қолданба мен байланыс"</string>
@@ -2000,7 +2000,7 @@
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Battery Saver іске қосылды"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Battery Saver"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Батареяны үнемдеу режимі"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Battery Saver өшірілді"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефонның заряды жеткілікті. Функцияларға енді шектеу қойылмайды."</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Планшеттің заряды жеткілікті. Функцияларға енді шектеу қойылмайды."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 28629fd3bd65..c60727f49cc5 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1219,8 +1219,8 @@
<string name="volume_music" msgid="7727274216734955095">"កម្រិត​សំឡេង​មេឌៀ"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"ចាក់​តាម​ប៊្លូធូស"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"កំណត់​សំឡេង​រោទ៍​ស្ងាត់"</string>
- <string name="volume_call" msgid="7625321655265747433">"កម្រិត​សំឡេង​ហៅ​ចូល"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"កម្រិត​សំឡេង​ហៅ​ចូល​តាម​ប៊្លូធូស"</string>
+ <string name="volume_call" msgid="7625321655265747433">"កម្រិត​សំឡេង​ក្នុងពេលនិយាយទូរសព្ទ"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"កម្រិត​សំឡេង​ក្នុងពេលនិយាយទូរសព្ទ​តាម​ប៊្លូធូស"</string>
<string name="volume_alarm" msgid="4486241060751798448">"កម្រិត​សំឡេងម៉ោងរោទ៍"</string>
<string name="volume_notification" msgid="6864412249031660057">"កម្រិត​សំឡេង​ការ​ជូន​ដំណឹង"</string>
<string name="volume_unknown" msgid="4041914008166576293">"កម្រិត​សំឡេង"</string>
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"ធ្វើ​បច្ចុប្បន្នភាព​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"លុប​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម កម្មវិធី​សន្សំថ្ម៖\n\n•បើករចនាប័ទ្មងងឹត\n•បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពល​ជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Ok Google” ជាដើម\n\n"<annotation id="url">"ស្វែងយល់​បន្ថែម"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម កម្មវិធី​សន្សំថ្ម៖\n\n•បើករចនាប័ទ្មងងឹត\n•បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពល​ជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Ok Google” ជាដើម"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម មុខងារ​សន្សំ​ថ្ម៖\n\n•បើករចនាប័ទ្មងងឹត\n•បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពល​ជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Hey Google” ជាដើម\n\n"<annotation id="url">"ស្វែងយល់​បន្ថែម"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម មុខងារ​សន្សំ​ថ្ម៖\n\n•បើករចនាប័ទ្មងងឹត\n•បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពល​ជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Hey Google” ជាដើម"</string>
<string name="data_saver_description" msgid="4995164271550590517">"ដើម្បីជួយកាត់បន្ថយការប្រើប្រាស់ទិន្នន័យ កម្មវិធីសន្សំសំចៃទិន្នន័យរារាំងកម្មវិធីមួយចំនួនមិនឲ្យបញ្ជូន ឬទទួលទិន្នន័យនៅផ្ទៃខាងក្រោយទេ។ កម្មវិធីដែលអ្នកកំពុងប្រើនាពេលបច្ចុប្បន្នអាចចូលប្រើប្រាស់​ទិន្នន័យបាន ប៉ុន្តែអាចនឹងមិនញឹកញាប់ដូចមុនទេ។ ឧទាហរណ៍ រូបភាពមិនបង្ហាញទេ លុះត្រាតែអ្នកប៉ះរូបភាពទាំងនោះ។"</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"បើកកម្មវិធីសន្សំសំចៃទិន្នន័យ?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"បើក"</string>
@@ -1999,9 +1999,9 @@
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"កំពុងបង្ហាញ​ពីលើកម្មវិធីផ្សេងទៀត​នៅលើអេក្រង់​របស់អ្នក"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ការ​ជូនដំណឹង​ព័ត៌មាន​របស់​មុខងារ​ទម្លាប់"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ថ្ម​អាច​នឹង​អស់ មុនពេល​សាកថ្មធម្មតា"</string>
- <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បាន​បើក​ដំណើរការកម្មវិធី​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"កម្មវិធីសន្សំថ្ម"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"កម្មវិធី​សន្សំ​ថ្ម​ត្រូវបានបិទ"</string>
+ <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បាន​បើក​ដំណើរការមុខងារ​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"មុខងារ​សន្សំ​ថ្ម"</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"មុខងារ​សន្សំ​ថ្ម​ត្រូវបានបិទ"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"ទូរសព្ទ​មាន​កម្រិតថ្ម​គ្រប់គ្រាន់​។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"ថេប្លេត​មាន​កម្រិតថ្ម​គ្រប់គ្រាន់​។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"ឧបករណ៍​មាន​កម្រិតថ្ម​គ្រប់គ្រាន់​។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 2f89ba370b39..34358c4789d0 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"space"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ಅಳಿಸಿ"</string>
- <string name="search_go" msgid="2141477624421347086">"ಹುಡುಕಿ"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"ಹುಡುಕಿ…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"ಹುಡುಕಿ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"ಪ್ರಶ್ನೆಯನ್ನು ಹುಡುಕಿ"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ಪ್ರಶ್ನೆಯನ್ನು ತೆರವುಗೊಳಿಸು"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ಪ್ರಶ್ನೆಯನ್ನು ಸಲ್ಲಿಸು"</string>
@@ -1221,7 +1221,7 @@
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ಶಾಂತ ರಿಂಗ್‌ಟೋನ್ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
<string name="volume_call" msgid="7625321655265747433">"ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"ಬ್ಲೂಟೂತ್‌‌ ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"ಅಲಾರಮ್ ವಾಲ್ಯೂಮ್"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"ಅಲಾರಂ ವಾಲ್ಯೂಮ್"</string>
<string name="volume_notification" msgid="6864412249031660057">"ಅಧಿಸೂಚನೆಯ ವಾಲ್ಯೂಮ್"</string>
<string name="volume_unknown" msgid="4041914008166576293">"ವಾಲ್ಯೂಮ್"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ಬ್ಲೂಟೂತ್‌‌ ವಾಲ್ಯೂಮ್"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ಝೂಮ್‌ ನಿಯಂತ್ರಿಸಲು ಎರಡು ಬಾರಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
<string name="ime_action_go" msgid="5536744546326495436">"ಹೋಗು"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"ಹುಡುಕಿ"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"ಕಳುಹಿಸು"</string>
<string name="ime_action_next" msgid="4169702997635728543">"ಮುಂದೆ"</string>
<string name="ime_action_done" msgid="6299921014822891569">"ಮುಗಿದಿದೆ"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"ಸೂಚಿತ ಭಾಷೆ"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"ಎಲ್ಲಾ ಭಾಷೆಗಳು"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"ಎಲ್ಲಾ ಪ್ರದೇಶಗಳು"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"ಹುಡುಕಿ"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ. ಇದನ್ನು <xliff:g id="APP_NAME_1">%2$s</xliff:g> ನಲ್ಲಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index c071fc7b63ca..d21acfb3577d 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -857,12 +857,12 @@
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Колдонуучунун нускамасын караңыз же Кардарларды тейлөө борборуна кайрылыңыз."</string>
<string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM-карта бөгөттөлгөн."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"SIM-карта бөгөттөн чыгарылууда…"</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун Google аккаунтуңузга кирип ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Сиз планшетиңизди бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> аракеттен кийин, планшет баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Android TV түзмөгүңүздүн кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүз демейки жөндөөлөргө кайтарылып, бардык колдонуучу дайындары жоголот."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"Сиз телефонуңузду бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> аракеттен кийин, телефон баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт."</string>
@@ -1199,7 +1199,7 @@
<string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо ыңгайлаштырылууда."</string>
<string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> даярдалууда."</string>
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Колдонмолорду иштетип баштоо"</string>
- <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөө аякталууда."</string>
+ <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөлүүдө"</string>
<string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> иштеп жатат"</string>
<string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Оюнга кайтуу үчүн таптаңыз"</string>
<string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Оюн тандоо"</string>
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Мультимедианын катуулугу"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth аркылуу ойнотулууда"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Үнсүз рингтон орнотулду"</string>
- <string name="volume_call" msgid="7625321655265747433">"Чалуудагы үн көлөмү"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Сүйлөшүүнүн катуулугу"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth чалуудагы үн көлөмү"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Ойготкучтун катуулугу"</string>
<string name="volume_notification" msgid="6864412249031660057">"Эскертме үн көлөмү"</string>
@@ -1317,7 +1317,7 @@
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Майнаптуулугуна таасири тиет. Аны өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
<string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB портунда суюктук же урандылар бар"</string>
- <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн, таптап коюңуз."</string>
+ <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB порт автоматтык түрдө өчтү. Кененирээк маалымат алуу үчүн, таптап коюңуз."</string>
<string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"USB портун колдонууга болот"</string>
<string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Телефон суюктук менен урандыларды аныктаган жок."</string>
<string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
@@ -1792,7 +1792,7 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Администраторуңуз жаңыртып койгон"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Администраторуңуз жок кылып салган"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Батареянын мөөнөтүн узартуу үчүн, Батареяны үнөмдөгүч режими төмөнкүлөрдү аткарат:\n\n•Караңгы теманы күйгүзөт\n•Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Батареянын мөөнөтүн узартуу үчүн Батареяны үнөмдөгүч режими төмөнкүлөрдү аткарат:\n\n•Караңгы теманы күйгүзөт\n•Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
<string name="battery_saver_description" msgid="8587408568232177204">"Батареянын иштешин узартуу үчүн, Батареяны үнөмдөөчү режим:\n\n•Караңгы теманы күйгүзөт\n•Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор дайын-даректерди фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайын-даректерди жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикти үнөмдөө режимин иштетесизби?"</string>
@@ -2001,8 +2001,8 @@
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея кубаттоого чейин отуруп калышы мүмкүн"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батареянын отуруп калбашы үчүн Батареяны үнөмдөгүч режими иштетилди"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Батареяны үнөмдөгүч"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Батареяны үнөмдөгүч режими өчүрүлдү"</string>
- <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефон жеткиликтүү кубатталды. Функцияны колдоно берсеңиз болот."</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Батареяны үнөмдөө режими өчүк"</string>
+ <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефондун кубаты жетиштүү. Функциялар мындан ары чектелбейт."</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Планшет жеткиликтүү кубатталды. Функцияны колдоно берсеңиз болот."</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Түзмөк жеткиликтүү кубатталды. Функцияны колдоно берсеңиз болот."</string>
<string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index b2d8e6a20fe9..35d39cb7a87e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -155,19 +155,19 @@
<string name="fcError" msgid="5325116502080221346">"Проблем со поврзувањето или неважечки код за карактеристиката."</string>
<string name="httpErrorOk" msgid="6206751415788256357">"Во ред"</string>
<string name="httpError" msgid="3406003584150566720">"Настана грешка на мрежа."</string>
- <string name="httpErrorLookup" msgid="3099834738227549349">"Не можеше да се најде URL."</string>
+ <string name="httpErrorLookup" msgid="3099834738227549349">"Не може да се најде URL."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="3976195595501606787">"Шемата за автентикација на локацијата не е поддржана."</string>
- <string name="httpErrorAuth" msgid="469553140922938968">"Не можеше да се автентицира."</string>
+ <string name="httpErrorAuth" msgid="469553140922938968">"Не може да се автентицира."</string>
<string name="httpErrorProxyAuth" msgid="7229662162030113406">"Автентикацијата преку прокси серверот беше неуспешна."</string>
- <string name="httpErrorConnect" msgid="3295081579893205617">"Не можеше да се поврзе со серверот."</string>
- <string name="httpErrorIO" msgid="3860318696166314490">"Не можеше да се комуницира со серверот. Обидете се повторно подоцна."</string>
+ <string name="httpErrorConnect" msgid="3295081579893205617">"Не може да се поврзе со серверот."</string>
+ <string name="httpErrorIO" msgid="3860318696166314490">"Не може да се комуницира со серверот. Обидете се повторно подоцна."</string>
<string name="httpErrorTimeout" msgid="7446272815190334204">"Времето за поврзување до серверот истече."</string>
<string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Страницата содржи премногу пренасочувања од серверот."</string>
<string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Протоколот не е поддржан."</string>
- <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Не можеше да се воспостави безбедна врска."</string>
- <string name="httpErrorBadUrl" msgid="754447723314832538">"Страницата не можеше да се отвори, бидејќи URL е неважечки."</string>
- <string name="httpErrorFile" msgid="3400658466057744084">"Не можеше да се пристапи до датотеката."</string>
- <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Не можеше да се најде бараната датотека."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"Не може да се воспостави безбедна врска."</string>
+ <string name="httpErrorBadUrl" msgid="754447723314832538">"Страницата не може да се отвори, бидејќи URL е неважечки."</string>
+ <string name="httpErrorFile" msgid="3400658466057744084">"Не може да се пристапи до датотеката."</string>
+ <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Не може да се најде бараната датотека."</string>
<string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Се обработуваат премногу барања. Обидете се повторно подоцна."</string>
<string name="notification_title" msgid="5783748077084481121">"Грешка при пријавување за <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="2341041749565687871">"Синхронизирај"</string>
@@ -543,7 +543,7 @@
<string name="biometric_error_canceled" msgid="8266582404844179778">"Проверката е откажана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не е поставен PIN, шема или лозинка"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Откриен е делумен отпечаток. Обидете се повторно."</string>
- <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не можеше да се обработи. Обидете се повторно."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензорот за отпечатоци е валкан. Исчистете го и обидете се повторно."</string>
<string name="fingerprint_acquired_too_fast" msgid="5151661932298844352">"Прстот се движеше пребрзо. Обидете се повторно."</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Прстот се движеше премногу бавно. Обидете се повторно."</string>
@@ -898,7 +898,7 @@
<string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Избирач на корисник"</string>
<string name="keyguard_accessibility_status" msgid="6792745049712397237">"Статус"</string>
<string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Камера"</string>
- <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Контроли на медиуми"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Контроли за аудио/видео содржини"</string>
<string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Прередувањето виџети започна."</string>
<string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Прередувањето виџети заврши."</string>
<string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Виџетот <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> е избришан."</string>
@@ -985,7 +985,7 @@
<string name="searchview_description_search" msgid="1045552007537359343">"Пребарај"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"Пребарај барање"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"Исчисти барање"</string>
- <string name="searchview_description_submit" msgid="6771060386117334686">"Поднеси барање"</string>
+ <string name="searchview_description_submit" msgid="6771060386117334686">"Испрати барање"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"Гласовно пребарување"</string>
<string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Овозможи „Истражувај со допир“?"</string>
<string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> сака да овозможи „Истражувај со допир“. Кога е вклучено „Истражувај со допир“, може да се слушнат или да се видат описи на она што е под вашиот прст или да се прават движења за комуницирање со таблетот."</string>
@@ -1344,7 +1344,7 @@
<string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
<string name="ext_media_new_notification_message" msgid="6095403121990786986">"Допрете за поставување"</string>
<string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можеби ќе треба да го преформатирате уредот. Допрете за отстранување."</string>
- <string name="ext_media_ready_notification_message" msgid="777258143284919261">"За пренесување фотографии и медиуми"</string>
+ <string name="ext_media_ready_notification_message" msgid="777258143284919261">"За пренесување фотографии и аудио/видео содржини"</string>
<string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем со <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не работи"</string>
<string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Допрете за да го поправите ова"</string>
@@ -1385,8 +1385,8 @@
<string name="ext_media_status_formatting" msgid="774148701503179906">"Се форматира..."</string>
<string name="ext_media_status_missing" msgid="6520746443048867314">"Не е внесено"</string>
<string name="activity_list_empty" msgid="4219430010716034252">"Не се пронајдени соодветни активности."</string>
- <string name="permlab_route_media_output" msgid="8048124531439513118">"насочување излез за медиуми"</string>
- <string name="permdesc_route_media_output" msgid="1759683269387729675">"Овозможува апликацијата да насочува излез за медиуми кон други надворешни уреди."</string>
+ <string name="permlab_route_media_output" msgid="8048124531439513118">"насочување излез за аудио/видео"</string>
+ <string name="permdesc_route_media_output" msgid="1759683269387729675">"Овозможува апликацијата да насочува излез за аудио/видео содржини кон други надворешни уреди."</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"читање сесии на инсталирање"</string>
<string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Дозволува апликација да чита сесии на инсталирање. Тоа овозможува апликацијата да гледа детали за активни инсталации на пакет."</string>
<string name="permlab_requestInstallPackages" msgid="7600020863445351154">"барање пакети за инсталирање"</string>
@@ -1396,7 +1396,7 @@
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"прашај дали да се игнорираат оптимизациите на батеријата"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Овозможува апликацијата да побара дозвола за игнорирање на оптимизациите на батеријата за таа апликација."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Допрете двапати за контрола на зумот"</string>
- <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не можеше да се додаде виџет."</string>
+ <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не може да се додаде виџет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Оди"</string>
<string name="ime_action_search" msgid="4501435960587287668">"Пребарај"</string>
<string name="ime_action_send" msgid="8456843745664334138">"Испрати"</string>
@@ -1431,12 +1431,12 @@
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Поврзување со секогаш вклучена VPN..."</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"Поврзани со секогаш вклучена VPN"</string>
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Исклучено од секогаш вклучената VPN"</string>
- <string name="vpn_lockdown_error" msgid="4453048646854247947">"Не можеше да се поврзе на секогаш вклучената VPN"</string>
+ <string name="vpn_lockdown_error" msgid="4453048646854247947">"Не може да се поврзе на секогаш вклучената VPN"</string>
<string name="vpn_lockdown_config" msgid="8331697329868252169">"Променете ја мрежата или поставките за VPN"</string>
<string name="upload_file" msgid="8651942222301634271">"Избери датотека"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"Не е избрана датотека"</string>
<string name="reset" msgid="3865826612628171429">"Ресетирај"</string>
- <string name="submit" msgid="862795280643405865">"Поднеси"</string>
+ <string name="submit" msgid="862795280643405865">"Испрати"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Апликацијата за возење работи"</string>
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Допрете за да излезете од апликацијата за возење."</string>
<string name="back_button_label" msgid="4078224038025043387">"Назад"</string>
@@ -1773,7 +1773,7 @@
<string name="restr_pin_try_later" msgid="5897719962541636727">"Обиди се повторно подоцна"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Се прикажува на цел екран"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"За да излезете, повлечете одозгора надолу."</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"Разбрав"</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"Сфатив"</string>
<string name="done_label" msgid="7283767013231718521">"Готово"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Приказ на часови во кружно движење"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Приказ на минути во кружно движење"</string>
@@ -1975,9 +1975,9 @@
<string name="popup_window_default_title" msgid="6907717596694826919">"Појавен прозорец"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Верзијата на апликацијата е постара или не е компатибилна со кратенкава"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Не можеше да се врати кратенката бидејќи апликацијата не поддржува бекап и враќање"</string>
- <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Не можеше да се врати кратенката бидејќи потписот на апликацијата не се совпаѓа"</string>
- <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Не можеше да се врати кратенката"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Не може да се врати кратенката бидејќи апликацијата не поддржува бекап и враќање"</string>
+ <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Не може да се врати кратенката бидејќи потписот на апликацијата не се совпаѓа"</string>
+ <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Не може да се врати кратенката"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Кратенката е оневозможена"</string>
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАЈ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"СЕПАК ОТВОРИ"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 3ecad6fce138..1b036045160c 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -325,7 +325,7 @@
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"ഡിസ്പ്ലേയുടെ സൂം നിലയും പൊസിഷനിംഗും നിയന്ത്രിക്കുക."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"ജെസ്‌റ്ററുകൾ നിർവഹിക്കുക"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ടാപ്പുചെയ്യാനോ സ്വൈപ്പുചെയ്യാനോ പിഞ്ചുചെയ്യാനോ മറ്റ് ജെസ്‌റ്ററുകൾ നിർവഹിക്കാനോ കഴിയും."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ഫിംഗർപ്രിന്റ് ജെസ്‌റ്ററുകൾ"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ഫിംഗർപ്രിന്റ് ജെസ്‌ച്ചറുകൾ"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ഉപകരണത്തിന്റെ ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെയ്‌ത ജെസ്‌റ്ററുകൾ ക്യാപ്‌ചർ ചെയ്യാനാകും."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"സ്ക്രീന്‍ഷോട്ട് എടുക്കുക"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ഡിസ്‌പ്ലേയുടെ സ്‌ക്രീൻഷോട്ട് എടുക്കാൻ കഴിയും."</string>
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"space"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"delete"</string>
- <string name="search_go" msgid="2141477624421347086">"തിരയൽ"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"തിരയുക…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"തിരയൽ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"തിരയൽ അന്വേഷണം"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"അന്വേഷണം മായ്‌ക്കുക"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ചോദ്യം സമർപ്പിക്കുക"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"സൂം നിയന്ത്രണം ലഭിക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"വിജറ്റ് ചേർക്കാനായില്ല."</string>
<string name="ime_action_go" msgid="5536744546326495436">"പോവുക"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"തിരയൽ"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"അയയ്‌ക്കുക"</string>
<string name="ime_action_next" msgid="4169702997635728543">"അടുത്തത്"</string>
<string name="ime_action_done" msgid="6299921014822891569">"പൂർത്തിയായി"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"നിര്‍‌ദ്ദേശിച്ചത്"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"എല്ലാ ഭാഷകളും"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"എല്ലാ പ്രദേശങ്ങളും"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"തിരയുക"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"ആപ്പ് ലഭ്യമല്ല"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ഇപ്പോൾ ലഭ്യമല്ല. <xliff:g id="APP_NAME_1">%2$s</xliff:g> ആണ് ഇത് മാനേജ് ചെയ്യുന്നത്."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"കൂടുതലറിയുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 121b71c1b4a7..656227a04835 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -273,7 +273,7 @@
<string name="notification_channel_car_mode" msgid="2123919247040988436">"Машины горим"</string>
<string name="notification_channel_account" msgid="6436294521740148173">"Бүртгэлийн төлөв"</string>
<string name="notification_channel_developer" msgid="1691059964407549150">"Хөгжүүлэгчийн мессеж"</string>
- <string name="notification_channel_developer_important" msgid="7197281908918789589">"Хөгжүүлэгчийн чухал зурвас"</string>
+ <string name="notification_channel_developer_important" msgid="7197281908918789589">"Хөгжүүлэгчийн чухал мессеж"</string>
<string name="notification_channel_updates" msgid="7907863984825495278">"Шинэчлэлтүүд"</string>
<string name="notification_channel_network_status" msgid="2127687368725272809">"Сүлжээний төлөв"</string>
<string name="notification_channel_network_alerts" msgid="6312366315654526528">"Сүлжээний сануулга"</string>
@@ -356,9 +356,9 @@
<string name="permlab_sendSms" msgid="7757368721742014252">"SMS мессежийг илгээх, харах"</string>
<string name="permdesc_sendSms" msgid="6757089798435130769">"Апп нь SMS мессеж илгээх боломжтой. Энэ нь санаандгүй төлбөрт оруулж болзошгүй. Хортой апп нь таны зөвшөөрөлгүйгээр мессеж илгээн таныг төлбөрт оруулж болзошгүй."</string>
<string name="permlab_readSms" msgid="5164176626258800297">"таны текст мессежийг унших(SMS эсвэл MMS)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Энэ апп таны таблетад хадгалсан бүх SMS (текст) зурвасыг унших боломжтой."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Энэ апп таны таблетад хадгалсан бүх SMS (текст) мессежийг унших боломжтой."</string>
<string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Энэ апп таны Android TV төхөөрөмжид хадгалсан бүх SMS (текст) мессежийг уншиж чадна."</string>
- <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Энэ апп таны утсанд хадгалсан бүх SMS (текст) зурвасыг унших боломжтой."</string>
+ <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Энэ апп таны утсанд хадгалсан бүх SMS (текст) мессежийг унших боломжтой."</string>
<string name="permlab_receiveWapPush" msgid="4223747702856929056">"текст мессеж(WAP) хүлээн авах"</string>
<string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Апп нь WAP мессежийг хүлээн авах болон биелүүлэх боломжтой. Энэ зөвшөөрөл нь танд илгээсэн мессежийг танд харуулалгүйгээр хянах эсвэл устгах боломжийг агуулна."</string>
<string name="permlab_getTasks" msgid="7460048811831750262">"ажиллаж байгаа апп-г дуудах"</string>
@@ -416,9 +416,9 @@
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Энэ апп таны Android TV төхөөрөмжид хадгалсан календарийн бүх арга хэмжээг унших болон таны календарийн өгөгдлийг хуваалцах эсвэл хадгалах боломжтой."</string>
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Энэ апп таны утсанд хадгалсан хуанлийн бүх арга хэмжээг унших, хуанлийн өгөгдлийг хуваалцах, хадгалах боломжтой."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"календарын хуваарийг нэмэх эсвэл өөрчлөх болон эзэмшигчид мэдэгдэлгүйгээр зочидруу имэйл илгээх"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Энэ апп таны таблет дээр хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс зурвас илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Энэ апп таны таблет дээр хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс мессеж илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Энэ апп таны Android TV төхөөрөмжид календарийн арга хэмжээ нэмэх, үүнийг устгах, эсвэл өөрчлөх боломжтой. Энэ апп календарийн өмчлөгчөөс ирсэн мэт харагдаж болох мессеж илгээх эсвэл арга хэмжээг өмчлөгчид нь мэдэгдэлгүйгээр өөрчлөх боломжтой."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Энэ апп таны утсанд хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс зурвас илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Энэ апп таны утсанд хуанлийн арга хэмжээг нэмэх, устгах, эсвэл өөрчлөх боломжтой. Энэ апп нь хуанли эзэмшигчээс мессеж илгээсэн мэт харагдах, эсвэл эзэмшигчид мэдэгдэлгүйгээр арга хэмжээг өөрчлөх боломжтой."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"байршил нийлүүлэгчийн нэмэлт тушаалд хандах"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"нарийвчилсан байршилд зөвхөн нүүр хэсэгт хандах"</string>
@@ -661,8 +661,8 @@
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Одоогийн Андройд Бийм дамжуулалтын мэдээллийг хүлээн авахыг аппликейшнд зөвшөөрөх"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM сертификатыг устгах"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Аппликейшнд DRM сертификатыг устгахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"зөөгч зурвасын үйлчилгээнд холбох"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Эзэмшигчид зөөгч зурвасын үйлчилгээний түвшний интерфэйст холбогдохыг зөвшөөрдөг. Энгийн апп-д шаардлагагүй."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"зөөгч мессежийн үйлчилгээнд холбох"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Эзэмшигчид зөөгч мессежийн үйлчилгээний түвшний интерфэйст холбогдохыг зөвшөөрдөг. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"Үүрэн холбооны үйлчилгээ үзүүлэгчтэй холбогдох"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Аливаа эзэмшигчийг үүрэн холбооны үйлчилгээ үзүүлэгчтэй холбодог. Энгийн аппд шаардлагагүй."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"Бүү саад бол тохируулгад хандалт хийх"</string>
@@ -950,18 +950,18 @@
<string name="autofill_parish" msgid="6847960518334530198">"Мөргөлч"</string>
<string name="autofill_area" msgid="8289022370678448983">"Хэсэг"</string>
<string name="autofill_emirate" msgid="2544082046790551168">"Эмират"</string>
- <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"өөрийн Вэб хавчуурга болон түүхийг унших"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"өөрийн Веб хавчуурга болон түүхийг унших"</string>
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Апп нь Хөтчийн зочилж байсан бүх URL-н түүх болон Хөтчийн бүх хавчуургыг унших боломжтой. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадавхтай аппликейшнүүдэд ашиглагдахгүй байх боломжтой."</string>
- <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"вэб хавчуурга болон түүхийг бичих"</string>
+ <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"веб хавчуурга болон түүхийг бичих"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Апп нь таны таблет дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликейшнд ажиллахгүй байх боломжтой."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Аппад таны Android TV төхөөрөмжид хадгалсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөхийг зөвшөөрнө. Энэ нь аппад Хөтчийн өгөгдлийг устгах эсвэл өөрчлөхийг зөвшөөрч болзошгүй. Санамж: энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вэб хөтчийн чадамжтай бусад аппад хэрэгжихгүй байж болзошгүй."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Аппад таны Android TV төхөөрөмжид хадгалсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөхийг зөвшөөрнө. Энэ нь аппад Хөтчийн өгөгдлийг устгах эсвэл өөрчлөхийг зөвшөөрч болзошгүй. Санамж: энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл веб хөтчийн чадамжтай бусад аппад хэрэгжихгүй байж болзошгүй."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Апп нь таны утсан дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликейшнд ажиллахгүй байх боломжтой."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"сэрүүлэг тохируулах"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"Апп нь суулгагдсан сэрүүлэгний апп дээр сэрүүлэг тохируулах боломжтой. Зарим сэрүүлэгний апп нь энэ функцийг дэмжихгүй байж болзошгүй."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"дуут шуудан нэмэх"</string>
- <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Таны дуут шуудангийн ирсэн мэйлд зурвас нэмэхийг апп-д зөвшөөрөх."</string>
+ <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Таны дуут шуудангийн ирсэн мэйлд мессеж нэмэхийг апп-д зөвшөөрөх."</string>
<string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"Хөтчийн геобайршлын зөвшөөрлийг өөрчлөх"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Апп нь Хөтчийн гео байршлын зөвшөөрлийг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан дурын вэб хуудасруу байршлын мэдээллийг илгээх боломжтой."</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Апп нь Хөтчийн гео байршлын зөвшөөрлийг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан дурын веб хуудасруу байршлын мэдээллийг илгээх боломжтой."</string>
<string name="save_password_message" msgid="2146409467245462965">"Та хөтчид энэ нууц үгийг сануулах уу?"</string>
<string name="save_password_notnow" msgid="2878327088951240061">"Одоо биш"</string>
<string name="save_password_remember" msgid="6490888932657708341">"Санах"</string>
@@ -1117,7 +1117,7 @@
<string name="yes" msgid="9069828999585032361">"ОК"</string>
<string name="no" msgid="5122037903299899715">"Цуцлах"</string>
<string name="dialog_alert_title" msgid="651856561974090712">"Анхаар"</string>
- <string name="loading" msgid="3138021523725055037">"Ачааллаж байна..."</string>
+ <string name="loading" msgid="3138021523725055037">"Ачаалж байна..."</string>
<string name="capital_on" msgid="2770685323900821829">"Идэвхтэй"</string>
<string name="capital_off" msgid="7443704171014626777">"Идэвхгүй"</string>
<string name="checked" msgid="9179896827054513119">"тэмдэглэсэн"</string>
@@ -1452,7 +1452,7 @@
<string name="progress_erasing" msgid="6891435992721028004">"Хуваалцсан хадгалах санг устгаж байна…"</string>
<string name="share" msgid="4157615043345227321">"Хуваалцах"</string>
<string name="find" msgid="5015737188624767706">"Олох"</string>
- <string name="websearch" msgid="5624340204512793290">"Вэб хайлт"</string>
+ <string name="websearch" msgid="5624340204512793290">"Веб хайлт"</string>
<string name="find_next" msgid="5341217051549648153">"Дараагийнхыг хайх"</string>
<string name="find_previous" msgid="4405898398141275532">"Өмнөхөөс олох"</string>
<string name="gpsNotifTicker" msgid="3207361857637620780">"<xliff:g id="NAME">%s</xliff:g>-н байршлын хүсэлт"</string>
@@ -1893,7 +1893,7 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> яг одоо боломжгүй байна."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Энэ аппыг Андройдын хуучин хувилбарт зориулсан бөгөөд буруу ажиллаж болзошгүй. Шинэчлэлтийг шалгаж эсвэл хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
- <string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ зурвасууд байна"</string>
+ <string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ мессежүүд байна"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Үзэхийн тулд SMS аппыг нээх"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Зарим функцийг хязгаарласан байж болзошгүй"</string>
<string name="profile_encrypted_detail" msgid="5279730442756849055">"Ажлын профайлыг түгжсэн"</string>
@@ -1961,7 +1961,7 @@
<string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
<string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"Эргийн бүс, голын эргийн бүсээс өндөрлөг газар зэрэг аюулгүй газар руу нэн даруй шилжинэ үү."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
- <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Онцгой байдлын зурвасын тест"</string>
+ <string name="etws_primary_default_message_test" msgid="4583367373909549421">"Онцгой байдлын мессежийн тест"</string>
<string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Хариу бичих"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
<string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM-г дуу хоолойд зөвшөөрдөггүй"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index bc4450fef4ff..6422683a7867 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -167,15 +167,15 @@
<string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"सुरक्षित कनेक्शन इंस्टॉल करू शकलो नाही."</string>
<string name="httpErrorBadUrl" msgid="754447723314832538">"URL अवैध असल्यामुळे पेज उघडू शकलो नाही."</string>
<string name="httpErrorFile" msgid="3400658466057744084">"फायलीवर प्रवेश करू शकलो नाही."</string>
- <string name="httpErrorFileNotFound" msgid="5191433324871147386">"विनंती केलेली फाईल शोधू शकलो नाही."</string>
+ <string name="httpErrorFileNotFound" msgid="5191433324871147386">"विनंती केलेली फाइल शोधू शकलो नाही."</string>
<string name="httpErrorTooManyRequests" msgid="2149677715552037198">"बर्‍याच विनंत्यांवर प्रक्रिया होत आहे. नंतर पुन्हा प्रयत्न करा."</string>
<string name="notification_title" msgid="5783748077084481121">"<xliff:g id="ACCOUNT">%1$s</xliff:g> साठी साइन इन एरर"</string>
<string name="contentServiceSync" msgid="2341041749565687871">"सिंक करा"</string>
<string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"सिंक करू शकत नाही"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"खूप जास्त <xliff:g id="CONTENT_TYPE">%s</xliff:g> हटवण्याचा प्रयत्न केला."</string>
- <string name="low_memory" product="tablet" msgid="5557552311566179924">"टॅबलेट संचयन पूर्ण भरले आहे. स्थान मोकळे करण्यासाठी काही फाईल हटवा."</string>
+ <string name="low_memory" product="tablet" msgid="5557552311566179924">"टॅबलेट संचयन पूर्ण भरले आहे. स्थान मोकळे करण्यासाठी काही फाइल हटवा."</string>
<string name="low_memory" product="watch" msgid="3479447988234030194">"पाहण्याचे संचयन पूर्ण भरले आहे. स्थान मोकळे करण्यासाठी काही फाइल हटवा."</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV डिव्हाइस स्टोरेज पूर्ण भरलेले आहे. जागा मोकळी करण्यासाठी काही फाईल हटवा."</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV डिव्हाइस स्टोरेज पूर्ण भरलेले आहे. जागा मोकळी करण्यासाठी काही फाइल हटवा."</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"फोन संचयन पूर्ण भरले आहे. स्थान मोकळे करण्यासाठी काही फाइल हटवा."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="other">प्रमाणपत्र अधिकार इंस्टॉल केले</item>
@@ -195,7 +195,7 @@
<string name="location_changed_notification_text" msgid="7158423339982706912">"अधिक जाणून घेण्यासाठी तुमच्या आयटी ॲडमिनशी संपर्क साधा"</string>
<string name="country_detector" msgid="7023275114706088854">"कंट्री डिटेक्टर"</string>
<string name="location_service" msgid="2439187616018455546">"स्थान सेवा"</string>
- <string name="sensor_notification_service" msgid="7474531979178682676">"सेंसर सूचना सेवा"</string>
+ <string name="sensor_notification_service" msgid="7474531979178682676">"सेन्सर सूचना सेवा"</string>
<string name="twilight_service" msgid="8964898045693187224">"ट्वायलाइट सेवा"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"तुमचे डिव्हाइस मिटविले जाईल"</string>
<string name="factory_reset_message" msgid="2657049595153992213">"प्रशासक अ‍ॅप वापरता येणार नाही. तुमचे डिव्हाइस आता साफ केले जाईल.\n\nतुम्हाला कुठलेही प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
@@ -314,7 +314,7 @@
<string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string>
<string name="permgroupdesc_phone" msgid="270048070781478204">"फोन कॉल आणि व्यवस्थापित"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"शरीर सेन्सर"</string>
- <string name="permgroupdesc_sensors" msgid="2610631290633747752">"आपल्‍या महत्त्वाच्या मापनांविषयी सेंसर डेटा अ‍ॅक्सेस करा"</string>
+ <string name="permgroupdesc_sensors" msgid="2610631290633747752">"आपल्‍या महत्त्वाच्या मापनांविषयी सेन्सर डेटा अ‍ॅक्सेस करा"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"विंडोमधील आशय पुन्हा मिळवा"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"तुम्ही वापरत असलेल्‍या विंडोमधील आशय तपासा."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"स्पर्श करून अन्वेषण सुरू करा"</string>
@@ -386,7 +386,7 @@
<string name="permlab_getPackageSize" msgid="375391550792886641">"अ‍ॅप संचयन स्थान मोजा"</string>
<string name="permdesc_getPackageSize" msgid="742743530909966782">"अ‍ॅप ला त्याचा कोड, डेटा आणि कॅशे आकार पुनर्प्राप्त करण्यासाठी अनुमती देते"</string>
<string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टम सेटिंग्ज सुधारित करा"</string>
- <string name="permdesc_writeSettings" msgid="8293047411196067188">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स आपल्या सिस्टीमचे कॉन्फिगरेशन दूषित करू शकतात."</string>
+ <string name="permdesc_writeSettings" msgid="8293047411196067188">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स आपल्या सिस्टीमचे कॉंफिगरेशन दूषित करू शकतात."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"सुरूवातीस चालवा"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर टॅबलेटला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"सिस्टम बूट होणे संपल्यावर ॲपला स्वतः सुरू होण्याची अनुमती देते. यामुळे तुमच्या Android TV डिव्हाइसला सुरू होण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर डिव्हाइसलाच धीमे करण्याची अनुमती ॲपला देते."</string>
@@ -409,15 +409,15 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, तुमच्या Android TV डिव्हाइसचा कॉल लॉग सुधारित करण्यासाठी ॲपला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"शरीर सेंसर (हृदय गती मॉनिटरसारखे) अ‍ॅक्सेस करा"</string>
+ <string name="permlab_bodySensors" msgid="3411035315357380862">"शरीर सेन्सर (हृदय गती मॉनिटरसारखे) अ‍ॅक्सेस करा"</string>
<string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"हृदय गती सारख्या, आपल्या शारीरिक स्थितीचे नियंत्रण करणार्‍या सेन्सरवरून डेटामध्ये प्रवेश करण्यासाठी ॲपला अनुमती देते."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"हा अ‍ॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"हे ॲप तुमच्या Android TV डिव्हाइसवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"हे अ‍ॅप तुमच्या Android TV डिव्हाइसवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"हा अ‍ॅप आपल्या फोनवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"कॅलेंडर इव्हेंट जोडा किंवा बदला आणि मालकाला न कळवता अतिथींना ईमेल पाठवा"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"हा अ‍ॅप आपल्या टॅब्लेटवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"हे ॲप तुमच्या Android TV डिव्हाइसवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हे अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"हे अ‍ॅप तुमच्या Android TV डिव्हाइसवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हे अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"हा अ‍ॅप आपल्या फोनवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"अतिरिक्त स्थान प्रदाता आदेश अ‍ॅक्सेस करा"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"अ‍ॅपला अतिरिक्त स्‍थान प्रदाता आदेशावर प्रवेश करण्‍याची अनुमती देते. हे कदाचित अ‍ॅपला GPS किंवा इतर स्‍थान स्रोत च्या ऑपरेशनमध्‍ये हस्तक्षेप करण्‍याची अनुमती देऊ शकते."</string>
@@ -558,7 +558,7 @@
<string name="fingerprint_error_canceled" msgid="540026881380070750">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"वापरकर्त्याने फिंगरप्रिंट ऑपरेशन रद्द केले."</string>
<string name="fingerprint_error_lockout" msgid="7853461265604738671">"खूप प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
- <string name="fingerprint_error_lockout_permanent" msgid="3895478283943513746">"खूप प्रयत्न करून झाले. फिंगरप्रिंट सेंसर बंद आहे."</string>
+ <string name="fingerprint_error_lockout_permanent" msgid="3895478283943513746">"खूप प्रयत्न करून झाले. फिंगरप्रिंट सेन्सर बंद आहे."</string>
<string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"पुन्हा प्रयत्न करा."</string>
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोणत्याही फिंगरप्रिंटची नोंद झाली नाही"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
@@ -650,7 +650,7 @@
<string name="permlab_bindDreamService" msgid="4776175992848982706">"स्‍वप्न सेवेवर प्रतिबद्ध करा"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"होल्‍डरला स्‍वप्नसेवेच्या शीर्ष-स्‍तराच्या इंटरफेसशी प्रतिबद्ध करण्‍यास अनुमती देते. सामान्‍य अ‍ॅप्‍सकरिता कधीही आवश्‍यक नसते."</string>
<string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"वाहकाद्वारे-प्रदान केलेल्‍या कॉन्‍फिगरेशन अ‍ॅपची विनंती करा"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"होल्‍डरला वाहकद्वारे-प्रदान केलेल्या कॉन्फिगरेशन अ‍ॅपची विनंती करण्‍याची अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"होल्‍डरला वाहकद्वारे-प्रदान केलेल्या कॉंफिगरेशन अ‍ॅपची विनंती करण्‍याची अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"नेटवर्क स्‍थितींवरील निरीक्षणांसाठी ऐका"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"अनु्प्रयोगाला नेटवर्क स्‍थितींवरील निरीक्षणे ऐकण्‍यासाठी अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"इनपुट डिव्हाइस कॅलिब्रेशन बदला"</string>
@@ -666,7 +666,7 @@
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"वाहक सेवांवर प्रतिबद्ध करा"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"वाहक सेवांवर प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य ॲप्ससाठी कधीही आवश्यकता नसावी."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"व्यत्यय आणू नका अ‍ॅक्सेस करा"</string>
- <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"व्यत्यय आणू नका कॉन्फिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी ॲपला अनुमती देते."</string>
+ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"व्यत्यय आणू नका कॉंफिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी ॲपला अनुमती देते."</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"व्ह्यू परवानगी वापर सुरू करा"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"धारकास अ‍ॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अ‍ॅप्ससाठी कधीही आवश्यकता नसते."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करा"</string>
@@ -745,7 +745,7 @@
</string-array>
<string name="phoneTypeCustom" msgid="5120365721260686814">"कस्टम"</string>
<string name="phoneTypeHome" msgid="3880132427643623588">"घर"</string>
- <string name="phoneTypeMobile" msgid="1178852541462086735">"मोबाईल"</string>
+ <string name="phoneTypeMobile" msgid="1178852541462086735">"मोबाइल"</string>
<string name="phoneTypeWork" msgid="6604967163358864607">"कार्य"</string>
<string name="phoneTypeFaxWork" msgid="6757519896109439123">"कार्य फॅक्स"</string>
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"निवास फॅक्स"</string>
@@ -760,7 +760,7 @@
<string name="phoneTypeRadio" msgid="2637819130239264771">"रेडिओ"</string>
<string name="phoneTypeTelex" msgid="2558783611711876562">"टेलेक्स"</string>
<string name="phoneTypeTtyTdd" msgid="532038552105328779">"TTY TDD"</string>
- <string name="phoneTypeWorkMobile" msgid="7522314392003565121">"कार्य मोबाईल"</string>
+ <string name="phoneTypeWorkMobile" msgid="7522314392003565121">"कार्य मोबाइल"</string>
<string name="phoneTypeWorkPager" msgid="3748332310638505234">"कार्य पेजर"</string>
<string name="phoneTypeAssistant" msgid="757550783842231039">"असिस्टंट"</string>
<string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
@@ -772,7 +772,7 @@
<string name="emailTypeHome" msgid="1597116303154775999">"घर"</string>
<string name="emailTypeWork" msgid="2020095414401882111">"कार्य"</string>
<string name="emailTypeOther" msgid="5131130857030897465">"अन्य"</string>
- <string name="emailTypeMobile" msgid="787155077375364230">"मोबाईल"</string>
+ <string name="emailTypeMobile" msgid="787155077375364230">"मोबाइल"</string>
<string name="postalTypeCustom" msgid="5645590470242939129">"कस्टम"</string>
<string name="postalTypeHome" msgid="7562272480949727912">"घर"</string>
<string name="postalTypeWork" msgid="8553425424652012826">"कार्य"</string>
@@ -874,11 +874,11 @@
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"खाते अनलॉक करा"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"बरेच पॅटर्न प्रयत्न"</string>
<string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"अनलॉक करण्यासाठी, आपल्या Google खात्यासह साइन इन करा."</string>
- <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"वापरकर्तानाव (ईमेल)"</string>
+ <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"वापरकर्ता नाव (ईमेल)"</string>
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"पासवर्ड"</string>
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"साइन इन करा"</string>
- <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"अवैध वापरकर्तानाव किंवा पासवर्ड."</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"तुमचे वापरकर्तानाव किंवा पासवर्ड विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
+ <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"अवैध वापरकर्ता नाव किंवा पासवर्ड."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"तुमचे वापरकर्ता नाव किंवा पासवर्ड विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
<string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"तपासत आहे..."</string>
<string name="lockscreen_unlock_label" msgid="4648257878373307582">"अनलॉक करा"</string>
<string name="lockscreen_sound_on_label" msgid="1660281470535492430">"ध्वनी सुरू"</string>
@@ -954,7 +954,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"ब्राउझरने भेट दिलेल्या सर्व URL चा इतिहास आणि ब्राउझरचे सर्व बुकमार्क वाचण्यास अ‍ॅप ला अनुमती देते. टीप: या परवानगीची तृतीय-पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमता असलेल्या अन्य अनुप्रयोगांद्वारे अंमलबजावणी करू शकत नाही."</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"वेब बुकमार्क आणि इतिहास लिहा"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"तुमच्या टॅब्लेटवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अ‍ॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"तुमच्या Android TV डिव्हाइसवर साठवलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी ॲप ला अनुमती देते. हे ॲपला ब्राउझर डेटा मिटवण्याची किंवा सुधारित करण्याची परवानगी देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अ‍ॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"तुमच्या Android TV डिव्हाइसवर साठवलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. हे अ‍ॅपला ब्राउझर डेटा मिटवण्याची किंवा सुधारित करण्याची परवानगी देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अ‍ॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"तुमच्या फोनवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अ‍ॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"अलार्म सेट करा"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"इंस्टॉल केलेल्या अलार्म घड्याळ ॲपमध्ये अलार्म सेट करण्यासाठी ॲपला अनुमती देते. काही अलार्म घड्याळ ॲप्समध्ये हे वैशिष्ट्य नसू शकते."</string>
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"स्पेस"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"एंटर"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"हटवा"</string>
- <string name="search_go" msgid="2141477624421347086">"शोध"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"शोधा…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"शोध"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"शोध क्वेरी"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"क्‍वेरी साफ करा"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"क्वेरी सबमिट करा"</string>
@@ -1266,8 +1266,8 @@
<string name="sms_control_yes" msgid="4858845109269524622">"अनुमती द्या"</string>
<string name="sms_control_no" msgid="4845717880040355570">"नकार द्या"</string>
<string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; हा &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;वर एक मेसेज पाठवू इच्छितो."</string>
- <string name="sms_short_code_details" msgid="2723725738333388351">"यामुळे आपल्या मोबाईल खात्यावर "<b>"शुल्क आकारले जाऊ शकते"</b>"."</string>
- <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"यामुळे आपल्या मोबाईल खात्यावर शुल्क आकारले जाऊ शकते."</b></string>
+ <string name="sms_short_code_details" msgid="2723725738333388351">"यामुळे आपल्या मोबाइल खात्यावर "<b>"शुल्क आकारले जाऊ शकते"</b>"."</string>
+ <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"यामुळे आपल्या मोबाइल खात्यावर शुल्क आकारले जाऊ शकते."</b></string>
<string name="sms_short_code_confirm_allow" msgid="920477594325526691">"पाठवा"</string>
<string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"रद्द करा"</string>
<string name="sms_short_code_remember_choice" msgid="1374526438647744862">"माझी वड लक्षात ठेवा"</string>
@@ -1275,10 +1275,10 @@
<string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"नेहमी अनुमती द्या"</string>
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"कधीही अनुमती देऊ नका"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"सिम कार्ड काढले"</string>
- <string name="sim_removed_message" msgid="9051174064474904617">"तुम्ही एक वैध सिम कार्ड घालून प्रारंभ करेपर्यंत मोबाईल नेटवर्क अनुपलब्ध असेल."</string>
+ <string name="sim_removed_message" msgid="9051174064474904617">"तुम्ही एक वैध सिम कार्ड घालून प्रारंभ करेपर्यंत मोबाइल नेटवर्क अनुपलब्ध असेल."</string>
<string name="sim_done_button" msgid="6464250841528410598">"पूर्ण झाले"</string>
<string name="sim_added_title" msgid="7930779986759414595">"सिम कार्ड जोडले"</string>
- <string name="sim_added_message" msgid="6602906609509958680">"मोबाईल नेटवर्कवर अ‍ॅक्सेस करण्यासाठी तुमचे डिव्हाइस रीस्टार्ट करा."</string>
+ <string name="sim_added_message" msgid="6602906609509958680">"मोबाइल नेटवर्कवर अ‍ॅक्सेस करण्यासाठी तुमचे डिव्हाइस रीस्टार्ट करा."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"रीस्टार्ट"</string>
<string name="install_carrier_app_notification_title" msgid="5712723402213090102">"मोबाइल सेवा अ‍ॅक्टिव्हेट करा"</string>
<string name="install_carrier_app_notification_text" msgid="2781317581274192728">"तुमचे नवीन सिम अ‍ॅक्टिव्हेट करण्यासाठी वाहकाचे अ‍ॅप डाउनलोड करा"</string>
@@ -1329,7 +1329,7 @@
<string name="select_input_method" msgid="3971267998568587025">"इनपुट पद्धत निवडा"</string>
<string name="show_ime" msgid="6406112007347443383">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string>
<string name="hardware" msgid="1800597768237606953">"व्हर्च्युअल कीबोर्ड दर्शवा"</string>
- <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"वास्तविक कीबोर्ड कॉन्फिगर करा"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"वास्तविक कीबोर्ड कॉंफिगर करा"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा आणि लेआउट निवडण्यासाठी टॅप करा"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"झूम नियंत्रणासाठी दोनदा टॅप करा"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट जोडू शकलो नाही."</string>
<string name="ime_action_go" msgid="5536744546326495436">"जा"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"शोधा"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"पाठवा"</string>
<string name="ime_action_next" msgid="4169702997635728543">"पुढे"</string>
<string name="ime_action_done" msgid="6299921014822891569">"पूर्ण झाले"</string>
@@ -1433,8 +1433,8 @@
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"कायम सुरू असलेल्या VPN मधून डिस्कनेक्ट केले"</string>
<string name="vpn_lockdown_error" msgid="4453048646854247947">"कायम सुरू असलेल्या VPN शी कनेक्ट करता आले नाही"</string>
<string name="vpn_lockdown_config" msgid="8331697329868252169">"नेटवर्क किंवा VPN सेटिंग्ज बदला"</string>
- <string name="upload_file" msgid="8651942222301634271">"फाईल निवडा"</string>
- <string name="no_file_chosen" msgid="4146295695162318057">"फाईल निवडली नाही"</string>
+ <string name="upload_file" msgid="8651942222301634271">"फाइल निवडा"</string>
+ <string name="no_file_chosen" msgid="4146295695162318057">"फाइल निवडली नाही"</string>
<string name="reset" msgid="3865826612628171429">"रीसेट करा"</string>
<string name="submit" msgid="862795280643405865">"सबमिट करा"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"ड्रायव्हिंग अ‍ॅप सुरू आहे"</string>
@@ -1599,11 +1599,11 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"पिन कोड जुळत नाहीत"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"बरेच पॅटर्न प्रयत्न"</string>
<string name="kg_login_instructions" msgid="3619844310339066827">"अनलॉक करण्यासाठी, आपल्या Google खात्यासह साइन इन करा."</string>
- <string name="kg_login_username_hint" msgid="1765453775467133251">"वापरकर्तानाव (ईमेल)"</string>
+ <string name="kg_login_username_hint" msgid="1765453775467133251">"वापरकर्ता नाव (ईमेल)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"पासवर्ड"</string>
<string name="kg_login_submit_button" msgid="893611277617096870">"साइन इन करा"</string>
- <string name="kg_login_invalid_input" msgid="8292367491901220210">"अवैध वापरकर्तानाव किंवा पासवर्ड."</string>
- <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"तुमचे वापरकर्तानाव किंवा पासवर्ड विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
+ <string name="kg_login_invalid_input" msgid="8292367491901220210">"अवैध वापरकर्ता नाव किंवा पासवर्ड."</string>
+ <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"तुमचे वापरकर्ता नाव किंवा पासवर्ड विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"खाते तपासत आहे…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"तुम्ही तुमचा पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"तुम्ही तुमचा पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"सुचवलेल्या भाषा"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"सर्व भाषा"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"सर्व प्रदेश"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"शोध"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"अ‍ॅप उपलब्ध नाही"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> आत्ता उपलब्ध नाही. हे <xliff:g id="APP_NAME_1">%2$s</xliff:g> कडून व्यवस्थापित केले जाते."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"अधिक जाणून घ्या"</string>
@@ -1909,7 +1909,7 @@
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो प्रारंभ करत आहे..."</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"डिव्हाइस रीसेट करत आहे..."</string>
<string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> अक्षम केले"</string>
- <string name="conference_call" msgid="5731633152336490471">"कॉन्फरन्स कॉल"</string>
+ <string name="conference_call" msgid="5731633152336490471">"कॉंफरन्स कॉल"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"टूलटिप"</string>
<string name="app_category_game" msgid="4534216074910244790">"गेम"</string>
<string name="app_category_audio" msgid="8296029904794676222">"संगीत आणि ऑडिओ"</string>
@@ -1956,7 +1956,7 @@
<string name="autofill_save_type_debit_card" msgid="3169397504133097468">"डेबिट कार्ड"</string>
<string name="autofill_save_type_payment_card" msgid="6555012156728690856">"पेमेंट कार्ड"</string>
<string name="autofill_save_type_generic_card" msgid="1019367283921448608">"कार्ड"</string>
- <string name="autofill_save_type_username" msgid="1018816929884640882">"वापरकर्तानाव"</string>
+ <string name="autofill_save_type_username" msgid="1018816929884640882">"वापरकर्ता नाव"</string>
<string name="autofill_save_type_email_address" msgid="1303262336895591924">"ईमेल ॲड्रेस"</string>
<string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"शांत रहा आणि जवळपास निवारा शोधा."</string>
<string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"किनारपट्टीचे प्रदेश आणि नदीकाठची क्षेत्रे त्वरित रिकामी करून उंच मैदानासारख्या अधिक सुरक्षित ठिकाणी जा."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 8a0dd91a7370..b9bf08fa6d7e 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1093,7 +1093,7 @@
<string name="cut" msgid="2561199725874745819">"ဖြတ်ရန်"</string>
<string name="copy" msgid="5472512047143665218">"ကူးရန်"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"ကလစ်ဘုတ်သို့ မိတ္တူကူးခြင်း မအောင်မြင်ပါ"</string>
- <string name="paste" msgid="461843306215520225">"Paste"</string>
+ <string name="paste" msgid="461843306215520225">"ကူးထည့်ရန်"</string>
<string name="paste_as_plain_text" msgid="7664800665823182587">"စာသားအတိုင်း ကူးထည့်ပါ"</string>
<string name="replace" msgid="7842675434546657444">"အစားထိုခြင်း"</string>
<string name="delete" msgid="1514113991712129054">"ဖျက်ရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1d15398f8539..5099d4f4de03 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1091,7 +1091,7 @@
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="1532369154488982046">"Merk alt"</string>
<string name="cut" msgid="2561199725874745819">"Klipp ut"</string>
- <string name="copy" msgid="5472512047143665218">"Kopier"</string>
+ <string name="copy" msgid="5472512047143665218">"Kopiér"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Kunne ikke kopiere til utklippstavlen"</string>
<string name="paste" msgid="461843306215520225">"Lim inn"</string>
<string name="paste_as_plain_text" msgid="7664800665823182587">"Lim inn som ren tekst"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b295fdef79e7..d639d3954b38 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -78,18 +78,18 @@
<string name="serviceNotProvisioned" msgid="8289333510236766193">"सेवाको व्यवस्था छैन।"</string>
<string name="CLIRPermanent" msgid="166443681876381118">"तपाईं कलर ID सेटिङ परिवर्तन गर्न सक्नुहुन्न।"</string>
<string name="RestrictedOnDataTitle" msgid="1500576417268169774">"कुनै पनि मोबाइल डेटा सेवा उपलब्ध छैन"</string>
- <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"आपतकालीन कल सेवा उपलब्ध छैन"</string>
+ <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"आपत्‌कालीन कल सेवा उपलब्ध छैन"</string>
<string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"कुनै पनि भ्वाइस सेवा उपलब्ध छैन"</string>
<string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"कुनै पनि भ्वाइस वा आपातकालीन कल सेवा उपलब्ध छैन"</string>
<string name="RestrictedStateContent" msgid="7693575344608618926">"तपाईंको सेवा प्रदायकले अस्थायी रूपमा निष्क्रिय पार्नुभएको"</string>
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> का लागि तपाईंको सेवा प्रदायकले अस्थायी रूपमा निष्क्रिय पार्नुभएको"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्कमाथि पहुँच राख्न सकिएन"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"रुचाइएको नेटवर्क परिवर्तन गरी हेर्नुहोस्‌। परिवर्तन गर्न ट्याप गर्नुहोस्‌।"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपतकालीन कल सेवा अनुपलब्ध छ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi मार्फत आपतकालीन कल गर्न सकिँदैन"</string>
+ <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपत्‌कालीन कल सेवा अनुपलब्ध छ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi मार्फत आपत्‌कालीन कल गर्न सकिँदैन"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्टहरू"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"कल फर्वार्ड गर्ने सेवा"</string>
- <string name="notification_channel_emergency_callback" msgid="54074839059123159">"आपतकालीन कलब्याक मोड"</string>
+ <string name="notification_channel_emergency_callback" msgid="54074839059123159">"आपत्‌कालीन कलब्याक मोड"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"मोबाइल डेटाको स्थिति"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS सन्देशहरू"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"भ्वाइस मेल सन्देशहरू"</string>
@@ -142,7 +142,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi कलिङ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
- <string name="wifi_calling_off_summary" msgid="5626710010766902560">"निष्क्रिय"</string>
+ <string name="wifi_calling_off_summary" msgid="5626710010766902560">"अफ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi मार्फत कल गर्नुहोस्"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"मोबाइल नेटवर्कमार्फत कल गर्नुहोस्"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi मात्र"</string>
@@ -201,7 +201,7 @@
<string name="factory_reset_message" msgid="2657049595153992213">"प्रशासकको एप प्रयोग गर्न मिल्दैन। तपाईंको यन्त्रको डेटा अब मेटाइने छ।\n\nतपाईंसँग प्रश्नहरू भएका खण्डमा आफ्नो संगठनका प्रशासकसँग सम्पर्क गर्नुहोस्।"</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string>
<string name="personal_apps_suspension_title" msgid="7561416677884286600">"आफ्नो कार्य प्रोफाइल सक्रिय गर्नुहोस्"</string>
- <string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत अनुप्रयोगहरूलाई रोक लगाइन्छ"</string>
+ <string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत एपहरूलाई रोक लगाइन्छ"</string>
<string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"मिति <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> बजे व्यक्तिगत एपहरूलाई रोक लगाइने छ। तपाईंका IT एडमिन तपाईंलाई आफ्नो कार्य प्रोफाइल <xliff:g id="NUMBER">%3$d</xliff:g> भन्दा धेरै दिन निष्क्रिय राख्ने अनुमति दिनुहुन्न।"</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"सक्रिय गर्नुहोस्"</string>
<string name="me" msgid="6207584824693813140">"मलाई"</string>
@@ -229,7 +229,7 @@
<string name="shutdown_confirm" product="default" msgid="136816458966692315">"तपाईँको फोन बन्द हुने छ।"</string>
<string name="shutdown_confirm_question" msgid="796151167261608447">"के तपाईं बन्द गर्न चाहनुहुन्छ?"</string>
<string name="reboot_safemode_title" msgid="5853949122655346734">"सुरक्षित मोडमा पुनःबुट गर्नुहोस्"</string>
- <string name="reboot_safemode_confirm" msgid="1658357874737219624">"सुरक्षित मोडमा तपाईं पुनःबुट गर्न चाहनु हुन्छ? तपाईंले स्थापना गरेका सबै तेस्रो पक्षका अनुप्रयोगहरूलाई असक्षम गराउने छ।"</string>
+ <string name="reboot_safemode_confirm" msgid="1658357874737219624">"सुरक्षित मोडमा तपाईं पुनःबुट गर्न चाहनु हुन्छ? तपाईंले स्थापना गरेका सबै तेस्रो पक्षका एपहरूलाई असक्षम गराउने छ।"</string>
<string name="recent_tasks_title" msgid="8183172372995396653">"नयाँ"</string>
<string name="no_recent_tasks" msgid="9063946524312275906">"कुनै नयाँ एपहरू छैनन्।"</string>
<string name="global_actions" product="tablet" msgid="4412132498517933867">"ट्याब्लेट विकल्पहरू"</string>
@@ -239,7 +239,7 @@
<string name="global_action_power_off" msgid="4404936470711393203">"बन्द गर्नुहोस्"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"पावर"</string>
<string name="global_action_restart" msgid="4678451019561687074">"पुनः सुरु गर्नुहोस्"</string>
- <string name="global_action_emergency" msgid="1387617624177105088">"आपतकालीन"</string>
+ <string name="global_action_emergency" msgid="1387617624177105088">"आपत्‌कालीन"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"बग रिपोर्ट"</string>
<string name="global_action_logout" msgid="6093581310002476511">"सत्रको अन्त्य गर्नुहोस्"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"स्क्रिनसट"</string>
@@ -302,13 +302,13 @@
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
<string name="permgrouplab_storage" msgid="1938416135375282333">"फाइल र मिडिया"</string>
- <string name="permgroupdesc_storage" msgid="6351503740613026600">"तपाईंको यन्त्रमा तस्बिर, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्"</string>
+ <string name="permgroupdesc_storage" msgid="6351503740613026600">"तपाईंको यन्त्रमा फोटो, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफोन"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक क्रियाकलाप"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"आफ्नो शारीरिक क्रियाकलापको डेटामाथि पहुँच राख्नु"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"क्यामेरा"</string>
- <string name="permgroupdesc_camera" msgid="7585150538459320326">"तस्बिर खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्"</string>
+ <string name="permgroupdesc_camera" msgid="7585150538459320326">"फोटो खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"कलका लगहरू"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"फोन कलको लग पढ्नुहोस् र लेख्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string>
@@ -343,34 +343,34 @@
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"एपलाई अन्य नम्बरमा कल पुर्ननिर्देश वा समग्र कल परित्याग विकल्प सहित बहिर्गमन कल समयमा डायल गर्दाको नम्बर हेर्न अनुमति दिन्छ।"</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"फोन कलहरूको जवाफ दिनुहोस्"</string>
<string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"एपलाई आगमन फोन कलको जवाफ दिन अनुमति दिन्छ।"</string>
- <string name="permlab_receiveSms" msgid="505961632050451881">"पाठ सन्देशहरू (SMS) प्राप्त गर्नुहोस्"</string>
+ <string name="permlab_receiveSms" msgid="505961632050451881">"टेक्स्ट म्यासेजहरू (SMS) प्राप्त गर्नुहोस्"</string>
<string name="permdesc_receiveSms" msgid="1797345626687832285">"एपलाई SMS सन्देशहरू प्राप्त गर्न र प्रक्रिया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
<string name="permlab_receiveMms" msgid="4000650116674380275">"पाठ सन्देश (MMS) प्राप्त गर्नुहोस्"</string>
<string name="permdesc_receiveMms" msgid="958102423732219710">"एपलाई MMS सन्देशहरू प्राप्त गर्न र प्रकृया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"मोबाइल प्रसारणसम्बन्धी सन्देशहरू फर्वार्ड गर्नुहोस्"</string>
- <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"मोबाइल प्रसारणसम्बन्धी सन्देशहरू प्राप्त हुनासाथै तिनीहरूलाई फर्वार्ड गर्नका लागि यसले एपलाई मोबाइल प्रसारण मोड्युलमा जोडिने अनुमति दिन्छ। तपाईंलाई कतिपय स्थानमा आपत्कालीन अवस्थाका बारेमा जानकारी दिनका लागि मोबाइल प्रसारणसम्बन्धी अलर्टहरू पठाइन्छ। हानिकारक एपहरूले आपत्कालीन मोबाइल प्रसारण प्राप्त हुँदा तपाईंको यन्त्रलाई कार्य सम्पादन गर्ने वा सञ्चालित हुने क्रममा हस्तक्षेप गर्न सक्छन्।"</string>
+ <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"मोबाइल प्रसारणसम्बन्धी सन्देशहरू प्राप्त हुनासाथै तिनीहरूलाई फर्वार्ड गर्नका लागि यसले एपलाई मोबाइल प्रसारण मोड्युलमा जोडिने अनुमति दिन्छ। तपाईंलाई कतिपय स्थानमा आपत्‌कालीन अवस्थाका बारेमा जानकारी दिनका लागि मोबाइल प्रसारणसम्बन्धी अलर्टहरू पठाइन्छ। हानिकारक एपहरूले आपत्‌कालीन मोबाइल प्रसारण प्राप्त हुँदा तपाईंको यन्त्रलाई कार्य सम्पादन गर्ने वा सञ्चालित हुने क्रममा हस्तक्षेप गर्न सक्छन्।"</string>
<string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"सेल प्रसारित सन्देशहरू पढ्नुहोस्"</string>
- <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"तपाईंको उपकरणद्वारा प्राप्त सेल प्रसारण सन्देशहरू एपलाई पढ्न अनुमति दिन्छ। सेल प्रसारण चेतावनीहरू केही स्थानहरूमा तपाईंलाई आपतकालीन गतिविधिहरूको बारेमा सचेत गराउन गरिएका छन्। खराब एपहरूले एउटा आपतकालीन सेल प्रसारण प्राप्त गर्दछ जब तपाईंको उपकरणको प्रदर्शन वा अपरेशनको साथ हस्तक्षेप गर्न सक्दछन्।"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"तपाईंको उपकरणद्वारा प्राप्त सेल प्रसारण सन्देशहरू एपलाई पढ्न अनुमति दिन्छ। सेल प्रसारण चेतावनीहरू केही स्थानहरूमा तपाईंलाई आपत्‌कालीन गतिविधिहरूको बारेमा सचेत गराउन गरिएका छन्। खराब एपहरूले एउटा आपत्‌कालीन सेल प्रसारण प्राप्त गर्दछ जब तपाईंको उपकरणको प्रदर्शन वा अपरेशनको साथ हस्तक्षेप गर्न सक्दछन्।"</string>
<string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"सदस्य बनाइका फिडहरू पढ्नुहोस्"</string>
<string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"एपलाई अहिलेको समीकरण गरिएका सूचकहरू बारे विवरणहरू लिने अनुमति दिन्छ।"</string>
<string name="permlab_sendSms" msgid="7757368721742014252">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
<string name="permdesc_sendSms" msgid="6757089798435130769">"एपलाई SMS सन्देशहरू पठाउन अनुमति दिन्छ। यसले अप्रत्यासित चार्जहरूको परिणाम दिन सक्दछ। खराब एपहरूले तपाईंको पुष्टि बिना सन्देशहरू पठाएर तपाईंको पैसा खर्च गराउन सक्दछ।"</string>
- <string name="permlab_readSms" msgid="5164176626258800297">"तपाईंका पाठ सन्देशहरू (SMS वा MMS) पढ्नुहोस्"</string>
+ <string name="permlab_readSms" msgid="5164176626258800297">"तपाईंका टेक्स्ट म्यासेजहरू (SMS वा MMS) पढ्नुहोस्"</string>
<string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"यस अनुप्रयोगले तपाईंको ट्याब्लेटमा भण्डारण गरिएका सबै SMS (पाठ) सन्देशहरू पढ्न सक्छ।"</string>
<string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"यस अनुप्रयोगले तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका सबै SMS.(पाठ) सन्देशहरू पढ्न सक्छ।"</string>
<string name="permdesc_readSms" product="default" msgid="774753371111699782">"यस अनुप्रयोगले तपाईंको फोनमा भण्डारण गरिएका सबै SMS (पाठ) सन्देशहरू पढ्न सक्छ।"</string>
- <string name="permlab_receiveWapPush" msgid="4223747702856929056">"पाठ सन्देशहरू (WAP) प्राप्त गर्नुहोस्"</string>
- <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"WAP सन्देशहरू प्राप्त गर्न र प्रशोधन गर्न एपलाई अनुमति दिन्छ। यो अनुमतिमा मोनिटर गर्ने वा तपाईँलाई पठाइएका सन्देशहरू तपाईँलाई नदेखाई मेट्ने क्षमता समावेश हुन्छ।"</string>
+ <string name="permlab_receiveWapPush" msgid="4223747702856929056">"टेक्स्ट म्यासेजहरू (WAP) प्राप्त गर्नुहोस्"</string>
+ <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"WAP सन्देशहरू प्राप्त गर्न र प्रशोधन गर्न एपलाई अनुमति दिन्छ। यो अनुमतिमा मोनिटर गर्ने वा तपाईँलाई पठाइएका म्यासेजहरू तपाईँलाई नदेखाई मेट्ने क्षमता समावेश हुन्छ।"</string>
<string name="permlab_getTasks" msgid="7460048811831750262">"चलिरहेका एपहरू पुनःबहाली गर्नुहोस्"</string>
<string name="permdesc_getTasks" msgid="7388138607018233726">"वर्तमानमा र भरखरै चलिरहेका कार्यहरू बारेको सूचना पुनःबहाली गर्न एपलाई अनुमित दिन्छ। यसले उपकरणमा प्रयोग भएका अनुप्रयोगहरूको बारेमा सूचना पत्ता लगाउन एपलाई अनुमति दिन सक्छ।"</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"प्रोफाइल र यन्त्र मालिकहरूको व्यवस्थापन गराउनुहोस्"</string>
- <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"अनुप्रयोगहरूलाई प्रोफाइल र यन्त्र मालिकहरू सेट गर्न अनुमति दिनुहोस्।"</string>
- <string name="permlab_reorderTasks" msgid="7598562301992923804">"चलिरहेका अनुप्रयोगहरूलाई पुनःक्रम गराउनुहोस्"</string>
+ <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"एपहरूलाई प्रोफाइल र यन्त्र मालिकहरू सेट गर्न अनुमति दिनुहोस्।"</string>
+ <string name="permlab_reorderTasks" msgid="7598562301992923804">"चलिरहेका एपहरूलाई पुनःक्रम गराउनुहोस्"</string>
<string name="permdesc_reorderTasks" msgid="8796089937352344183">"कामहरूलाई अग्रभाग र पृष्ठभूमिमा सार्न एपलाई अनुमति दिन्छ। अनुप्रयोगले यो तपाईँको इनपुट बिना नै गर्न सक्छ।"</string>
<string name="permlab_enableCarMode" msgid="893019409519325311">"कार मोड सक्षम गर्नुहोस्"</string>
<string name="permdesc_enableCarMode" msgid="56419168820473508">"कार मोडलाई सक्षम पार्न एपलाई अनुमति दिन्छ।"</string>
<string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"एपहरू बन्द गर्नुहोस्"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"एपलाई अन्य अनुप्रयोगहरूको पृष्ठभूमि प्रक्रियाहरू बन्द गर्न अनुमति दिन्छ। यसले अन्य अनुप्रयोगहरूलाई चल्नबाट रोक्न सक्दछ।"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"एपलाई अन्य अनुप्रयोगहरूको पृष्ठभूमि प्रक्रियाहरू बन्द गर्न अनुमति दिन्छ। यसले अन्य एपहरूलाई चल्नबाट रोक्न सक्दछ।"</string>
<string name="permlab_systemAlertWindow" msgid="5757218350944719065">"यो एप अन्य एपहरूमाथि देखा पर्न सक्छ"</string>
<string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"यो एप अन्य एपहरूमाथि वा स्क्रिनका अन्य भागहरूमा देखा पर्न सक्छ। यसले एपको सामान्य प्रयोगमा अवरोध पुर्याउन सक्छ र अन्य एपहरू देखा पर्ने तरिकालाई परिवर्तन गर्न सक्छ।"</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"पृष्ठभूमिमा चलाउनुहोस्"</string>
@@ -378,7 +378,7 @@
<string name="permlab_useDataInBackground" msgid="783415807623038947">"पृष्ठभूमिमा डेटा प्रयोग गर्नुहोस्"</string>
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"यो अनुप्रयोगले पृष्ठभूमिमा डेटा प्रयोग गर्नसक्छ। यसले गर्दा धेरै डेटा प्रयोग हुनसक्छ।"</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"एपहरू जहिले पनि चल्ने बनाउनुहोस्"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि एपलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य अनुप्रयोगहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि एपलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य एपहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
<string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"एपलाई आफ्ना केही अंशहरू मेमोरीमा स्थायी रूपमा राख्ने अनुमति दिन्छ। यसले गर्दा अन्य अनुप्रयोगहरूका लागि मेमोरीको अभाव हुन सक्ने भएकाले तपाईंको Android टिभी यन्त्र सुस्त हुन सक्छ।"</string>
<string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य एपहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"अग्रभूमिको सेवा सञ्चालन गर्नुहोस्"</string>
@@ -396,9 +396,9 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"एपलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android टिभी यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"औपचारिक प्रसारणलाई पठाउनको लागि एक एपलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"तपाईँका सम्पर्कहरू पढ्नुहोस्"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"तपाईँका सम्पर्कहरू परिवर्तन गर्नुहोस्"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"एपलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
<string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
@@ -435,17 +435,17 @@
<string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM लाई आदेश पठाउन एपलाई अनुमति दिन्छ। यो निकै खतरनाक हुन्छ।"</string>
<string name="permlab_activityRecognition" msgid="1782303296053990884">"शारीरिक गतिविधि पहिचान गर्नुहोस्‌"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"यो अनुप्रयोगले तपाईंको शारीरिक गतिविधिको पहिचान गर्न सक्छ।"</string>
- <string name="permlab_camera" msgid="6320282492904119413">"तस्बिरहरू र भिडियोहरू लिनुहोस्।"</string>
- <string name="permdesc_camera" msgid="1354600178048761499">"यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।"</string>
- <string name="permlab_systemCamera" msgid="3642917457796210580">"एप वा सेवालाई तस्बिर र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ"</string>
+ <string name="permlab_camera" msgid="6320282492904119413">"फोटोहरू र भिडियोहरू लिनुहोस्।"</string>
+ <string name="permdesc_camera" msgid="1354600178048761499">"यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ।"</string>
+ <string name="permlab_systemCamera" msgid="3642917457796210580">"एप वा सेवालाई फोटो र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"कुनै एप वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।"</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"कुनै क्यामेरा यन्त्र खोलिँदा (कुन अनुप्रयोगले खोलेको भन्ने बारेमा) वा बन्द गरिँदा यो अनुप्रयोगले कलब्याक प्राप्त गर्न सक्छ।"</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"कम्पन नियन्त्रण गर्नुहोस्"</string>
<string name="permdesc_vibrate" msgid="8733343234582083721">"एपलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।"</string>
<string name="permdesc_vibrator_state" msgid="7050024956594170724">"यो एपलाई कम्पनको स्थितिमाथि पहुँच राख्न दिनुहोस्।"</string>
<string name="permlab_callPhone" msgid="1798582257194643320">"फोन नम्बरहरूमा सीधै कल गर्नुहोस्"</string>
- <string name="permdesc_callPhone" msgid="5439809516131609109">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न एपलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले एपलाई आपतकालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब एपहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
+ <string name="permdesc_callPhone" msgid="5439809516131609109">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न एपलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले एपलाई आपत्‌कालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब एपहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कल सेवा पहुँच गर्नुहोस्"</string>
<string name="permdesc_accessImsCallService" msgid="6328551241649687162">"तपाईँको हस्तक्षेप बिना नै कल गर्न IMS सेवा प्रयोग गर्न एपलाई अनुमति दिन्छ।"</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"फोन स्थिति र पहिचान पढ्नुहोस्"</string>
@@ -614,7 +614,7 @@
<string name="permlab_readSyncSettings" msgid="6250532864893156277">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
<string name="permdesc_readSyncSettings" msgid="1325658466358779298">"एपलाई खाताको लागि सिंक सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको एप खातासँग सिंक भएको नभएको निर्धारण गर्न सक्दछ।"</string>
<string name="permlab_writeSyncSettings" msgid="6583154300780427399">"टगल सिंक खुला र बन्द"</string>
- <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"अनुप्रयोगहरूलाई खाताको लागि सिंक सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति एपको सिंक सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
+ <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"एपहरूलाई खाताको लागि सिंक सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति एपको सिंक सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"सिंक तथ्याङ्कहरू पढ्नुहोस्"</string>
<string name="permdesc_readSyncStats" msgid="3867809926567379434">"एपलाई खाताको लागि समीकरणको आँकडा समीकरण घटनाहरूको इतिहास र समीकरण गरिएको डेटाको मापन समेत, पढ्न अनुमति दिन्छ।"</string>
<string name="permlab_sdcardRead" msgid="5791467020950064920">"आफ्नो आदान प्रदान गरिएको भण्डारणको सामग्रीहरूहरू पढ्नुहोस्"</string>
@@ -642,9 +642,9 @@
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"नेटवर्क उपयोग लेखालाई परिमार्जन गर्नुहोस्"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"एपलाई कसरी अनुप्रयोगहरूको विरूद्धमा कसरी नेटवर्क उपयोगी अकाउन्टेड छ भनेर परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"सूचनाहरू पहुँच गर्नुहोस्"</string>
- <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य अनुप्रयोगहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन अनुप्रयोगहरूलाई अनुमति दिन्छ।"</string>
+ <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य अनुप्रयोगहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन एपहरूलाई अनुमति दिन्छ।"</string>
<string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"जानकारी श्रोता सेवामा बाँध्नुहोस्"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य एपहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
<string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"सर्त प्रदायक सेवामा जोड्न"</string>
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"सर्त प्रदायक सेवाको माथिल्लो स्तरको इन्टरफेसमा जोड्न बाहकलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"सपना सेवामा बाँध्नुहोस्"</string>
@@ -668,7 +668,7 @@
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"बाधा नपुर्याउँनुहोस् पहुँच गर्नुहोस्"</string>
<string name="permdesc_access_notification_policy" msgid="8538374112403845013">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्‍नको लागि एपलाई अनुमति दिनुहोस्।"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string>
- <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै अनुप्रयोगसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
+ <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै एपसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण एपहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"मनिटरको स्क्रिन अनलक गर्ने प्रयासहरू"</string>
@@ -823,13 +823,13 @@
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"गलत PIN कोड।"</string>
<string name="keyguard_label_text" msgid="3841953694564168384">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</string>
- <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"आपतकालीन नम्बर"</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"आपत्‌कालीन नम्बर"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"कुनै सेवा छैन"</string>
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"स्क्रिन लक गरिएको।"</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"अनलक वा आपतकालीन कल गर्न मेनु थिच्नुहोस्।"</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"अनलक वा आपत्‌कालीन कल गर्न मेनु थिच्नुहोस्।"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"अनलक गर्नु ढाँचा खिच्नुहोस्"</string>
- <string name="lockscreen_emergency_call" msgid="7500692654885445299">"आपतकालीन"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"आपत्‌कालीन"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"कलमा फर्किनुहोस्"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"सही!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"फेरि प्रयास गर्नुहोस्"</string>
@@ -851,7 +851,7 @@
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"रोक्नुहोस्"</string>
<string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"दोहोर्याउनुहोस्"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"फास्ट फर्वार्ड"</string>
- <string name="emergency_calls_only" msgid="3057351206678279851">"आपतकालीन कलहरू मात्र"</string>
+ <string name="emergency_calls_only" msgid="3057351206678279851">"आपत्‌कालीन कलहरू मात्र"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"नेटवर्क लक छ"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM कार्ड PUK-लक गरिएको छ।"</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"प्रयोगकर्ता निर्देशक वा ग्राहक सेवा सम्पर्क हर्नुहोस्।"</string>
@@ -1119,7 +1119,7 @@
<string name="dialog_alert_title" msgid="651856561974090712">"सावधानी"</string>
<string name="loading" msgid="3138021523725055037">"लोड हुँदै..."</string>
<string name="capital_on" msgid="2770685323900821829">"चालु"</string>
- <string name="capital_off" msgid="7443704171014626777">"बन्द"</string>
+ <string name="capital_off" msgid="7443704171014626777">"अफ"</string>
<string name="checked" msgid="9179896827054513119">"जाँच गरिएको"</string>
<string name="not_checked" msgid="7972320087569023342">"जाँच गरिएको छैन"</string>
<string name="whichApplication" msgid="5432266899591255759">"प्रयोग गरेर कारबाही पुरा गर्नुहोस्"</string>
@@ -1344,7 +1344,7 @@
<string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
<string name="ext_media_new_notification_message" msgid="6095403121990786986">"सेटअप गर्न ट्याप गर्नुहोस्"</string>
<string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"तपाईंले यो यन्त्र पुनः फर्म्याट गर्नु पर्ने हुन सक्छ। यो यन्त्र हटाउन ट्याप गर्नुहोस्।"</string>
- <string name="ext_media_ready_notification_message" msgid="777258143284919261">"तस्बिरहरू र मिडिया स्थानान्तरणका लागि"</string>
+ <string name="ext_media_ready_notification_message" msgid="777258143284919261">"फोटोहरू र मिडिया स्थानान्तरणका लागि"</string>
<string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g> मा समस्या देखियो"</string>
<string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ले काम गरिरहेको छैन"</string>
<string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"समस्या समाधान गर्न ट्याप गर्नुहोस्"</string>
@@ -1382,7 +1382,7 @@
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"बिग्रेको"</string>
<string name="ext_media_status_unsupported" msgid="5460509911660539317">"असमर्थित"</string>
<string name="ext_media_status_ejecting" msgid="7532403368044013797">"निकाल्दै..."</string>
- <string name="ext_media_status_formatting" msgid="774148701503179906">"फरम्याट गर्दै…"</string>
+ <string name="ext_media_status_formatting" msgid="774148701503179906">"फर्म्याट गर्दै…"</string>
<string name="ext_media_status_missing" msgid="6520746443048867314">"सम्मिलित छैन"</string>
<string name="activity_list_empty" msgid="4219430010716034252">"कुनै मिल्ने गतिविधि पाइएन।"</string>
<string name="permlab_route_media_output" msgid="8048124531439513118">"मिडिया निकास दिशानिर्देश गराउनुहोस्"</string>
@@ -1460,9 +1460,9 @@
<string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोध गरिएको"</string>
<string name="gpsVerifYes" msgid="3719843080744112940">"हो"</string>
<string name="gpsVerifNo" msgid="1671201856091564741">"होइन"</string>
- <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"आपत्कालीन सेवा उपलब्ध गराउन स्थान प्रयोग गरेको थियो"</string>
- <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"तपाईंको यन्त्रका उत्पादकले हालसालै तपाईंलाई आपत्कालीन सेवा उपलब्ध गराउने प्रयोजनका लागि तपाईंको स्थान प्रयोग गरेको थियो"</string>
- <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"तपाईंको टेलिफोन कम्पनीले हालसालै तपाईंलाई आपत्कालीन सेवा उपलब्ध गराउने प्रयोजनका लागि तपाईंको स्थान प्रयोग गरेको थियो"</string>
+ <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"आपत्‌कालीन सेवा उपलब्ध गराउन स्थान प्रयोग गरेको थियो"</string>
+ <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"तपाईंको यन्त्रका उत्पादकले हालसालै तपाईंलाई आपत्‌कालीन सेवा उपलब्ध गराउने प्रयोजनका लागि तपाईंको स्थान प्रयोग गरेको थियो"</string>
+ <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"तपाईंको टेलिफोन कम्पनीले हालसालै तपाईंलाई आपत्‌कालीन सेवा उपलब्ध गराउने प्रयोजनका लागि तपाईंको स्थान प्रयोग गरेको थियो"</string>
<string name="sync_too_many_deletes" msgid="6999440774578705300">"सीमा नाघेकाहरू मेट्नुहोस्"</string>
<string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"त्यहाँ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> मेटाइएका आइटमहरू छन् <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>को लागि, खाता <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>। तपाईं के गर्न चाहनु हुन्छ?"</string>
<string name="sync_really_delete" msgid="5657871730315579051">"वस्तुहरू मेट्नुहोस्"</string>
@@ -1473,7 +1473,7 @@
<string name="add_account_button_label" msgid="322390749416414097">"खाता थप्नुहोस्"</string>
<string name="number_picker_increment_button" msgid="7621013714795186298">"बढाउनुहोस्"</string>
<string name="number_picker_decrement_button" msgid="5116948444762708204">"घटाउनुहोस्"</string>
- <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> छोइराख्नुहोस्।"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> टच एण्ड होल्ड गर्नुहोस्।"</string>
<string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"बढाउन माथि र घटाउन तल सार्नुहोस्।"</string>
<string name="time_picker_increment_minute_button" msgid="7195870222945784300">"मिनेट बढाउनुहोस्"</string>
<string name="time_picker_decrement_minute_button" msgid="230925389943411490">"मिनेट घटाउनुहोस्"</string>
@@ -1633,7 +1633,7 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"निष्क्रिय"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको यन्त्र पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string>
<string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"तपाईंले <xliff:g id="SERVICE">%1$s</xliff:g> सक्रिय गर्नुभयो भने तपाईंको यन्त्रले डेटा इन्क्रिप्ट गर्ने सुविधाको स्तरोन्नति गर्न तपाईंको स्क्रिन लक सुविधाको प्रयोग गर्ने छैन।"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"तपाईंलाई पहुँच राख्न आवश्यक पर्ने कुरामा सहयोग गर्ने अनुप्रयोगहरूमाथि पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश अनुप्रयोगहरूका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"तपाईंलाई पहुँच राख्न आवश्यक पर्ने कुरामा सहयोग गर्ने एपमाथि पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश अनुप्रयोगहरूका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"कारबाहीहरू हेर्नुहोस् र तिनमा कार्य गर्नुहोस्"</string>
@@ -1656,9 +1656,9 @@
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले पहुँचको बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँच बटन छोइराख्नुहोस्।"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एउटा सुविधाबाट अर्को सुविधामा जान दुईवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा छोइराख्नुहोस्।"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एउटा सुविधाबाट अर्को सुविधामा जान तीनवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा छोइराख्नुहोस्।"</string>
+ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँच बटन टच एण्ड होल्ड गर्नुहोस्।"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एउटा सुविधाबाट अर्को सुविधामा जान दुईवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एउटा सुविधाबाट अर्को सुविधामा जान तीनवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
<string name="user_switched" msgid="7249833311585228097">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गर्दै..."</string>
@@ -1872,7 +1872,7 @@
<string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण नगरिएको"</string>
<string name="importance_from_user" msgid="2782756722448800447">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
- <string name="notification_history_title_placeholder" msgid="7748630986182249599">"अनुप्रयोगसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
+ <string name="notification_history_title_placeholder" msgid="7748630986182249599">"एपसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (यस खाताको प्रयोगकर्ता पहिले नै अवस्थित छ) मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="ACCOUNT">%2$s</xliff:g> मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
<string name="language_selection_title" msgid="52674936078683285">"भाषा थप्नुहोस्"</string>
@@ -1904,7 +1904,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> लाई पिन गर्नुहोस्"</string>
<string name="unpin_target" msgid="3963318576590204447">"अनपिन गर्नुहोस्"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> लाई अनपिन गर्नुहोस्"</string>
- <string name="app_info" msgid="6113278084877079851">"अनुप्रयोगका बारे जानकारी"</string>
+ <string name="app_info" msgid="6113278084877079851">"एपका बारे जानकारी"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो सुरु गर्दै…"</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"यन्त्रलाई रिसेट गर्दै…"</string>
@@ -1914,7 +1914,7 @@
<string name="app_category_game" msgid="4534216074910244790">"खेलहरू"</string>
<string name="app_category_audio" msgid="8296029904794676222">"सङ्गीत तथा अडियो"</string>
<string name="app_category_video" msgid="2590183854839565814">"चलचित्र तथा भिडियो"</string>
- <string name="app_category_image" msgid="7307840291864213007">"तस्बिर तथा छविहरू"</string>
+ <string name="app_category_image" msgid="7307840291864213007">"फोटो तथा छविहरू"</string>
<string name="app_category_social" msgid="2278269325488344054">"सामाजिक तथा सञ्चार"</string>
<string name="app_category_news" msgid="1172762719574964544">"समाचार तथा पत्रिकाहरू"</string>
<string name="app_category_maps" msgid="6395725487922533156">"नक्सा तथा नेभिगेसन"</string>
@@ -1961,7 +1961,7 @@
<string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
<string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"तटीय क्षेत्र र नदीछेउका ठाउँहरू छाडी उच्च सतहमा अवस्थित कुनै अझ सुरक्षित ठाउँमा जानुहोस्।"</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="4888224011071875068">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
- <string name="etws_primary_default_message_test" msgid="4583367373909549421">"आपतकालीन सन्देशहरूको परीक्षण"</string>
+ <string name="etws_primary_default_message_test" msgid="4583367373909549421">"आपत्‌कालीन सन्देशहरूको परीक्षण"</string>
<string name="notification_reply_button_accessibility" msgid="5235776156579456126">"जवाफ दिनु…"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
<string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM मार्फत भ्वाइस कल गर्न मिल्दैन"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c2c0e1f4c00e..e6b00396af22 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -711,7 +711,7 @@
<item msgid="6216981255272016212">"Aangepast"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="7786349763648997741">"Thuis"</item>
+ <item msgid="7786349763648997741">"Privé"</item>
<item msgid="435564470865989199">"Werk"</item>
<item msgid="4199433197875490373">"Overig"</item>
<item msgid="3233938986670468328">"Aangepast"</item>
@@ -769,7 +769,7 @@
<string name="eventTypeAnniversary" msgid="4684702412407916888">"Jubileum"</string>
<string name="eventTypeOther" msgid="530671238533887997">"Overig"</string>
<string name="emailTypeCustom" msgid="1809435350482181786">"Aangepast"</string>
- <string name="emailTypeHome" msgid="1597116303154775999">"Thuis"</string>
+ <string name="emailTypeHome" msgid="1597116303154775999">"Privé"</string>
<string name="emailTypeWork" msgid="2020095414401882111">"Werk"</string>
<string name="emailTypeOther" msgid="5131130857030897465">"Overig"</string>
<string name="emailTypeMobile" msgid="787155077375364230">"Mobiel"</string>
@@ -931,9 +931,9 @@
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nWeet u zeker dat u deze pagina wilt verlaten?"</string>
<string name="save_password_label" msgid="9161712335355510035">"Bevestigen"</string>
<string name="double_tap_toast" msgid="7065519579174882778">"Tip: dubbeltik om in en uit te zoomen."</string>
- <string name="autofill_this_form" msgid="3187132440451621492">"Autom. aanvullen"</string>
- <string name="setup_autofill" msgid="5431369130866618567">"Autom. aanvullen instellen"</string>
- <string name="autofill_window_title" msgid="4379134104008111961">"Automatisch aanvullen met <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
+ <string name="autofill_this_form" msgid="3187132440451621492">"Autom. invullen"</string>
+ <string name="setup_autofill" msgid="5431369130866618567">"Autom. invullen instellen"</string>
+ <string name="autofill_window_title" msgid="4379134104008111961">"Automatisch invullen met <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
<string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="760522655085707045">", "</string>
@@ -1101,7 +1101,7 @@
<string name="selectTextMode" msgid="3225108910999318778">"Tekst selecteren"</string>
<string name="undo" msgid="3175318090002654673">"Ongedaan maken"</string>
<string name="redo" msgid="7231448494008532233">"Opnieuw"</string>
- <string name="autofill" msgid="511224882647795296">"Automatisch aanvullen"</string>
+ <string name="autofill" msgid="511224882647795296">"Automatisch invullen"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"Tekstselectie"</string>
<string name="addToDictionary" msgid="8041821113480950096">"Toevoegen aan woordenboek"</string>
<string name="deleteText" msgid="4200807474529938112">"Verwijderen"</string>
@@ -1276,7 +1276,7 @@
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Nooit toestaan"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"Simkaart verwijderd"</string>
<string name="sim_removed_message" msgid="9051174064474904617">"Het mobiele netwerk is niet beschikbaar totdat u het apparaat opnieuw start met een geldige simkaart."</string>
- <string name="sim_done_button" msgid="6464250841528410598">"Gereed"</string>
+ <string name="sim_done_button" msgid="6464250841528410598">"Klaar"</string>
<string name="sim_added_title" msgid="7930779986759414595">"Simkaart aangesloten"</string>
<string name="sim_added_message" msgid="6602906609509958680">"Start je apparaat opnieuw voor toegang tot het mobiele netwerk."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"Opnieuw starten"</string>
@@ -1289,7 +1289,7 @@
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Tijd instellen"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Datum instellen"</string>
<string name="date_time_set" msgid="4603445265164486816">"Instellen"</string>
- <string name="date_time_done" msgid="8363155889402873463">"Gereed"</string>
+ <string name="date_time_done" msgid="8363155889402873463">"Klaar"</string>
<string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"NIEUW: "</font></string>
<string name="perms_description_app" msgid="2747752389870161996">"Geleverd door <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="5729199278862516390">"Geen rechten nodig"</string>
@@ -1376,7 +1376,7 @@
<string name="ext_media_status_removed" msgid="241223931135751691">"Verwijderd"</string>
<string name="ext_media_status_unmounted" msgid="8145812017295835941">"Uitgeworpen"</string>
<string name="ext_media_status_checking" msgid="159013362442090347">"Controleren…"</string>
- <string name="ext_media_status_mounted" msgid="3459448555811203459">"Gereed"</string>
+ <string name="ext_media_status_mounted" msgid="3459448555811203459">"Klaar"</string>
<string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Alleen lezen"</string>
<string name="ext_media_status_bad_removal" msgid="508448566481406245">"Onveilig verwijderd"</string>
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"Beschadigd"</string>
@@ -1401,7 +1401,7 @@
<string name="ime_action_search" msgid="4501435960587287668">"Zoeken"</string>
<string name="ime_action_send" msgid="8456843745664334138">"Verzenden"</string>
<string name="ime_action_next" msgid="4169702997635728543">"Volgende"</string>
- <string name="ime_action_done" msgid="6299921014822891569">"Gereed"</string>
+ <string name="ime_action_done" msgid="6299921014822891569">"Klaar"</string>
<string name="ime_action_previous" msgid="6548799326860401611">"Vorige"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Uitvoeren"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
@@ -1448,7 +1448,7 @@
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> van <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="one">1 overeenkomst</item>
</plurals>
- <string name="action_mode_done" msgid="2536182504764803222">"Gereed"</string>
+ <string name="action_mode_done" msgid="2536182504764803222">"Klaar"</string>
<string name="progress_erasing" msgid="6891435992721028004">"Gedeelde opslag wissen…"</string>
<string name="share" msgid="4157615043345227321">"Delen"</string>
<string name="find" msgid="5015737188624767706">"Vinden"</string>
@@ -1492,7 +1492,7 @@
<string name="keyboardview_keycode_alt" msgid="8997420058584292385">"Alt"</string>
<string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Annuleren"</string>
<string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Delete"</string>
- <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Gereed"</string>
+ <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Klaar"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Modus wijzigen"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
@@ -1645,7 +1645,7 @@
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Functies kiezen voor gebruik met de sneltoets via de volumeknop"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> is uitgeschakeld"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Snelkoppelingen bewerken"</string>
- <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gereed"</string>
+ <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Klaar"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Sneltoets uitschakelen"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
@@ -1774,7 +1774,7 @@
<string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt weergegeven"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ik snap het"</string>
- <string name="done_label" msgid="7283767013231718521">"Gereed"</string>
+ <string name="done_label" msgid="7283767013231718521">"Klaar"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Ronde schuifregelaar voor uren"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Ronde schuifregelaar voor minuten"</string>
<string name="select_hours" msgid="5982889657313147347">"Uren selecteren"</string>
@@ -1928,13 +1928,13 @@
<string name="time_picker_prompt_label" msgid="303588544656363889">"Typ een tijd"</string>
<string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Schakel naar de tekstinvoermodus om de tijd in te voeren."</string>
<string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Schakel naar de klokmodus om de tijd in te voeren."</string>
- <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opties voor automatisch aanvullen"</string>
- <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Opslaan voor Automatisch aanvullen"</string>
+ <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opties voor automatisch invullen"</string>
+ <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Opslaan voor Automatisch invullen"</string>
<string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Content kan niet automatisch worden aangevuld"</string>
- <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Geen suggesties van Automatisch aanvullen"</string>
+ <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Geen suggesties van Automatisch invullen"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
- <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggesties van Automatisch aanvullen</item>
- <item quantity="one">Eén suggestie van Automatisch aanvullen</item>
+ <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggesties van Automatisch invullen</item>
+ <item quantity="one">Eén suggestie van Automatisch invullen</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Opslaan in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_type" msgid="3002460014579799605">"<xliff:g id="TYPE">%1$s</xliff:g> opslaan in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 873cdbb89c00..d34f18bca576 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"ସ୍ପେସ୍‍"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"ଏଣ୍ଟର୍"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ୍‍"</string>
- <string name="search_go" msgid="2141477624421347086">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="search_go" msgid="2141477624421347086">"Search"</string>
<string name="search_hint" msgid="455364685740251925">"ସର୍ଚ୍ଚ…"</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"Search"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"କ୍ୱେରୀ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"କ୍ୱେରୀ ଖାଲି କରନ୍ତୁ"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"କ୍ୱେରୀ ଦାଖଲ କରନ୍ତୁ"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍‌ କରନ୍ତୁ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ୱିଜେଟ୍‍ ଯୋଡ଼ିପାରିବ ନାହିଁ।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ଯାଆନ୍ତୁ"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"Search"</string>
<string name="ime_action_send" msgid="8456843745664334138">"ପଠାନ୍ତୁ"</string>
<string name="ime_action_next" msgid="4169702997635728543">"ପରବର୍ତ୍ତୀ"</string>
<string name="ime_action_done" msgid="6299921014822891569">"ହୋଇଗଲା"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"ପ୍ରସ୍ତାବିତ"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"ସମସ୍ତ ଭାଷା"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"ସମସ୍ତ ଅଞ୍ଚଳ"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"Search"</string>
<string name="app_suspended_title" msgid="888873445010322650">"ଆପ୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"ବର୍ତ୍ତମାନ <xliff:g id="APP_NAME_0">%1$s</xliff:g> ଉପଲବ୍ଧ ନାହିଁ। ଏହା <xliff:g id="APP_NAME_1">%2$s</xliff:g> ଦ୍ଵାରା ପରିଚାଳିତ ହେଉଛି।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 9faa33785f1f..0565f2c3d43d 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -896,7 +896,7 @@
<string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"ਅਣਲਾਕ ਖੇਤਰ ਨਸ਼ਟ ਕੀਤਾ।"</string>
<string name="keyguard_accessibility_widget" msgid="6776892679715699875">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ਵਿਜੇਟ।"</string>
<string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"ਉਪਭੋਗਤਾ ਚੋਣਕਾਰ"</string>
- <string name="keyguard_accessibility_status" msgid="6792745049712397237">"ਅਵਸਥਾ"</string>
+ <string name="keyguard_accessibility_status" msgid="6792745049712397237">"ਸਥਿਤੀ"</string>
<string name="keyguard_accessibility_camera" msgid="7862557559464986528">"ਕੈਮਰਾ"</string>
<string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"ਮੀਡੀਆ ਨਿਯੰਤਰਣ"</string>
<string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"ਵਿਜੇਟ ਨੂੰ ਪੁਨਰ ਤਰਤੀਬ ਦੇਣਾ ਸ਼ੁਰੂ ਹੋਇਆ।"</string>
@@ -1216,18 +1216,18 @@
<string name="dump_heap_ready_text" msgid="5849618132123045516">"ਸਾਂਝਾ ਕਰਨ ਲਈ <xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਪ੍ਰਕਿਰਿਆ ਦਾ ਹੀਪ ਡੰਪ ਤੁਹਾਡੇ ਲਈ ਉਪਲਬਧ ਹੈ। ਸਾਵਧਾਨ ਰਹੋ: ਸ਼ਾਇਦ ਇਸ ਹੀਪ ਡੰਪ ਵਿੱਚ ਕੋਈ ਵੀ ਸੰਵੇਦਨਸ਼ੀਲ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋਵੇ, ਜਿਸ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਦੀ ਪਹੁੰਚ ਹੈ, ਜਿਸ ਵਿੱਚ ਸ਼ਾਇਦ ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੀਆਂ ਚੀਜ਼ਾਂ ਸ਼ਾਮਲ ਹੋਣ।"</string>
<string name="sendText" msgid="493003724401350724">"ਲਿਖਤ ਲਈ ਕੋਈ ਕਾਰਵਾਈ ਚੁਣੋ"</string>
<string name="volume_ringtone" msgid="134784084629229029">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string>
- <string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
+ <string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth ਰਾਹੀਂ ਪਲੇ ਕਰ ਰਿਹਾ ਹੈ"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਖਾਮੋਸ਼ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string>
<string name="volume_call" msgid="7625321655265747433">"ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"ਬਲੂਟੁੱਥ ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਵੌਲਿਊਮ"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_notification" msgid="6864412249031660057">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string>
<string name="volume_unknown" msgid="4041914008166576293">"ਵੌਲਿਊਮ"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetooth ਵੌਲਿਊਮ"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"ਰਿੰਗਟੋਨ ਵੌਲਿਊਮ"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"ਕਾਲ ਅਵਾਜ਼"</string>
- <string name="volume_icon_description_media" msgid="4997633254078171233">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
+ <string name="volume_icon_description_media" msgid="4997633254078171233">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string>
<string name="ringtone_default" msgid="9118299121288174597">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"ਪੂਰਵ-ਨਿਰਧਾਰਤ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 254f1d04be87..4374e7fd7830 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -186,10 +186,10 @@
<item quantity="one">Urząd certyfikacji został zainstalowany</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Przez nieznany podmiot zewnętrzny"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Przez administratora Twojego profilu do pracy"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Przez administratora Twojego profilu służbowego"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Przez <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5891181538182009328">"Usunięto profil służbowy"</string>
- <string name="work_profile_deleted_details" msgid="3773706828364418016">"Brakuje aplikacji administratora profilu do pracy lub jest ona uszkodzona. Dlatego Twój profil służbowy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string>
+ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Brakuje aplikacji administratora profilu służbowego lub jest ona uszkodzona. Dlatego Twój profil służbowy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Twój profil służbowy nie jest już dostępny na tym urządzeniu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zbyt wiele prób podania hasła"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator odstąpił urządzenie do użytku osobistego"</string>
@@ -204,8 +204,8 @@
<string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string>
<string name="factory_reset_message" msgid="2657049595153992213">"Nie można użyć aplikacji administratora. Dane z urządzenia zostaną wykasowane.\n\nJeśli masz pytania, skontaktuj się z administratorem organizacji."</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"Drukowanie wyłączone przez: <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
- <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Włącz profil do pracy"</string>
- <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Zablokowano aplikacje osobiste do czasu włączenia profilu do pracy"</string>
+ <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Włącz profil służbowy"</string>
+ <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Zablokowano aplikacje osobiste do czasu włączenia profilu służbowego"</string>
<string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Aplikacje osobiste zostaną zablokowane <xliff:g id="DATE">%1$s</xliff:g> o <xliff:g id="TIME">%2$s</xliff:g>. Administrator IT nie pozwala na wyłączenie profilu służbowego na dłużej niż <xliff:g id="NUMBER">%3$d</xliff:g> dni."</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Włącz"</string>
<string name="me" msgid="6207584824693813140">"Ja"</string>
@@ -709,7 +709,7 @@
<string-array name="phoneTypes">
<item msgid="8996339953292723951">"Dom"</item>
<item msgid="7740243458912727194">"Komórka"</item>
- <item msgid="8526146065496663766">"Praca"</item>
+ <item msgid="8526146065496663766">"Służbowy"</item>
<item msgid="8150904584178569699">"Faks w pracy"</item>
<item msgid="4537253139152229577">"Faks domowy"</item>
<item msgid="6751245029698664340">"Pager"</item>
@@ -718,24 +718,24 @@
</string-array>
<string-array name="emailAddressTypes">
<item msgid="7786349763648997741">"Dom"</item>
- <item msgid="435564470865989199">"Praca"</item>
+ <item msgid="435564470865989199">"Służbowy"</item>
<item msgid="4199433197875490373">"Inne"</item>
<item msgid="3233938986670468328">"Niestandardowy"</item>
</string-array>
<string-array name="postalAddressTypes">
<item msgid="3861463339764243038">"Dom"</item>
- <item msgid="5472578890164979109">"Praca"</item>
+ <item msgid="5472578890164979109">"Służbowy"</item>
<item msgid="5718921296646594739">"Inny"</item>
<item msgid="5523122236731783179">"Niestandardowy"</item>
</string-array>
<string-array name="imAddressTypes">
<item msgid="588088543406993772">"Dom"</item>
- <item msgid="5503060422020476757">"Praca"</item>
+ <item msgid="5503060422020476757">"Służbowy"</item>
<item msgid="2530391194653760297">"Inne"</item>
<item msgid="7640927178025203330">"Niestandardowy"</item>
</string-array>
<string-array name="organizationTypes">
- <item msgid="6144047813304847762">"Praca"</item>
+ <item msgid="6144047813304847762">"Służbowy"</item>
<item msgid="7402720230065674193">"Inne"</item>
<item msgid="808230403067569648">"Niestandardowy"</item>
</string-array>
@@ -1453,8 +1453,8 @@
<string name="deny" msgid="6632259981847676572">"Odmów"</string>
<string name="permission_request_notification_title" msgid="1810025922441048273">"Prośba o pozwolenie"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Prośba o pozwolenie\ndotyczące konta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"Używasz tej aplikacji poza profilem do pracy"</string>
- <string name="forward_intent_to_work" msgid="3620262405636021151">"Używasz tej aplikacji w swoim profilu do pracy"</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"Używasz tej aplikacji poza profilem służbowym"</string>
+ <string name="forward_intent_to_work" msgid="3620262405636021151">"Używasz tej aplikacji w swoim profilu służbowym"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"Sposób wprowadzania tekstu"</string>
<string name="sync_binding_label" msgid="469249309424662147">"Synchronizacja"</string>
<string name="accessibility_binding_label" msgid="1974602776545801715">"Ułatwienia dostępu"</string>
@@ -1591,7 +1591,7 @@
<string name="SetupCallDefault" msgid="5581740063237175247">"Odebrać połączenie?"</string>
<string name="activity_resolver_use_always" msgid="5575222334666843269">"Zawsze"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"Tylko raz"</string>
- <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s nie obsługuje profilu do pracy"</string>
+ <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s nie obsługuje profilu służbowego"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Tablet"</string>
<string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Telewizor"</string>
<string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
@@ -1828,7 +1828,7 @@
<string name="select_day" msgid="2060371240117403147">"Wybierz miesiąc i dzień"</string>
<string name="select_year" msgid="1868350712095595393">"Wybierz rok"</string>
<string name="deleted_key" msgid="9130083334943364001">"<xliff:g id="KEY">%1$s</xliff:g> usunięte"</string>
- <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (praca)"</string>
+ <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (służbowy)"</string>
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 2"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 3"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Podaj PIN, aby odpiąć"</string>
@@ -1950,8 +1950,8 @@
<string name="app_suspended_default_message" msgid="6451215678552004172">"Aplikacja <xliff:g id="APP_NAME_0">%1$s</xliff:g> nie jest teraz dostępna. Zarządza tym aplikacja <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"Więcej informacji"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Wznów działanie aplikacji"</string>
- <string name="work_mode_off_title" msgid="5503291976647976560">"Włączyć profil do pracy?"</string>
- <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacje do pracy, powiadomienia, dane i inne funkcje profilu do pracy zostaną włączone"</string>
+ <string name="work_mode_off_title" msgid="5503291976647976560">"Włączyć profil służbowy?"</string>
+ <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacje służbowe, powiadomienia, dane i inne funkcje profilu służbowego zostaną włączone"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Włącz"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c78bfb761bfe..9a63a1041643 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1128,7 +1128,7 @@
<string name="whichViewApplication" msgid="5733194231473132945">"Abrir com"</string>
<string name="whichViewApplicationNamed" msgid="415164730629690105">"Abrir com %1$s"</string>
<string name="whichViewApplicationLabel" msgid="7367556735684742409">"Abrir"</string>
- <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Abra os links de <xliff:g id="HOST">%1$s</xliff:g> com:"</string>
+ <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Abrir os links de <xliff:g id="HOST">%1$s</xliff:g> com:"</string>
<string name="whichOpenLinksWith" msgid="1120936181362907258">"Abrir os links com:"</string>
<string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Abra os links com a app <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
<string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Abra os links de <xliff:g id="HOST">%1$s</xliff:g> com a app <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 6d348d0eb7a1..3f2c6dff6d63 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -298,7 +298,7 @@
<string name="safeMode" msgid="8974401416068943888">"Безопасный режим"</string>
<string name="android_system_label" msgid="5974767339591067210">"Система Android"</string>
<string name="user_owner_label" msgid="8628726904184471211">"Переключиться на личный профиль"</string>
- <string name="managed_profile_label" msgid="7316778766973512382">"Переключиться на рабочий профиль"</string>
+ <string name="managed_profile_label" msgid="7316778766973512382">"Перейти в рабочий профиль"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"Контакты"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"доступ к контактам"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"Местоположение"</string>
@@ -1261,7 +1261,7 @@
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Выбран режим \"Без звука\""</string>
<string name="volume_call" msgid="7625321655265747433">"Громкость при разговоре"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Громкость при разговоре"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Громкость сигнала предупреждения"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Громкость будильника"</string>
<string name="volume_notification" msgid="6864412249031660057">"Громкость уведомления"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Громкость"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Громкость Bluetooth-устройства"</string>
@@ -1312,7 +1312,7 @@
<string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Отмена"</string>
<string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Запомнить выбор"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Это можно изменить позже в разделе настроек \"Приложения\"."</string>
- <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Всегда разрешать"</string>
+ <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Разрешать всегда"</string>
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Не разрешать"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"SIM-карта удалена"</string>
<string name="sim_removed_message" msgid="9051174064474904617">"Пока вы не вставите действующую SIM-карту, мобильная сеть будет недоступна."</string>
@@ -1688,7 +1688,7 @@
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Выберите функции, которые будут запускаться с помощью кнопки специальных возможностей"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Выберите функции, которые будут запускаться с помощью кнопки регулировки громкости"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Сервис \"<xliff:g id="SERVICE_NAME">%s</xliff:g>\" отключен."</string>
- <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Изменить быстрые клавиши"</string>
+ <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Изменить ярлыки"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Деактивировать быстрое включение"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Использовать быстрое включение"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e21cc58dfda5..dde651f9732d 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1162,7 +1162,7 @@
<string name="capital_off" msgid="7443704171014626777">"IZKLOPLJENO"</string>
<string name="checked" msgid="9179896827054513119">"potrjeno"</string>
<string name="not_checked" msgid="7972320087569023342">"ni potrjeno"</string>
- <string name="whichApplication" msgid="5432266899591255759">"Dokončanje dejanja z"</string>
+ <string name="whichApplication" msgid="5432266899591255759">"Dokončanje dejanja z aplikacijo"</string>
<string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončanje dejanja z aplikacijo %1$s"</string>
<string name="whichApplicationLabel" msgid="7852182961472531728">"Izvedba dejanja"</string>
<string name="whichViewApplication" msgid="5733194231473132945">"Odpiranje z aplikacijo"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1e5c42c77200..258940b6e5d2 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -751,7 +751,7 @@
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"Faks shtëpie"</string>
<string name="phoneTypePager" msgid="576402072263522767">"Biper"</string>
<string name="phoneTypeOther" msgid="6918196243648754715">"Tjetër"</string>
- <string name="phoneTypeCallback" msgid="3455781500844157767">"Ri-telefono"</string>
+ <string name="phoneTypeCallback" msgid="3455781500844157767">"Kthim telefonate"</string>
<string name="phoneTypeCar" msgid="4604775148963129195">"Numri i telefonit të makinës"</string>
<string name="phoneTypeCompanyMain" msgid="4482773154536455441">"Numri kryesor i telefonit të kompanisë"</string>
<string name="phoneTypeIsdn" msgid="2496238954533998512">"ISDN"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d0e5182a0463..105ee44d0114 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -94,7 +94,7 @@
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус мобилних података"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS-ови"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Поруке говорне поште"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Позивање преко Wi-Fi мреже"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Позивање преко WiFi мреже"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"Статус SIM-а"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Обавештења SIM картице са статусом „висок приоритет“"</string>
<string name="peerTtyModeFull" msgid="337553730440832160">"Корисник захтева ПОТПУН режим TTY"</string>
@@ -123,30 +123,30 @@
<string name="roamingText11" msgid="5245687407203281407">"Банер роминга је укључен"</string>
<string name="roamingText12" msgid="673537506362152640">"Банер роминга је искључен"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Претраживање услуге"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Подешавање позивања преко Wi-Fi-ја није успело"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Подешавање позивања преко WiFi-а није успело"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"Да бисте упућивали позиве и слали поруке преко WiFi-а, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко WiFi-а. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"Проблем у вези са регистровањем позивања преко Wi‑Fi-ја код мобилног оператера: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> позивање преко Wi-Fi-ја"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – позивање преко Wi-Fi-ја"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> позивање преко WiFi-а"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> – позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN позив"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
- <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Позивање преко Wi-Fi-ја | <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
+ <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Позивање преко WiFi-а | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Позивање преко Wi-Fi-ја"</string>
- <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко Wi-Fi-ја"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Позивање преко WiFi-а"</string>
+ <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Искључено"</string>
- <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко Wi-Fi-ја"</string>
+ <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко WiFi-а"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Позив преко мобилне мреже"</string>
- <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Само Wi-Fi"</string>
+ <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Само WiFi"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> након <xliff:g id="TIME_DELAY">{2}</xliff:g> секунде/и"</string>
@@ -241,7 +241,7 @@
<string name="global_action_power_off" msgid="4404936470711393203">"Искључи"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"Напајање"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Рестартуј"</string>
- <string name="global_action_emergency" msgid="1387617624177105088">"Хитни позив"</string>
+ <string name="global_action_emergency" msgid="1387617624177105088">"Хитан позив"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Извештај о грешци"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Заврши сесију"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Снимак екрана"</string>
@@ -495,14 +495,14 @@
<string name="permdesc_changeNetworkState" msgid="649341947816898736">"Дозвољава апликацији да мења статус повезивања са мрежом."</string>
<string name="permlab_changeTetherState" msgid="9079611809931863861">"промена повезивања привезивањем"</string>
<string name="permdesc_changeTetherState" msgid="3025129606422533085">"Дозвољава апликацији да мења статус везе са привезаном мрежом."</string>
- <string name="permlab_accessWifiState" msgid="5552488500317911052">"преглед Wi-Fi веза"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Дозвољава апликацији да прегледа информације о Wi-Fi умрежавању, као што су информације о томе да ли је Wi-Fi омогућен и називи повезаних Wi-Fi уређаја."</string>
- <string name="permlab_changeWifiState" msgid="7947824109713181554">"повезивање и прекид везе са Wi-Fi мрежом"</string>
- <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Дозвољава апликацији да се повезује са приступним тачкама за Wi-Fi и прекида везу са њима, као и да уноси промене у конфигурацију уређаја за Wi-Fi мреже."</string>
- <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"омогућавање пријема вишесмерног Wi-Fi саобраћаја"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на Wi-Fi мрежи помоћу вишесмерних адреса, а не само на таблет. Користи више напајања од режима једносмерног саобраћаја."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на Wi-Fi мрежи помоћу вишесмерних адреса, а не само на Android TV уређај. Користи више енергије од режима без вишесмерног слања."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на Wi-Fi мрежи помоћу вишесмерних адреса, а не само на телефон. Користи више напајања од режима једносмерног саобраћаја."</string>
+ <string name="permlab_accessWifiState" msgid="5552488500317911052">"преглед WiFi веза"</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Дозвољава апликацији да прегледа информације о WiFi умрежавању, као што су информације о томе да ли је WiFi омогућен и називи повезаних WiFi уређаја."</string>
+ <string name="permlab_changeWifiState" msgid="7947824109713181554">"повезивање и прекид везе са WiFi мрежом"</string>
+ <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Дозвољава апликацији да се повезује са приступним тачкама за WiFi и прекида везу са њима, као и да уноси промене у конфигурацију уређаја за WiFi мреже."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"омогућавање пријема вишесмерног WiFi саобраћаја"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на таблет. Користи више напајања од режима једносмерног саобраћаја."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на Android TV уређај. Користи више енергије од режима без вишесмерног слања."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Дозвољава апликацији да прима пакете који се шаљу на све уређаје на WiFi мрежи помоћу вишесмерних адреса, а не само на телефон. Користи више напајања од режима једносмерног саобраћаја."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"приступ Bluetooth подешавањима"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Дозвољава апликацији да конфигурише локални Bluetooth таблет, као и да открије даљинске уређаје и упари се са њима."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Дозвољава апликацији да конфигурише Bluetooth на Android TV уређају и да открије удаљене уређаје и упари се са њима."</string>
@@ -1256,7 +1256,7 @@
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Звуци аларма"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Звуци обавештења"</string>
<string name="ringtone_unknown" msgid="5059495249862816475">"Непознато"</string>
- <string name="wifi_available_sign_in" msgid="381054692557675237">"Пријављивање на Wi-Fi мрежу"</string>
+ <string name="wifi_available_sign_in" msgid="381054692557675237">"Пријављивање на WiFi мрежу"</string>
<string name="network_available_sign_in" msgid="1520342291829283114">"Пријавите се на мрежу"</string>
<!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
<skip />
@@ -1272,7 +1272,7 @@
<string name="network_switch_metered_toast" msgid="501662047275723743">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
<string-array name="network_switch_type_name">
<item msgid="2255670471736226365">"мобилни подаци"</item>
- <item msgid="5520925862115353992">"Wi-Fi"</item>
+ <item msgid="5520925862115353992">"WiFi"</item>
<item msgid="1055487873974272842">"Bluetooth"</item>
<item msgid="1616528372438698248">"Етернет"</item>
<item msgid="9177085807664964627">"VPN"</item>
@@ -1538,10 +1538,10 @@
<string name="data_usage_warning_title" msgid="9034893717078325845">"Упозорење на потрошњу података"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"Потрошили сте <xliff:g id="APP">%s</xliff:g> података"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Достигли сте ограничење података"</string>
- <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Нема више Wi-Fi података"</string>
+ <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Нема више WiFi података"</string>
<string name="data_usage_limit_body" msgid="3567699582000085710">"Подаци су паузирани током остатка циклуса"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Потрошили сте мобилне податке"</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Потрошили сте Wi-Fi податке"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Потрошили сте WiFi податке"</string>
<string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Прекорачили сте <xliff:g id="SIZE">%s</xliff:g> од подешеног ограничења"</string>
<string name="data_usage_restricted_title" msgid="126711424380051268">"Позадински подаци су ограничени"</string>
<string name="data_usage_restricted_body" msgid="5338694433686077733">"Додирните за уклањање ограничења."</string>
@@ -1815,7 +1815,7 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирао је администратор"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Да би се продужило трајање батерије, Уштеда батерије:\n\n•укључује тамну тему\n•искључује или ограничава активности у позадини, неке визуелне ефекте и друге функције, на пример, „Ок Google“\n\n"<annotation id="url">"Сазнајте више"</annotation></string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Да би се продужило трајање батерије, Уштеда батерије:\n\n•укључује тамну тему\n•искључује или ограничава активности у позадини, неке визуелне ефекте и друге функције, на пример „Ок Google“\n\n"<annotation id="url">"Сазнајте више"</annotation></string>
<string name="battery_saver_description" msgid="8587408568232177204">"Да би се продужило трајање батерије, Уштеда батерије:\n\n•укључује тамну тему\n•искључује или ограничава активности у позадини, неке визуелне ефекте и друге функције, на пример, „Ок Google“"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Да би се смањила потрошња података, Уштеда података спречава неке апликације да шаљу или примају податке у позадини. Апликација коју тренутно користите може да приступа подацима, али ће то чинити ређе. На пример, слике се неће приказивати док их не додирнете."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Желите да укључите Уштеду података?"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3c5a1e92db7b..206ea8d300d1 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1829,7 +1829,7 @@
<item quantity="other">I %d tim</item>
<item quantity="one">I en 1 tim</item>
</plurals>
- <string name="zen_mode_until" msgid="2250286190237669079">"Till kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_until" msgid="2250286190237669079">"Till <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"Till <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nästa alarm)"</string>
<string name="zen_mode_forever" msgid="740585666364912448">"Tills du stänger av"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Tills du inaktiverar Stör ej"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 7a5cdcffbefa..45a0354311f6 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -303,9 +303,9 @@
<string name="permgroupdesc_sms" msgid="5726462398070064542">"itume na iangalie SMS"</string>
<string name="permgrouplab_storage" msgid="1938416135375282333">"Faili na maudhui"</string>
<string name="permgroupdesc_storage" msgid="6351503740613026600">"ifikie picha, maudhui na faili kwenye kifaa chako"</string>
- <string name="permgrouplab_microphone" msgid="2480597427667420076">"Kipokea sauti"</string>
+ <string name="permgrouplab_microphone" msgid="2480597427667420076">"Maikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"irekodi sauti"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Shughuli za kimwili"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Mazoezi ya mwili"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ifikie shughuli zako za kimwili"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ipige picha na kurekodi video"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 32ea9795ed9d..9b0d9a26f1e8 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1307,7 +1307,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"அனலாக் ஆடியோ துணைக்கருவி கண்டறியப்பட்டது"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"இணைத்துள்ள சாதனமானது இந்த மொபைலுடன் இணங்கவில்லை. மேலும் அறிய, தட்டவும்."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB பிழைதிருத்தத்தை ஆஃப் செய்ய தட்டவும்"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"USB பிழைதிருத்தத்தை ஆஃப் செய்யத் தட்டவும்"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB பிழைதிருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"வைஃபை பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"வைஃபை பிழைதிருத்தத்தை ஆஃப் செய்ய தட்டவும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 2d3c68507e7a..b97c6c785735 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -822,12 +822,12 @@
<string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"అన్‌లాక్ చేయడానికి పాస్‌వర్డ్‌ను టైప్ చేయండి"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"అన్‌లాక్ చేయడానికి పిన్‌ను టైప్ చేయండి"</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"చెల్లని పిన్‌ కోడ్."</string>
- <string name="keyguard_label_text" msgid="3841953694564168384">"అన్‌లాక్ చేయడానికి, మెను ఆపై 0ని నొక్కండి."</string>
+ <string name="keyguard_label_text" msgid="3841953694564168384">"అన్‌లాక్ చేయడానికి, మెనూ ఆపై 0ని నొక్కండి."</string>
<string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"అత్యవసర నంబర్"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"సేవ లేదు"</string>
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"స్క్రీన్ లాక్ చేయబడింది."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్‌లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెను నొక్కండి."</string>
- <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్‌లాక్ చేయడానికి మెను నొక్కండి."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్‌లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెనూ నొక్కండి."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్‌లాక్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"అన్‌లాక్ చేయడానికి నమూనాను గీయండి"</string>
<string name="lockscreen_emergency_call" msgid="7500692654885445299">"అత్యవసరం"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"కాల్‌కు తిరిగి వెళ్లు"</string>
@@ -970,7 +970,7 @@
<string name="text_copied" msgid="2531420577879738860">"వచనం క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
<string name="copied" msgid="4675902854553014676">"కాపీ చేయబడింది"</string>
<string name="more_item_label" msgid="7419249600215749115">"ఎక్కువ"</string>
- <string name="prepend_shortcut_label" msgid="1743716737502867951">"మెను+"</string>
+ <string name="prepend_shortcut_label" msgid="1743716737502867951">"మెనూ+"</string>
<string name="menu_meta_shortcut_label" msgid="1623390163674762478">"Meta+"</string>
<string name="menu_ctrl_shortcut_label" msgid="131911133027196485">"Ctrl+"</string>
<string name="menu_alt_shortcut_label" msgid="343761069945250991">"Alt+"</string>
@@ -980,9 +980,9 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"space"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"delete"</string>
- <string name="search_go" msgid="2141477624421347086">"వెతుకు"</string>
+ <string name="search_go" msgid="2141477624421347086">"సెర్చ్"</string>
<string name="search_hint" msgid="455364685740251925">"వెతుకు..."</string>
- <string name="searchview_description_search" msgid="1045552007537359343">"శోధించండి"</string>
+ <string name="searchview_description_search" msgid="1045552007537359343">"సెర్చ్"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"ప్రశ్నను శోధించండి"</string>
<string name="searchview_description_clear" msgid="1989371719192982900">"ప్రశ్నను క్లియర్ చేయి"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"ప్రశ్నని సమర్పించండి"</string>
@@ -1398,7 +1398,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"విడ్జెట్‌ను జోడించడం సాధ్యపడలేదు."</string>
<string name="ime_action_go" msgid="5536744546326495436">"వెళ్లు"</string>
- <string name="ime_action_search" msgid="4501435960587287668">"వెతుకు"</string>
+ <string name="ime_action_search" msgid="4501435960587287668">"సెర్చ్"</string>
<string name="ime_action_send" msgid="8456843745664334138">"పంపు"</string>
<string name="ime_action_next" msgid="4169702997635728543">"తర్వాత"</string>
<string name="ime_action_done" msgid="6299921014822891569">"పూర్తయింది"</string>
@@ -1881,7 +1881,7 @@
<string name="language_picker_section_suggested" msgid="6556199184638990447">"సూచించినవి"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"అన్ని భాషలు"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"అన్ని ప్రాంతాలు"</string>
- <string name="locale_search_menu" msgid="6258090710176422934">"వెతుకు"</string>
+ <string name="locale_search_menu" msgid="6258090710176422934">"సెర్చ్"</string>
<string name="app_suspended_title" msgid="888873445010322650">"యాప్ అందుబాటులో లేదు"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ప్రస్తుతం అందుబాటులో లేదు. ఇది <xliff:g id="APP_NAME_1">%2$s</xliff:g> ద్వారా నిర్వహించబడుతుంది."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"మరింత తెలుసుకోండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 000ad10827a4..d4e0672fa4d2 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -2029,7 +2029,7 @@
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> และอีก <xliff:g id="COUNT_3">%d</xliff:g> ไฟล์</item>
<item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> และอีก <xliff:g id="COUNT_1">%d</xliff:g> ไฟล์</item>
</plurals>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ไม่มีบุคคลที่แนะนำให้แชร์ด้วย"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ไม่พบใครที่แนะนำให้แชร์ด้วย"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"รายชื่อแอป"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"แอปนี้ไม่ได้รับอนุญาตให้บันทึกเสียงแต่จะบันทึกเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"หน้าแรก"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4cea142cbe60..03c65688a56a 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Na-update ng iyong admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Na-delete ng iyong admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Para patagalin ang baterya, ginagawa ng Pangtipid sa Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”\n\n"<annotation id="url">"Matuto pa"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"Para patagalin ang baterya, ginagawa ng Pangtipid sa Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Para patagalin ang baterya, ginagawa ng Pantipid ng Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”\n\n"<annotation id="url">"Matuto pa"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"Para patagalin ang baterya, ginagawa ng Pantipid ng Baterya na:\n\n•I-on ang Madilim na tema\n•I-off o paghigpitan ang aktibidad sa background, ilang visual effect, at iba pang feature gaya ng “Hey Google”"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Upang makatulong na mabawasan ang paggamit ng data, pinipigilan ng Data Saver ang ilang app na magpadala o makatanggap ng data sa background. Maaaring mag-access ng data ang isang app na ginagamit mo sa kasalukuyan, ngunit mas bihira na nito magagawa iyon. Halimbawa, maaaring hindi lumabas ang mga larawan hangga\'t hindi mo nata-tap ang mga ito."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"I-on ang Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"I-on"</string>
@@ -1999,9 +1999,9 @@
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"ipinapakita sa ibabaw ng ibang app sa iyong screen"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification ng impormasyon ng Routine Mode"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Maaaring maubos ang baterya bago ang karaniwang pag-charge"</string>
- <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pangtipid sa Baterya para patagalin ang buhay ng baterya"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pangtipid sa Baterya"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Na-off ang Pangtipid sa Baterya"</string>
+ <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pantipid ng Baterya para patagalin ang buhay ng baterya"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pantipid ng Baterya"</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Na-off ang Pantipid ng Baterya"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"May sapat na charge ang telepono. Hindi na pinaghihigpitan ang mga feature."</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"May sapat na charge ang tablet. Hindi na pinaghihigpitan ang mga feature."</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"May sapat na charge ang device. Hindi na pinaghihigpitan ang mga feature."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 2ac900bc3e9c..1f00a5dc8137 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1130,7 +1130,7 @@
<string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="1532369154488982046">"Вибрати все"</string>
- <string name="cut" msgid="2561199725874745819">"Виріз."</string>
+ <string name="cut" msgid="2561199725874745819">"Вирізати"</string>
<string name="copy" msgid="5472512047143665218">"Копіювати"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Не вдалося скопіювати в буфер обміну"</string>
<string name="paste" msgid="461843306215520225">"Вставити"</string>
@@ -1259,9 +1259,9 @@
<string name="volume_music" msgid="7727274216734955095">"Гучність медіа"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Відтвор. через Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Установлено сигнал дзвінка без звуку"</string>
- <string name="volume_call" msgid="7625321655265747433">"Обсяг вхідних"</string>
- <string name="volume_bluetooth_call" msgid="2930204618610115061">"Обсяг вхідних Bluetooth"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Гучн. сповіщ."</string>
+ <string name="volume_call" msgid="7625321655265747433">"Гучність під час розмови"</string>
+ <string name="volume_bluetooth_call" msgid="2930204618610115061">"Гучність у викликах Bluetooth"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Гучність будильника"</string>
<string name="volume_notification" msgid="6864412249031660057">"Гучність сповіщень"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Гучність"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Гучність Bluetooth"</string>
@@ -1856,7 +1856,7 @@
<item quantity="other">Протягом %1$d хв (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
- <item quantity="one">%1$d годину (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">%1$d година (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d години (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">%1$d годин (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d години (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 4666b418ee77..52218f9b5022 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -272,8 +272,8 @@
<string name="notification_channel_security" msgid="8516754650348238057">"سیکیورٹی"</string>
<string name="notification_channel_car_mode" msgid="2123919247040988436">"کار وضع"</string>
<string name="notification_channel_account" msgid="6436294521740148173">"اکاؤنٹ اسٹیٹس"</string>
- <string name="notification_channel_developer" msgid="1691059964407549150">"ڈیولپر کے پیغامات"</string>
- <string name="notification_channel_developer_important" msgid="7197281908918789589">"اہم ڈیولپر پیغامات"</string>
+ <string name="notification_channel_developer" msgid="1691059964407549150">"ڈویلپر کے پیغامات"</string>
+ <string name="notification_channel_developer_important" msgid="7197281908918789589">"اہم ڈویلپر پیغامات"</string>
<string name="notification_channel_updates" msgid="7907863984825495278">"اپ ڈیٹس"</string>
<string name="notification_channel_network_status" msgid="2127687368725272809">"نیٹ ورک اسٹیٹس"</string>
<string name="notification_channel_network_alerts" msgid="6312366315654526528">"نیٹ ورک الرٹس"</string>
@@ -1211,7 +1211,7 @@
<string name="dump_heap_ready_notification" msgid="2302452262927390268">"<xliff:g id="PROC">%1$s</xliff:g> ہیپ ڈمپ تیار ہے"</string>
<string name="dump_heap_notification_detail" msgid="8431586843001054050">"ہیپ ڈمپ جمع ہو گیا ہے۔ اشتراک کرنے کیلئے تھپتھپائیں۔"</string>
<string name="dump_heap_title" msgid="4367128917229233901">"ہیپ ڈمپ کا اشتراک کریں؟"</string>
- <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> کارروائی اپنی میموری کی حد <xliff:g id="SIZE">%2$s</xliff:g> سے تجاوز کر گئی ہے۔ آپ کے لیے ایک ہیپ ڈمپ اس کے ڈیولپر کے ساتھ اشتراک کرنے کے لیے دستیاب ہے۔ محتاط رہیں: اس ہیپ ڈمپ میں آپ کی کوئی ایسی ذاتی معلومات بھی شامل ہو سکتی ہے جس تک ایپلیکیشن کو رسائی حاصل ہے۔"</string>
+ <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> کارروائی اپنی میموری کی حد <xliff:g id="SIZE">%2$s</xliff:g> سے تجاوز کر گئی ہے۔ آپ کے لیے ایک ہیپ ڈمپ اس کے ڈویلپر کے ساتھ اشتراک کرنے کے لیے دستیاب ہے۔ محتاط رہیں: اس ہیپ ڈمپ میں آپ کی کوئی ایسی ذاتی معلومات بھی شامل ہو سکتی ہے جس تک ایپلیکیشن کو رسائی حاصل ہے۔"</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g> پروسیس نے اپنی میموری کی حد <xliff:g id="SIZE">%2$s</xliff:g> سے بڑھا لی ہے۔ آپ کے اشتراک کرنے کے لیے ہیپ ڈمپ دستیاب ہے۔ محتاط رہیں: اس ہیپ ڈمپ میں حساس ذاتی معلومات ہو سکتی ہے، جس میں آپ کے ذریعے ٹائپ کردہ چیزیں شامل ہو سکتی ہیں، جس تک پروسیس کو رسائی حاصل ہو سکتی ہے۔"</string>
<string name="dump_heap_ready_text" msgid="5849618132123045516">"<xliff:g id="PROC">%1$s</xliff:g> کے پروسیس کا ہیپ ڈمپ آپ کے اشتراک کے لیے دستیاب ہے۔ محتاط رہیں: اس ہیپ ڈمپ میں ممکنہ طور پر حساس ذاتی معلومات ہو سکتی ہے، جس میں آپ کے ذریعے ٹائپ کردہ چیزیں شامل ہو سکتی ہیں، جس تک پروسیس کو رسائی حاصل ہو سکتی ہے۔"</string>
<string name="sendText" msgid="493003724401350724">"متن کیلئے ایک کارروائی منتخب کریں"</string>
@@ -1891,7 +1891,7 @@
<string name="work_mode_turn_on" msgid="3662561662475962285">"آن کریں"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"ایپ دستیاب نہیں ہے"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ابھی دستیاب نہیں ہے۔"</string>
- <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏یہ ایپ Android کے پرانے ورژن کے لئے بنائی گئی ہے اور ہو سکتا ہے صحیح طور پر کام نہ کرے۔ اپ ڈیٹس چیک کر کے آزمائیں یا ڈیولپر سے رابطہ کریں۔"</string>
+ <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏یہ ایپ Android کے پرانے ورژن کے لئے بنائی گئی ہے اور ہو سکتا ہے صحیح طور پر کام نہ کرے۔ اپ ڈیٹس چیک کر کے آزمائیں یا ڈویلپر سے رابطہ کریں۔"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"اپ ڈیٹ چیک کریں"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"آپ کے پاس نئے پیغامات ہیں"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏دیکھنے کیلئے SMS ایپ کھولیں"</string>
@@ -2071,7 +2071,7 @@
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏SIM نیٹ ورک غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏SIM نیٹ ورک سب سیٹ کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏SIM کارپوریٹ کو غیر مقفل کرنے کا PIN"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"‏SIM کے خدمت کے فراہم کنندہ کو غیر مقفل کرنے کا PIN"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"‏SIM کے سروس فراہم کنندہ کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_SIM_ENTRY" msgid="4487435301206073787">"‏SIM کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"‏PUK درج کریں"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"‏PUK درج کریں"</string>
@@ -2082,7 +2082,7 @@
<string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY" msgid="687618528751880721">"‏RUIM network2 کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY" msgid="6810596579655575381">"‏RUIM hrpd کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY" msgid="2715929642540980259">"‏RUIM کارپوریٹ کو غیر مقفل کرنے کا PIN"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"‏RUIM خدمت کے فراہم کنندہ کو غیر مقفل کرنے کا PIN"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"‏RUIM سروس فراہم کنندہ کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY" msgid="7382468767274580323">"‏RUIM کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"‏PUK درج کریں"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"‏PUK درج کریں"</string>
@@ -2094,10 +2094,10 @@
<string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY" msgid="3988705848553894358">"‏SP Equivalent Home PLMN کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_ICCID_ENTRY" msgid="6186770686690993200">"‏ICCID کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_IMPI_ENTRY" msgid="7043865376145617024">"‏IMPI کو غیر مقفل کرنے کا PIN"</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY" msgid="6144227308185112176">"‏نیٹ ورک سب سیٹ خدمت کے فراہم کنندہ کو غیر مقفل کرنے کا PIN"</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY" msgid="6144227308185112176">"‏نیٹ ورک سب سیٹ سروس فراہم کنندہ کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS" msgid="4233355366318061180">"‏SIM نیٹ ورک کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS" msgid="6742563947637715645">"‏SIM نیٹ ورک سب سیٹ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے …"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="2033399698172403560">"‏SIM کے خدمت کے فراہم کنندہ کو غیر مقفل کرنے کی درخواست کی جار ہی ہے…"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="2033399698172403560">"‏SIM کے سروس فراہم کنندہ کو غیر مقفل کرنے کی درخواست کی جار ہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS" msgid="4795977251920732254">"‏SIM کارپوریٹ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS" msgid="1090425878157254446">"‏PUK کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS" msgid="6476898876518094438">"‏PUK کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
@@ -2108,13 +2108,13 @@
<string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS" msgid="4013870911606478520">"‏RUIM network1 کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS" msgid="9032651188219523434">"‏RUIM network2 کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS" msgid="6584576506344491207">"‏RUIM hrpd کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="830981927724888114">"‏RUIM خدمت کے فراہم کنندہ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS" msgid="830981927724888114">"‏RUIM سروس فراہم کنندہ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS" msgid="7851790973098894802">"‏RUIM کارپوریٹ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS" msgid="1149560739586960121">"‏SPN کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS" msgid="5708964693522116025">"‏Requesting SP Equivalent Home کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS" msgid="7288103122966483455">"‏ICCID کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS" msgid="4036752174056147753">"‏IMPI کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS" msgid="5089536274515338566">"نیٹ ورک سب سیٹ کے خدمت کے فراہم کنندہ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS" msgid="5089536274515338566">"نیٹ ورک سب سیٹ کے سروس فراہم کنندہ کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS" msgid="6737197986936251958">"‏RUIM کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS" msgid="5658767775619998623">"‏PUK کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS" msgid="665978313257653727">"‏PUK کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
@@ -2124,14 +2124,14 @@
<string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS" msgid="1230605365926493599">"‏PUK کو غیر مقفل کرنے کی درخواست کی جا رہی ہے…"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ERROR" msgid="1924844017037151535">"‏SIM نیٹ ورک کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR" msgid="3372797822292089708">"‏SIM نیٹ ورک سب سیٹ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"‏SIM کے خدمت کے فراہم کنندہ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR" msgid="1878443146720411381">"‏SIM کے سروس فراہم کنندہ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR" msgid="7664778312218023192">"‏SIM کارپوریٹ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_SIM_ERROR" msgid="2472944311643350302">"‏SIM کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR" msgid="828089694480999120">"‏RUIM Network1 کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR" msgid="17619001007092511">"‏RUIM Network2 غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_RUIM_HRPD_ERROR" msgid="807214229604353614">"‏RUIM Hrpd کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR" msgid="8644184447744175747">"‏RUIM کارپوریٹ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"‏RUIM خدمت کے فراہم کنندہ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR" msgid="3801002648649640407">"‏RUIM سروس فراہم کنندہ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_RUIM_RUIM_ERROR" msgid="707397021218680753">"‏RUIM کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR" msgid="894358680773257820">"‏PUK غیر مقفل نہیں ہو سکا۔"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR" msgid="352466878146726991">"‏PUK غیر مقفل نہیں ہو سکا۔"</string>
@@ -2148,16 +2148,16 @@
<string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR" msgid="1116993930995545742">"‏SP Equivalent Home PLMN کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_ICCID_ERROR" msgid="7559167306794441462">"‏ICCID کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_IMPI_ERROR" msgid="2782926139511136588">"‏IMPI کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR" msgid="1890493954453456758">"نیٹ ورک سب سیٹ خدمت کے فراہم کنندہ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR" msgid="1890493954453456758">"نیٹ ورک سب سیٹ سروس فراہم کنندہ کو غیر مقفل کرنے کی درخواست ناکام ہو گئی۔"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS" msgid="4886243367747126325">"‏SIM نیٹ ورک غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS" msgid="4053809277733513987">"‏SIM نیٹ ورک سب سیٹ غیر مقفل ہو گیا۔"</string>
- <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS" msgid="8249342930499801740">"‏SIM کے خدمت کا فراہم کنندہ غیر مقفل ہو گیا۔"</string>
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS" msgid="8249342930499801740">"‏SIM کے سروس فراہم کنندہ غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS" msgid="2339794542560381270">"‏SIM کارپوریٹ غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_SIM_SIM_SUCCESS" msgid="6975608174152828954">"‏SIM غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS" msgid="2846699261330463192">"‏RUIM Network1 غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS" msgid="5335414726057102801">"‏RUIM Network2 غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS" msgid="8868100318474971969">"‏RUIM Hrpd غیر مقفل ہو گیا۔"</string>
- <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS" msgid="6020936629725666932">"‏RUIM خدمت کا فراہم کنندہ غیر مقفل ہو گیا۔"</string>
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS" msgid="6020936629725666932">"‏RUIM سروس فراہم کنندہ غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS" msgid="6944873647584595489">"‏RUIM کارپوریٹ غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS" msgid="2526483514124121988">"‏RUIM غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS" msgid="7662200333621664621">"‏PUK غیر مقفل ہو گیا۔"</string>
@@ -2175,7 +2175,7 @@
<string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS" msgid="8146602361895007345">"‏SP Equivalent Home PLMN غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS" msgid="8058678548991999545">"‏ICCID غیر مقفل ہو گیا۔"</string>
<string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS" msgid="2545608067978550571">"‏IMPI غیر مقفل ہو گیا۔"</string>
- <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS" msgid="4352382949744625007">"نیٹ ورک سب سیٹ کے خدمت کا فراہم کنندہ غیر مقفل ہو گیا۔"</string>
+ <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS" msgid="4352382949744625007">"نیٹ ورک سب سیٹ کے سروس فراہم کنندہ غیر مقفل ہو گیا۔"</string>
<string name="config_pdp_reject_dialog_title" msgid="4072057179246785727"></string>
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index a3a59e31db57..34c48966bc8c 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1219,7 +1219,7 @@
<string name="volume_music" msgid="7727274216734955095">"Multimedia tovushi"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth orqali ijro etilmoqda"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Ovozsiz rejim tanlandi"</string>
- <string name="volume_call" msgid="7625321655265747433">"Suhbat vaqtidagi tovush balandligi"</string>
+ <string name="volume_call" msgid="7625321655265747433">"Suhbat tovushi"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Kiruvchi bluetooth tovushi"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Signal tovushi"</string>
<string name="volume_notification" msgid="6864412249031660057">"Eslatma tovushi"</string>
@@ -1231,7 +1231,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Eslatma tovushi"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Standart rington"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Standart (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Yo‘q"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Hech qanday"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Ringtonlar"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Signal ovozlari"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Bildirishnoma ovozlari"</string>
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Administrator tomonidan yangilangan"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administrator tomonidan o‘chirilgan"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Batareya quvvatini uzaytirish uchun Quvvat tejash funksiyasi:\n\n•Tungi mavzuni yoqadi\n•Fondagi harakatlar, vizual effektlar va “Hey Google” kabi boshqa funksiyalarni faolsizlantiradi\n\n"<annotation id="url">"Batafsil"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"Batareya quvvatini uzaytirish uchun Quvvat tejash funksiyasi:\n\n•Tungi mavzuni yoqadi\n•Fondagi harakatlar, vizual effektlar va “Hey Google” kabi boshqa funksiyalarni faolsizlantiradi"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Batareya quvvatini uzaytirish uchun Quvvat tejash funksiyasi:\n\n•Tungi mavzuni yoqadi\n•Fondagi harakatlar, vizual effektlar va “Ok Google” kabi boshqa funksiyalarni faolsizlantiradi\n\n"<annotation id="url">"Batafsil"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"Batareya quvvatini uzaytirish uchun Quvvat tejash funksiyasi:\n\n•Tungi mavzuni yoqadi\n•Fondagi harakatlar, vizual effektlar va “Ok Google” kabi boshqa funksiyalarni faolsizlantiradi"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Trafik tejash rejimida ayrim ilovalar uchun orqa fonda internetdan foydalanish imkoniyati cheklanadi. Siz ishlatayotgan ilova zaruratga qarab internet-trafik sarflashi mumkin, biroq cheklangan miqdorda. Masalan, rasmlar ustiga bosmaguningizcha ular yuklanmaydi."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Trafik tejash yoqilsinmi?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Yoqish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 701604037d4a..1a0ec2a1c763 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1128,10 +1128,10 @@
<string name="whichViewApplication" msgid="5733194231473132945">"Mở bằng"</string>
<string name="whichViewApplicationNamed" msgid="415164730629690105">"Mở bằng %1$s"</string>
<string name="whichViewApplicationLabel" msgid="7367556735684742409">"Mở"</string>
- <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng"</string>
- <string name="whichOpenLinksWith" msgid="1120936181362907258">"Mở đường dẫn liên kết bằng"</string>
- <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Mở đường dẫn liên kết bằng <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
- <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+ <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Mở đường liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng"</string>
+ <string name="whichOpenLinksWith" msgid="1120936181362907258">"Mở đường liên kết bằng"</string>
+ <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Mở đường liên kết bằng <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+ <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Mở đường liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
<string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Cấp quyền truy cập"</string>
<string name="whichEditApplication" msgid="6191568491456092812">"Chỉnh sửa bằng"</string>
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Chỉnh sửa bằng %1$s"</string>
diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml
index 083f9d05069e..375fc5c10baf 100644
--- a/packages/CarSystemUI/res/values-ca/strings.xml
+++ b/packages/CarSystemUI/res/values-ca/strings.xml
@@ -24,7 +24,7 @@
<string name="start_guest_session" msgid="497784785761754874">"Convidat"</string>
<string name="car_add_user" msgid="4067337059622483269">"Afegeix un usuari"</string>
<string name="car_new_user" msgid="6637442369728092473">"Usuari nou"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai."</string>
+ <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai."</string>
<string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"S\'està carregant"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"S\'està carregant l\'usuari (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml
index c1c21d17a3a7..027242a536fa 100644
--- a/packages/CarSystemUI/res/values-es-rUS/strings.xml
+++ b/packages/CarSystemUI/res/values-es-rUS/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Agregar usuario"</string>
<string name="car_new_user" msgid="6637442369728092473">"Usuario nuevo"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando agregues un usuario nuevo, esa persona deberá configurar su espacio."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario podrá actualizar las apps de otras personas."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml
index 60689695725c..6abf92ffa77a 100644
--- a/packages/CarSystemUI/res/values-fi/strings.xml
+++ b/packages/CarSystemUI/res/values-fi/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Lisää käyttäjä"</string>
<string name="car_new_user" msgid="6637442369728092473">"Uusi käyttäjä"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Kun lisäät uuden käyttäjän, hänen on valittava oman tilansa asetukset."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Ladataan"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ladataan käyttäjäprofiilia (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml
index 901cbe759d63..1145dc32dcb0 100644
--- a/packages/CarSystemUI/res/values-in/strings.xml
+++ b/packages/CarSystemUI/res/values-in/strings.xml
@@ -24,7 +24,7 @@
<string name="start_guest_session" msgid="497784785761754874">"Tamu"</string>
<string name="car_add_user" msgid="4067337059622483269">"Tambahkan Pengguna"</string>
<string name="car_new_user" msgid="6637442369728092473">"Pengguna Baru"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri."</string>
+ <string name="user_add_user_message_setup" msgid="1035578846007352323">"Jika ditambahkan, pengguna baru harus menyiapkan ruangnya sendiri."</string>
<string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Memuat"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuat pengguna (dari <xliff:g id="FROM_USER">%1$d</xliff:g> menjadi <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml
index f9449be39540..5220aa5bf1bd 100644
--- a/packages/CarSystemUI/res/values-kk/strings.xml
+++ b/packages/CarSystemUI/res/values-kk/strings.xml
@@ -24,7 +24,7 @@
<string name="start_guest_session" msgid="497784785761754874">"Қонақ"</string>
<string name="car_add_user" msgid="4067337059622483269">"Пайдаланушыны енгізу"</string>
<string name="car_new_user" msgid="6637442369728092473">"Жаңа пайдаланушы"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Енгізілген жаңа пайдаланушы өз профилін реттеуі керек."</string>
+ <string name="user_add_user_message_setup" msgid="1035578846007352323">"Қосылған жаңа пайдаланушы өз профилін реттеуі керек."</string>
<string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Жүктелуде"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Пайдаланушы профилі жүктелуде (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml
index b093363d0c23..b3b355a42aa8 100644
--- a/packages/CarSystemUI/res/values-ky/strings.xml
+++ b/packages/CarSystemUI/res/values-ky/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Колдонуучу кошуу"</string>
<string name="car_new_user" msgid="6637442369728092473">"Жаңы колдонуучу"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Жаңы колдонуучу кошулганда, ал өзүнүн профилин жөндөп алышы керек."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу калган бардык колдонуучулар үчүн да жаңырта алат."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Жүктөлүүдө"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Колдонуучу тууралуу маалымат жүктөлүүдө (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-ne/strings.xml b/packages/CarSystemUI/res/values-ne/strings.xml
index 70bcfc763cf2..40639dedc4b5 100644
--- a/packages/CarSystemUI/res/values-ne/strings.xml
+++ b/packages/CarSystemUI/res/values-ne/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"प्रयोगकर्ता थप्नुहोस्"</string>
<string name="car_new_user" msgid="6637442369728092473">"नयाँ प्रयोगकर्ता"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"तपाईंले नयाँ प्रयोगकर्ता थप्दा ती व्यक्तिले आफ्नो स्थान सेटअप गर्नु पर्छ।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका एपहरू अद्यावधिक गर्न सक्छन्।"</string>
<string name="car_loading_profile" msgid="4507385037552574474">"लोड गरिँदै"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"प्रयोगकर्तासम्बन्धी जानकारी लोड गरिँदै (<xliff:g id="FROM_USER">%1$d</xliff:g> बाट <xliff:g id="TO_USER">%2$d</xliff:g> मा)"</string>
</resources>
diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml
index ea99f0faf5e0..2016b7b18adf 100644
--- a/packages/CarSystemUI/res/values-sk/strings.xml
+++ b/packages/CarSystemUI/res/values-sk/strings.xml
@@ -25,7 +25,7 @@
<string name="car_add_user" msgid="4067337059622483269">"Pridať používateľa"</string>
<string name="car_new_user" msgid="6637442369728092473">"Nový používateľ"</string>
<string name="user_add_user_message_setup" msgid="1035578846007352323">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Ktorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
+ <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý používateľ môže aktualizovať aplikácie pre všetkých ostatných používateľov."</string>
<string name="car_loading_profile" msgid="4507385037552574474">"Načítava sa"</string>
<string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítava sa používateľ (predchádzajúci: <xliff:g id="FROM_USER">%1$d</xliff:g>, nasledujúci: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index f42bf1982b36..11d1b0a9ef2a 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -483,6 +483,13 @@ public class ExternalStorageProvider extends FileSystemProvider {
}
@Override
+ protected void onDocIdDeleted(String docId) {
+ Uri uri = DocumentsContract.buildDocumentUri(AUTHORITY, docId);
+ getContext().revokeUriPermission(uri, ~0);
+ }
+
+
+ @Override
public Cursor queryRoots(String[] projection) throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
synchronized (mRootsLock) {
diff --git a/packages/SettingsLib/HelpUtils/res/values-es/strings.xml b/packages/SettingsLib/HelpUtils/res/values-es/strings.xml
index 97ff5efc6401..97e3559914a2 100644
--- a/packages/SettingsLib/HelpUtils/res/values-es/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-es/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="7106780063063027882">"Ayuda y sugerencias"</string>
+ <string name="help_feedback_label" msgid="7106780063063027882">"Ayuda y comentarios"</string>
</resources>
diff --git a/packages/SettingsLib/HelpUtils/res/values-te/strings.xml b/packages/SettingsLib/HelpUtils/res/values-te/strings.xml
index ea66717b1e87..82c8613b5c8c 100644
--- a/packages/SettingsLib/HelpUtils/res/values-te/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-te/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="7106780063063027882">"సహాయం &amp; అభిప్రాయం"</string>
+ <string name="help_feedback_label" msgid="7106780063063027882">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index a640da4deb4d..df7a260b4045 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -25,7 +25,7 @@
<string name="wifi_remembered" msgid="3266709779723179188">"تم الحفظ"</string>
<string name="wifi_disconnected" msgid="7054450256284661757">"غير متصلة"</string>
<string name="wifi_disabled_generic" msgid="2651916945380294607">"غير مفعّلة"</string>
- <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏تعذّرت تهيئة عنوان IP"</string>
+ <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏تعذّر إعداد عنوان IP"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"الجهاز غير متصل بسبب انخفاض جودة الشبكة"</string>
<string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‏تعذّر اتصال WiFi"</string>
<string name="wifi_disabled_password_failure" msgid="6892387079613226738">"حدثت مشكلة في المصادقة"</string>
@@ -85,7 +85,7 @@
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"المكالمات الهاتفية"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز الإرسال"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"الدخول إلى الإنترنت"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"استخدام الإنترنت"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"مشاركة جهة الاتصال"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"استخدام مع مشاركة جهة الاتصال"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"مشاركة اتصال الإنترنت"</string>
@@ -153,7 +153,7 @@
<string name="unknown" msgid="3544487229740637809">"غير معروف"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"المستخدم: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"تم ضبط بعض الإعدادات التلقائية"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"لم يتم تعيين إعدادات تلقائية"</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"لم يتم ضبط إعدادات تلقائية"</string>
<string name="tts_settings" msgid="8130616705989351312">"إعدادات تحويل النص إلى كلام"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"تحويل النص إلى كلام"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"معدل سرعة الكلام"</string>
@@ -245,7 +245,7 @@
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"هل تريد السماح بإلغاء قفل المصنّع الأصلي للجهاز؟"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"تحذير: لن تعمل ميزات الحماية على هذا الجهاز أثناء تفعيل هذا الإعداد."</string>
<string name="mock_location_app" msgid="6269380172542248304">"اختيار تطبيق الموقع الزائف"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"لم يتم تعيين تطبيق موقع زائف"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"لم يتم ضبط تطبيق موقع زائف"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"تطبيق الموقع الزائف: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"الشبكات"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"شهادة عرض شاشة لاسلكي"</string>
@@ -293,8 +293,8 @@
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"عندما نتوقف عن رصد أي أخطاء باستخدام المسجِّل الدائم مرة أخرى، يتعين علينا محو بيانات المسجِّل الموجودة على جهازك."</string>
<string name="select_logpersist_title" msgid="447071974007104196">"تخزين بيانات المسجِّل باستمرار على الجهاز"</string>
<string name="select_logpersist_dialog_title" msgid="7745193591195485594">"تحديد مخازن السجلات المؤقتة المراد تخزينها باستمرار على الجهاز"</string>
- <string name="select_usb_configuration_title" msgid="6339801314922294586">"‏حدد تهيئة USB"</string>
- <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"‏حدد تهيئة USB"</string>
+ <string name="select_usb_configuration_title" msgid="6339801314922294586">"‏حدد إعداد USB"</string>
+ <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"‏حدد إعداد USB"</string>
<string name="allow_mock_location" msgid="2102650981552527884">"السماح بمواقع وهمية"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"السماح بمواقع وهمية"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"تفعيل فحص سمة العرض"</string>
@@ -319,7 +319,7 @@
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تعيين سلوك التحقق من HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"تصحيح الأخطاء"</string>
<string name="debug_app" msgid="8903350241392391766">"اختيار التطبيق لتصحيحه"</string>
- <string name="debug_app_not_set" msgid="1934083001283807188">"لم يتم تعيين تطبيق لتصحيحه"</string>
+ <string name="debug_app_not_set" msgid="1934083001283807188">"لم يتم ضبط تطبيق لتصحيحه"</string>
<string name="debug_app_set" msgid="6599535090477753651">"تطبيق التصحيح: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="select_application" msgid="2543228890535466325">"اختيار تطبيق"</string>
<string name="no_application" msgid="9038334538870247690">"لا شيء"</string>
@@ -382,9 +382,9 @@
<string name="local_backup_password_title" msgid="4631017948933578709">"كلمة مرور احتياطية للكمبيوتر"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"النُسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
- <string name="local_backup_password_toast_success" msgid="4891666204428091604">"تم تعيين كلمة مرور احتياطية جديدة"</string>
+ <string name="local_backup_password_toast_success" msgid="4891666204428091604">"تم ضبط كلمة مرور احتياطية جديدة"</string>
<string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"كلمة المرور الجديدة وتأكيدها لا يتطابقان"</string>
- <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"تعذّر تعيين كلمة مرور احتياطية"</string>
+ <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"تعذّر ضبط كلمة مرور احتياطية"</string>
<string name="loading_injected_setting_summary" msgid="8394446285689070348">"جارٍ التحميل…"</string>
<string-array name="color_mode_names">
<item msgid="3836559907767149216">"نابض بالحياة (تلقائي)"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 3ced29b47dd6..4ace288034bd 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -27,7 +27,7 @@
<string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogućeno"</string>
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP konfiguracija je otkazala"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nije povezano zbog lošeg kvaliteta mreže"</string>
- <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi veza je otkazala"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi veza je otkazala"</string>
<string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem sa potvrdom identiteta"</string>
<string name="wifi_cant_connect" msgid="5718417542623056783">"Povezivanje nije uspelo"</string>
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Povezivanje sa „<xliff:g id="AP_NAME">%1$s</xliff:g>“ nije uspelo"</string>
@@ -131,12 +131,12 @@
<string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Uparivanje desnog slušnog aparata…"</string>
<string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Levi – nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"Desni – nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="accessibility_wifi_off" msgid="1195445715254137155">"Wi-Fi je isključen."</string>
- <string name="accessibility_no_wifi" msgid="5297119459491085771">"Wi-Fi veza je prekinuta."</string>
- <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"Wi-Fi signal ima jednu crtu."</string>
- <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi signal ima dve crte."</string>
- <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi signal ima tri crte."</string>
- <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi signal je najjači."</string>
+ <string name="accessibility_wifi_off" msgid="1195445715254137155">"WiFi je isključen."</string>
+ <string name="accessibility_no_wifi" msgid="5297119459491085771">"WiFi veza je prekinuta."</string>
+ <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"WiFi signal ima jednu crtu."</string>
+ <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi signal ima dve crte."</string>
+ <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi signal ima tri crte."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi signal je najjači."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorena mreža"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Bezbedna mreža"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
@@ -232,7 +232,7 @@
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i port"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skeniraj QR kôd"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparite uređaj pomoću Wi‑Fi mreže tako što ćete skenirati QR kôd"</string>
- <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na Wi-Fi mrežu"</string>
+ <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na WiFi mrežu"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izveštaj o greškama"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Prikaži dugme u meniju napajanja za pravljenje izveštaja o greškama"</string>
@@ -250,7 +250,7 @@
<string name="debug_networking_category" msgid="6829757985772659599">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Sertifikacija bežičnog ekrana"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje Wi-Fi skeniranja"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje WiFi skeniranja"</string>
<string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasumično MAC razvrstavanje po Wi‑Fi‑ju"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilni podaci su uvek aktivni"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzanje privezivanja"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 01d7682416fa..00a6bfc935a7 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Л: акумулятар: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, П: акумулятар: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Уключана"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аўдыё медыяпрылады"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аўдыя медыяфайлаў"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Тэлефонныя выклікі"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Перадача файлаў"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Прылада ўводу"</string>
@@ -212,7 +212,7 @@
<string name="adb_wireless_settings" msgid="2295017847215680229">"Адладка па Wi-Fi"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Каб праглядаць і выкарыстоўваць даступныя прылады, уключыце адладку па Wi-Fi"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Спалучыць прыладу з дапамогай QR-кода"</string>
- <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кода"</string>
+ <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кодаў"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Спалучыць прыладу з дапамогай кода спалучэння"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Спалучаць новыя прылады з дапамогай шасцізначнага кода"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Спалучаныя прылады"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 2db23f73e683..a68b9a4c3a0a 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -211,9 +211,9 @@
<string name="adb_wireless_error" msgid="721958772149779856">"সমস্যা"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"ওয়্যারলেস ডিবাগিং"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"কোন কোন ডিভাইস উপলভ্য আছে তা দেখে নিয়ে ব্যবহার করার জন্য, ওয়্যারলেস ডিবাগিং চালু করুন"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR কোড স্ক্যানার ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"যোগ করার কোড ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"পেয়ারিং কোড ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ছয় সংখ্যার কোড ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"যোগ করা ডিভাইস"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"এখন কানেক্ট রয়েছে"</string>
@@ -222,16 +222,16 @@
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"ডিভাইসে আঙ্গুলের ছাপ: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"কানেক্ট করা যায়নি"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>টি সঠিক নেটওয়ার্কে কানেক্ট আছে কিনা দেখে নিন"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"ডিভাইসের সাথে যোগ করুন"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"ওয়াই-ফাই যোগ করার কোড"</string>
- <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"যোগ করা যায়নি"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"ডিভাইসের সাথে পেয়ার করুন"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"ওয়াই-ফাইয়ের সাথে পেয়ার করার কোড"</string>
+ <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"পেয়ার করা যায়নি"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"ডিভাইসটি একই নেটওয়ার্কে কানেক্ট আছে কিনা দেখে নিন।"</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"ডিভাইস যোগ করা হচ্ছে…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ডিভাইস যোগ করা যায়নি। এটি দুটি কারণে হয়ে থাকে - QR কোডটি সঠিক নয় বা ডিভাইসটি একই নেটওয়ার্কে কানেক্ট করা নেই।"</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP অ্যাড্রেস ও পোর্ট"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR কোড স্ক্যান করুন"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR কোড স্ক্যান করে ওয়াই-ফাইয়ের সাহায্যে ডিভাইস যোগ করুন"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"একটি ওয়াই-ফাই নেটওয়ার্কের সাথে কানেক্ট করুন"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"ত্রুটি প্রতিবেদনের শর্টকাট"</string>
@@ -488,8 +488,8 @@
<string name="status_unavailable" msgid="5279036186589861608">"অনুপলভ্য"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC র‍্যান্ডমাইজ করা হয়েছে"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
- <item quantity="one">%1$dটি ডিভাইস কানেক্ট</item>
- <item quantity="other">%1$dটি ডিভাইস কানেক্ট</item>
+ <item quantity="one">%1$dটি ডিভাইস কানেক্ট রয়েছে</item>
+ <item quantity="other">%1$dটি ডিভাইস কানেক্ট রয়েছে</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"আরও বেশি।"</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"আরও কম।"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 6595c226a171..aaaddf0bd4d1 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -27,7 +27,7 @@
<item msgid="8356618438494652335">"Autentifikacija…"</item>
<item msgid="2837871868181677206">"Dobivanje IP adrese…"</item>
<item msgid="4613015005934755724">"Povezano"</item>
- <item msgid="3763530049995655072">"Suspendirano"</item>
+ <item msgid="3763530049995655072">"Obustavljeno"</item>
<item msgid="7852381437933824454">"Prekidanje veze…"</item>
<item msgid="5046795712175415059">"Isključen"</item>
<item msgid="2473654476624070462">"Neuspješno"</item>
@@ -41,7 +41,7 @@
<item msgid="3028983857109369308">"Autentifikacija s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="4287401332778341890">"Dobivanje IP adrese iz mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="1043944043827424501">"Povezano s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
- <item msgid="7445993821842009653">"Suspendirano"</item>
+ <item msgid="7445993821842009653">"Obustavljeno"</item>
<item msgid="1175040558087735707">"Prekidanje veze s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="699832486578171722">"Isključen"</item>
<item msgid="522383512264986901">"Neuspješno"</item>
@@ -187,7 +187,7 @@
<item msgid="97587758561106269">"Isključeno"</item>
<item msgid="7126170197336963369">"Međuspremnici svih zapisnika"</item>
<item msgid="7167543126036181392">"Međuspremnici svih zapisnika osim radija"</item>
- <item msgid="5135340178556563979">"samo međuspremnik zapisnika kernela"</item>
+ <item msgid="5135340178556563979">"samo međumemorija zapisnika kernela"</item>
</string-array>
<string-array name="window_animation_scale_entries">
<item msgid="2675263395797191850">"Animacija isključena"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index f26fe9d58533..a7468b2a507b 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -474,7 +474,7 @@
<string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Najveći"</string>
<string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="content_description_menu_button" msgid="6254844309171779931">"Meni"</string>
- <string name="retail_demo_reset_message" msgid="5392824901108195463">"Unesite lozinku da izvršite vraćanje na fabričke postavke u načinu demonstracije"</string>
+ <string name="retail_demo_reset_message" msgid="5392824901108195463">"Unesite lozinku da izvršite vraćanje na fabričke postavke u načinu rada za demonstraciju"</string>
<string name="retail_demo_reset_next" msgid="3688129033843885362">"Naprijed"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"Potrebna je lozinka"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"Aktivne metode unosa"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 3ca9d5272d48..3363fddbb8d3 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -66,7 +66,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconnectat"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"S\'està desconnectant..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"S\'està connectant…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connectat"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"S\'està vinculant..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense accés al telèfon)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense contingut multimèdia)"</string>
@@ -532,7 +532,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restringit"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Vols afegir un usuari nou?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Pots compartir aquest dispositiu amb altres persones creant usuaris addicionals. Cada usuari té el seu propi espai, que pot personalitzar amb aplicacions i fons de pantalla, entre d\'altres. Els usuaris també poden ajustar opcions de configuració del dispositiu, com ara la Wi-Fi, que afecten els altres usuaris.\n\nQuan afegeixis un usuari nou, haurà de configurar el seu espai.\n\nTots els usuaris poden actualitzar les aplicacions de la resta. És possible que la configuració i els serveis d\'accessibilitat no es transfereixin a l\'usuari nou."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Vols configurar l\'usuari ara?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Assegura\'t que la persona estigui disponible per accedir al dispositiu i configurar el seu espai."</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vols configurar el perfil ara?"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 287a1aca2fbd..8b4ae9eb0ab7 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -196,7 +196,7 @@
<string name="choose_profile" msgid="343803890897657450">"Elegir perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Trabajo"</string>
- <string name="development_settings_title" msgid="140296922921597393">"Opciones para programadores"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"Opciones para desarrolladores"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activar opciones para programador"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Establecer opciones para desarrollar aplicaciones"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"Las opciones de programador no están disponibles para este usuario."</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 9d3455766f6b..bd92738844f0 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -511,7 +511,7 @@
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altavoz del teléfono"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
- <string name="help_label" msgid="3528360748637781274">"Ayuda y sugerencias"</string>
+ <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
<string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
<string name="shared_data_title" msgid="1017034836800864953">"Datos compartidos"</string>
<string name="shared_data_summary" msgid="5516326713822885652">"Ver y modificar los datos compartidos"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index d003ef0b9c71..dcb23d891113 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> akut"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> akut, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> akut"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivne"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Meedia heli"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Meediaheli"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonikõned"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failiedastus"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Sisendseade"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 0042321a3654..eaf14f0bfb53 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -401,7 +401,7 @@
<string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktibo. Aldatzeko, sakatu hau."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Egonean moduko aplikazioaren egoera: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Abian diren zerbitzuak"</string>
- <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ikusi eta kontrolatu unean abian diren zerbitzuak"</string>
+ <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ikusi eta kontrolatu une honetan abian diren zerbitzuak"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView inplementazioa"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ezarri WebView inplementazioa"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Jada ez dago erabilgarri aukera hori. Saiatu berriro."</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 1c0881531f89..65ced77c210e 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -28,7 +28,7 @@
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏پیکربندی IP انجام نشد"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"اتصال ناموفق به دلیل شبکه با کیفیت پایین"</string>
<string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‏اتصال Wi-Fi برقرار نشد"</string>
- <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"مشکل احراز هویت"</string>
+ <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"مشکل اصالت‌سنجی"</string>
<string name="wifi_cant_connect" msgid="5718417542623056783">"برقراری اتصال ممکن نیست"</string>
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"برقراری اتصال به «<xliff:g id="AP_NAME">%1$s</xliff:g>» ممکن نیست"</string>
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"گذرواژه را بررسی و دوباره امتحان کنید"</string>
@@ -139,7 +139,7 @@
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"‏قدرت سیگنال Wi‑Fi کامل است."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"شبکه باز"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"شبکه ایمن"</string>
- <string name="process_kernel_label" msgid="950292573930336765">"‏سیستم عامل Android"</string>
+ <string name="process_kernel_label" msgid="950292573930336765">"‏سیستم‌عامل Android"</string>
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"برنامه‌های حذف شده"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"برنامه‌ها و کاربران حذف شده"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"به‌روزرسانی‌های سیستم"</string>
@@ -211,8 +211,8 @@
<string name="adb_wireless_error" msgid="721958772149779856">"خطا"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"اشکال‌زدایی بی‌سیم"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"برای مشاهده و استفاده از دستگاه‌های در دسترس، اشکال‌زدایی بی‌سیم را روشن کنید"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"‏مرتبط کردن دستگاه با کد QR"</string>
- <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"‏دستگاه‌های جدید را بااستفاده از اسکنر کد QR مرتبط کنید"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"مرتبط کردن دستگاه با رمزینه پاسخ‌سریع"</string>
+ <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"دستگاه‌های جدید را بااستفاده از اسکنر رمزینه پاسخ‌سریع مرتبط کنید"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"مرتبط کردن دستگاه با کد مرتبط‌سازی"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"دستگاه‌های جدید را با استفاده از کد شش رقمی مرتبط کنید"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"دستگاه‌های مرتبط‌شده"</string>
@@ -226,12 +226,12 @@
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"‏کد مرتبط‌سازی Wi‑Fi"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"مرتبط‌سازی ناموفق"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"مطمئن شوید که دستگاه به همان شبکه متصل باشد."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"‏دستگاه را ازطریق Wi‑Fi و با اسکن کردن کد QR مرتبط کنید"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"‏دستگاه را ازطریق Wi‑Fi و با اسکن کردن رمزینه پاسخ‌سریع مرتبط کنید"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"مرتبط‌سازی دستگاه…"</string>
- <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"‏مرتبط کردن دستگاه انجام نشد. یا کد QR اشتباه بوده است، یا دستگاه به همان شبکه متصل نیست."</string>
+ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"مرتبط کردن دستگاه انجام نشد. یا رمزینه پاسخ‌سریع اشتباه بوده است، یا دستگاه به همان شبکه متصل نیست."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"‏نشانی IP و درگاه"</string>
- <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"‏اسکن کد QR"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"‏دستگاه را ازطریق Wi‑Fi و با اسکن کردن کد QR مرتبط کنید"</string>
+ <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"اسکن رمزینه پاسخ‌سریع"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"‏دستگاه را ازطریق Wi‑Fi و با اسکن کردن رمزینه پاسخ‌سریع مرتبط کنید"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"‏لطفاً به شبکه Wi-Fi متصل شوید"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"‏ADB (پل اشکال‌زدایی Android)، اشکال‌زدایی کردن، برنامه‌نویس"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"میان‌بر گزارش مشکل"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 140d4cee6ad7..cb601c164f83 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -142,7 +142,7 @@
<string name="process_kernel_label" msgid="950292573930336765">"Système d\'exploitation Android"</string>
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applications supprimées"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applications et utilisateurs supprimés"</string>
- <string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour système"</string>
+ <string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour du système"</string>
<string name="tether_settings_title_usb" msgid="3728686573430917722">"Partage de connexion par USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Point d\'accès Wi-Fi mobile"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Partage connexion Bluetooth"</string>
@@ -489,6 +489,7 @@
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"Les adresses MAC sont randomisées"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
<item quantity="one">%1$d appareil connecté</item>
+ <item quantity="many">%1$d devices connected</item>
<item quantity="other">%1$d appareils connectés</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
@@ -498,7 +499,7 @@
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
- <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priorités seulement"</string>
+ <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Prioritaires seulement"</string>
<string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Vous n\'entendrez pas votre prochaine alarme à <xliff:g id="WHEN">%1$s</xliff:g> sauf si vous désactivez préalablement cette option"</string>
<string name="zen_alarm_warning" msgid="245729928048586280">"Vous n\'entendrez pas votre prochaine alarme à <xliff:g id="WHEN">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index c73da50b6de6..d4d79495e955 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -165,7 +165,7 @@
<string name="tts_lang_not_selected" msgid="7927823081096056147">"Langue non sélectionnée"</string>
<string name="tts_default_lang_summary" msgid="9042620014800063470">"Définir la langue utilisée par la synthèse vocale"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"Écouter un échantillon"</string>
- <string name="tts_play_example_summary" msgid="634044730710636383">"Lire une courte démonstration de la synthèse vocale"</string>
+ <string name="tts_play_example_summary" msgid="634044730710636383">"Écoutez une courte démonstration de la synthèse vocale"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"Installer les données vocales"</string>
<string name="tts_install_data_summary" msgid="3608874324992243851">"Installer les données nécessaires à la synthèse vocale"</string>
<string name="tts_engine_security_warning" msgid="3372432853837988146">"Ce moteur de synthèse vocale est susceptible de collecter tout ce qui sera lu, y compris les données personnelles comme les mots de passe et les numéros de carte de paiement. Il provient du moteur <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Voulez-vous activer son utilisation ?"</string>
@@ -189,8 +189,8 @@
<item msgid="1158955023692670059">"Rapide"</item>
<item msgid="5664310435707146591">"Plus rapide"</item>
<item msgid="5491266922147715962">"Très rapide"</item>
- <item msgid="7659240015901486196">"Rapide"</item>
- <item msgid="7147051179282410945">"Très rapide"</item>
+ <item msgid="7659240015901486196">"Beaucoup plus rapide"</item>
+ <item msgid="7147051179282410945">"Extrêmement rapide"</item>
<item msgid="581904787661470707">"La plus rapide"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Sélectionner un profil"</string>
@@ -489,6 +489,7 @@
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"La sélection des adresses MAC est aléatoire"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
<item quantity="one">%1$d appareil connecté</item>
+ <item quantity="many">%1$d devices connected</item>
<item quantity="other">%1$d appareils connectés</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index aa1f9605b07d..eac8ba8aaac0 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -33,11 +33,11 @@
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' સાથે કનેક્ટ કરી શકાતું નથી"</string>
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"પાસવર્ડ તપાસો અને ફરી પ્રયાસ કરો"</string>
<string name="wifi_not_in_range" msgid="1541760821805777772">"રેન્જમાં નથી"</string>
- <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"આપમેળે કનેક્ટ કરશે નહીં"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ઑટોમૅટિક રીતે કનેક્ટ કરશે નહીં"</string>
<string name="wifi_no_internet" msgid="1774198889176926299">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
<string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા સચવાયું"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
- <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા આપમેળે કનેક્ટ થયું"</string>
+ <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા ઑટોમૅટિક રીતે કનેક્ટ થયું"</string>
<string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
<string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કનેક્ટ થયેલ"</string>
<string name="available_via_passpoint" msgid="1716000261192603682">"%1$s દ્વારા ઉપલબ્ધ"</string>
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> બૅટરી, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> બૅટરી"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"સક્રિય"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"મીડિયા ઑડિઓ"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"મીડિયા ઑડિયો"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ફોન કૉલ"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ફાઇલ સ્થાનાંતરણ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ઇનપુટ ઉપકરણ"</string>
@@ -113,7 +113,7 @@
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"ઇનપુટ માટે ઉપયોગ કરો"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"શ્રવણ યંત્રો માટે ઉપયોગ કરો"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"જોડી"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"જોડાણ બનાવો"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"જોડી કરો"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"રદ કરો"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"એ કનેક્ટ કરેલ હોય ત્યારે જોડાણ બનાવવાથી તમારા સંપર્કો અને કૉલ ઇતિહાસનો અ‍ૅક્સેસ મળે છે."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે જોડી કરી શક્યાં નહીં."</string>
@@ -488,8 +488,8 @@
<string name="status_unavailable" msgid="5279036186589861608">"અનુપલબ્ધ"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"MACને રેન્ડમ કરેલ છે"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
- <item quantity="one">%1$d ઉપકરણ કનેક્ટ કર્યું</item>
- <item quantity="other">%1$d ઉપકરણો કનેક્ટ કર્યા</item>
+ <item quantity="one">%1$d ડિવાઇસ કનેક્ટ કર્યું</item>
+ <item quantity="other">%1$d ડિવાઇસ કનેક્ટ કર્યા</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"વધુ સમય."</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ઓછો સમય."</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 9b6a27ae8620..f2de28e0372c 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -488,7 +488,7 @@
<string name="status_unavailable" msgid="5279036186589861608">"मौजूद नहीं है"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"एमएसी पता रैंडम पर सेट है"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
- <item quantity="one">%1$d डिवाइस जुड़े हैं</item>
+ <item quantity="one">%1$d डिवाइस जुड़ा है</item>
<item quantity="other">%1$d डिवाइस जुड़े हैं</item>
</plurals>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ज़्यादा समय."</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index d16ff03b0903..5fbf3ac3b750 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -145,7 +145,7 @@
<string name="data_usage_ota" msgid="7984667793701597001">"Rendszerfrissítések"</string>
<string name="tether_settings_title_usb" msgid="3728686573430917722">"USB-megosztás"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Hordozható hotspot"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth megosztása"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth-megosztás"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Megosztás"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Megosztás és hotspot"</string>
<string name="managed_user_title" msgid="449081789742645723">"Összes munkaalkalmazás"</string>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index a2de6dfc7387..141ce3990800 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -55,7 +55,7 @@
</string-array>
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"Երբեք չօգտագործել HDCP ստուգումը"</item>
- <item msgid="8254225038262324761">"Օգտագործել HDCP-ը` միայն DRM-ի բովանդակությունը ստուգելու համար"</item>
+ <item msgid="8254225038262324761">"Օգտագործել HDCP-ը՝ միայն DRM-ի բովանդակությունը ստուգելու համար"</item>
<item msgid="6421717003037072581">"Միշտ օգտագործել HDCP ստուգումը"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index b010b504b00c..3d25ff85ef05 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -37,7 +37,7 @@
<string name="wifi_no_internet" msgid="1774198889176926299">"Ինտերնետ կապ չկա"</string>
<string name="saved_network" msgid="7143698034077223645">"Ով է պահել՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
- <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ավտոմատ կերպով միացել է ցանցի վարկանիշի ծառայության մատակարարի միջոցով"</string>
+ <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ավտոմատ միացել է ցանցերի վարկանիշի մատակարարի միջոցով"</string>
<string name="connected_via_passpoint" msgid="7735442932429075684">"Միացված է %1$s-ի միջոցով"</string>
<string name="connected_via_app" msgid="3532267661404276584">"Միացված է <xliff:g id="NAME">%1$s</xliff:g>-ի միջոցով"</string>
<string name="available_via_passpoint" msgid="1716000261192603682">"Հասանելի է %1$s-ի միջոցով"</string>
@@ -57,7 +57,7 @@
<string name="osu_sign_up_complete" msgid="7640183358878916847">"Գրանցումն ավարտված է: Միացում…"</string>
<string name="speed_label_very_slow" msgid="8526005255731597666">"Շատ դանդաղ"</string>
<string name="speed_label_slow" msgid="6069917670665664161">"Դանդաղ"</string>
- <string name="speed_label_okay" msgid="1253594383880810424">"Հաստատել"</string>
+ <string name="speed_label_okay" msgid="1253594383880810424">"Լավ"</string>
<string name="speed_label_medium" msgid="9078405312828606976">"Միջին"</string>
<string name="speed_label_fast" msgid="2677719134596044051">"Արագ"</string>
<string name="speed_label_very_fast" msgid="8215718029533182439">"Շատ արագ"</string>
@@ -344,7 +344,7 @@
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Թարմացվելիս ընդգծել սարքաշարի ծածկույթները կանաչ գույնով"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"Վրիպազերծել GPU գերազանցումները"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Կասեցնել HW վրադրումները"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Միշտ օգտագործել GPU-ն` էկրանի կազմման համար"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Միշտ օգտագործել GPU-ն՝ էկրանի կազմման համար"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Նմանակել գունատարածքը"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Ակտիվացնել OpenGL հետքերը"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Անջատել USB աուդիո երթուղումը"</string>
@@ -494,7 +494,7 @@
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Ավելացնել ժամանակը:"</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Պակասեցնել ժամանակը:"</string>
<string name="cancel" msgid="5665114069455378395">"Չեղարկել"</string>
- <string name="okay" msgid="949938843324579502">"Հաստատել"</string>
+ <string name="okay" msgid="949938843324579502">"Եղավ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Երբեք"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index d20bf38024ab..5cdd954d3e6e 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -31,7 +31,7 @@
<item msgid="7852381437933824454">"Memutus sambungan..."</item>
<item msgid="5046795712175415059">"Sambungan terputus"</item>
<item msgid="2473654476624070462">"Gagal"</item>
- <item msgid="9146847076036105115">"Dicekal"</item>
+ <item msgid="9146847076036105115">"Diblokir"</item>
<item msgid="4543924085816294893">"Menghindari sambungan buruk untuk sementara"</item>
</string-array>
<string-array name="wifi_status_with_ssid">
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 42ccd5310913..c68a438e8c08 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -156,7 +156,7 @@
<string name="launch_defaults_none" msgid="8049374306261262709">"Tidak ada setelan default"</string>
<string name="tts_settings" msgid="8130616705989351312">"Setelan text-to-speech"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"Keluaran text-to-speech"</string>
- <string name="tts_default_rate_title" msgid="3964187817364304022">"Laju bicara"</string>
+ <string name="tts_default_rate_title" msgid="3964187817364304022">"Kecepatan ucapan"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"Kecepatan teks diucapkan"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"Tinggi nada"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"Memengaruhi nada ucapan yang disintesis"</string>
@@ -180,8 +180,8 @@
<string name="tts_engine_settings_button" msgid="477155276199968948">"Luncurkan setelan mesin"</string>
<string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Mesin yang dipilih"</string>
<string name="tts_general_section_title" msgid="8919671529502364567">"Umum"</string>
- <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Setel ulang tinggi nada ucapan"</string>
- <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Setel ulang tinggi nada diucapkannya teks menjadi default."</string>
+ <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Reset tinggi nada ucapan"</string>
+ <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Reset tinggi nada diucapkannya teks menjadi default."</string>
<string-array name="tts_rate_entries">
<item msgid="9004239613505400644">"Sangat lambat"</item>
<item msgid="1815382991399815061">"Lambat"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 50fdfc9a9136..94cd9f66a027 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -66,7 +66,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Connessione…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connesso"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"Accoppiamento…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono escluso)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (contenuti multimediali esclusi)"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index d166c179757c..91c2fa20f59a 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -243,7 +243,7 @@
</string-array>
<string-array name="track_frame_time_entries">
<item msgid="634406443901014984">"OFF"</item>
- <item msgid="1288760936356000927">"バーとして画面に表示"</item>
+ <item msgid="1288760936356000927">"棒グラフとして画面に表示"</item>
<item msgid="5023908510820531131">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g> 内"</item>
</string-array>
<string-array name="debug_hw_overdraw_entries">
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 03065e896da2..98c4f1032636 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -85,7 +85,7 @@
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ការហៅ​ទូរសព្ទ"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ផ្ទេរ​ឯកសារ"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"ឧបករណ៍​បញ្ចូល"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ចូល​អ៊ីនធឺណិត"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ការចូលប្រើ​អ៊ីនធឺណិត"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ការ​ចែករំលែក​​ទំនាក់ទំនង"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ប្រើ​សម្រាប់​ការ​ចែករំលែក​ទំនាក់ទំនង"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ចែករំលែក​ការ​តភ្ជាប់​អ៊ីនធឺណិត"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 71c5e491d927..ddaf97087519 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -307,7 +307,7 @@
<string name="adb_keys_warning_message" msgid="2968555274488101220">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್‌ಗಳಿಂದ USB ಡೀಬಗ್‌ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"ಅಭಿವೃದ್ಧಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"ಈ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಅಭಿವೃದ್ಧಿಯ ಬಳಕೆಗೆ ಮಾತ್ರ. ಅವುಗಳು ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌‌ಗಳಿಗೆ ಧಕ್ಕೆ ಮಾಡಬಹುದು ಅಥವಾ ಅವು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರುವಂತೆ ಮಾಡಬಹುದು."</string>
- <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ಮೂಲಕ ಆಪ್‌ ಪರಿಶೀಲಿಸಿ"</string>
+ <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ಮೂಲಕ ಆ್ಯಪ್‌ ಪರಿಶೀಲಿಸಿ"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ಹಾನಿಮಾಡುವಂತಹ ವರ್ತನೆಗಾಗಿ ADB/ADT ಮೂಲಕ ಸ್ಥಾಪಿಸಲಾದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ಹೆಸರುಗಳಿಲ್ಲದ (ಕೇವಲ MAC ವಿಳಾಸಗಳು ಮಾತ್ರ) ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲಾಗುತ್ತದೆ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ರಿಮೋಟ್ ಸಾಧನಗಳಲ್ಲಿ ಕಂಡುಬರುವ ಸ್ವೀಕಾರಾರ್ಹವಲ್ಲದ ಜೋರಾದ ವಾಲ್ಯೂಮ್ ಅಥವಾ ನಿಯಂತ್ರಣದ ಕೊರತೆಯಂತಹ ವಾಲ್ಯೂಮ್ ಸಮಸ್ಯೆಗಳಂತಹ ಸಂದರ್ಭದಲ್ಲಿ ಬ್ಲೂಟೂತ್‍ನ ನಿಚ್ಚಳ ವಾಲ್ಯೂಮ್ ವೈಶಿಷ್ಟ್ಯವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 5d82eae2fcba..6d24511291d5 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -539,7 +539,7 @@
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"지금 설정"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"나중에"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"추가"</string>
- <string name="user_new_user_name" msgid="60979820612818840">"새 사용자"</string>
+ <string name="user_new_user_name" msgid="60979820612818840">"신규 사용자"</string>
<string name="user_new_profile_name" msgid="2405500423304678841">"새 프로필"</string>
<string name="user_info_settings_title" msgid="6351390762733279907">"사용자 정보"</string>
<string name="profile_info_settings_title" msgid="105699672534365099">"프로필 정보"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 2702392c108f..4cb93fac0868 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Файл өткөрүү үчүн колдонулсун"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Киргизүү үчүн колдонулсун"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Угуу аппараттары үчүн колдонуу"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Жупташтыруу"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Байланыштыруу"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ЖУПТАШТЫРУУ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Жок"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз."</string>
@@ -223,7 +223,7 @@
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Байланышкан жок"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> туура тармакка туташып турганын текшериңиз"</string>
<string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Түзмөктү жупташтыруу"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi жупташтыруучу коду"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi аркылуу байланыштыруу коду"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Туташкан жок"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Түзмөк бир тармакка туташып турушу керек."</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
@@ -397,8 +397,8 @@
<item msgid="1282170165150762976">"Санарип мазмун үчүн оптималдаштырылган түстөр"</item>
</string-array>
<string name="inactive_apps_title" msgid="5372523625297212320">"Көшүү режиминдеги колдонмолор"</string>
- <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Иштеген жок. Которуштуруу үчүн таптап коюңуз."</string>
- <string name="inactive_app_active_summary" msgid="8047630990208722344">"Иштеп турат. Которуштуруу үчүн таптап коюңуз."</string>
+ <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Иштеген жок. Күйгүзүү үчүн басып коюңуз."</string>
+ <string name="inactive_app_active_summary" msgid="8047630990208722344">"Иштеп турат. Өчүрүү үчүн басып коюңуз."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Көшүү режиминдеги колдонмонун абалы:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Иштеп жаткан кызматтар"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"Учурда иштеп жаткан кызматтарды көрүп, көзөмөлдөп турасыз"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 34299d801946..b3532954f2f7 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -51,9 +51,9 @@
<string name="connected_via_carrier" msgid="1968057009076191514">"Поврзано преку %1$s"</string>
<string name="available_via_carrier" msgid="465598683092718294">"Достапно преку %1$s"</string>
<string name="osu_opening_provider" msgid="4318105381295178285">"Се отвора <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
- <string name="osu_connect_failed" msgid="9107873364807159193">"Не можеше да се поврзе"</string>
+ <string name="osu_connect_failed" msgid="9107873364807159193">"Не може да се поврзе"</string>
<string name="osu_completing_sign_up" msgid="8412636665040390901">"Се завршува регистрацијата…"</string>
- <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не можеше да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
+ <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не може да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
<string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрацијата е завршена. Се поврзува…"</string>
<string name="speed_label_very_slow" msgid="8526005255731597666">"Многу бавна"</string>
<string name="speed_label_slow" msgid="6069917670665664161">"Бавна"</string>
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активен"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аудио на медиуми"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук на аудио/видео"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонски повици"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос на датотека"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Влезен уред"</string>
@@ -116,8 +116,8 @@
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"СПАРИ"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Кога е поврзано, спарувањето одобрува пристап до контактите и историјата на повиците."</string>
- <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не можеше да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не можеше да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен PIN или лозинка."</string>
+ <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не може да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен PIN или лозинка."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не може да комуницира со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Спарувањето е одбиено од <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компјутер"</string>
@@ -204,10 +204,10 @@
<string name="tethering_settings_not_available" msgid="266821736434699780">"Поставките за спојување не се достапни за овој корисник"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"Поставките за името на пристапната точка не се достапни за овој корисник"</string>
<string name="enable_adb" msgid="8072776357237289039">"Отстранување грешки на USB"</string>
- <string name="enable_adb_summary" msgid="3711526030096574316">"Режим на отстранување грешки кога е поврзано USB"</string>
+ <string name="enable_adb_summary" msgid="3711526030096574316">"Режим за отстранување грешки кога е поврзано USB"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"Отповикај овластувања за отстранување грешки од USB"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Безжично отстранување грешки"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим на отстранување грешки кога е поврзано Wi‑Fi"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим за отстранување грешки кога е поврзано Wi‑Fi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Грешка"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Безжично отстранување грешки"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"За да ги гледате и користите достапните уреди, вклучете го безжичното отстранување грешки"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index c5e87bcf3945..aebbe9808607 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -171,11 +171,11 @@
</string-array>
<string-array name="select_logd_size_summaries">
<item msgid="409235464399258501">"Идэвхгүй"</item>
- <item msgid="4195153527464162486">"лог буфер бүрт 64K"</item>
- <item msgid="7464037639415220106">"лог буфер бүрт 256K"</item>
- <item msgid="8539423820514360724">"лог буфер бүрт 1M"</item>
- <item msgid="1984761927103140651">"лог буфер бүрт 4M"</item>
- <item msgid="7892098981256010498">"лог буфер бүрт 16M"</item>
+ <item msgid="4195153527464162486">"лог буфер бүрд 64K"</item>
+ <item msgid="7464037639415220106">"лог буфер бүрд 256K"</item>
+ <item msgid="8539423820514360724">"лог буфер бүрд 1M"</item>
+ <item msgid="1984761927103140651">"лог буфер бүрд 4M"</item>
+ <item msgid="7892098981256010498">"лог буфер бүрд 16M"</item>
</string-array>
<string-array name="select_logpersist_titles">
<item msgid="704720725704372366">"Идэвхгүй"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 8407db6d3a08..ed7fdc7c7877 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -70,7 +70,7 @@
<string name="bluetooth_pairing" msgid="4269046942588193600">"Хослуулж байна…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Холбогдсон (утас байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Холбогдсон (медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (зурвасын хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (мессежийн хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Холбогдсон (утас эсвэл медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
@@ -288,7 +288,7 @@
<string name="wifi_metered_label" msgid="8737187690304098638">"Хязгаартай"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Хязгааргүй"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Логгерын буферын хэмжээ"</string>
- <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Лог буфер бүрт ногдох логгерын хэмжээг сонгоно уу"</string>
+ <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Лог буфер бүрд ногдох логгерын хэмжээг сонгоно уу"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Нэвтрэгчийн тогтмол санг устгах уу?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Бид байнгын логоор хянаагүй үед таны төхөөрөмжтэй холбоотой нэвтрэгч өгөгдлийг устгах шаардлагатай."</string>
<string name="select_logpersist_title" msgid="447071974007104196">"Төхөөрөмжид тогтмол нэвтрэгчийн өгөгдлийн сан"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index c50f365f68e3..38e1ea38bcee 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -25,7 +25,7 @@
<string name="wifi_remembered" msgid="3266709779723179188">"सेव्ह केले"</string>
<string name="wifi_disconnected" msgid="7054450256284661757">"डिस्कनेक्ट केले"</string>
<string name="wifi_disabled_generic" msgid="2651916945380294607">"अक्षम"</string>
- <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP कॉन्फिगरेशन अयशस्वी"</string>
+ <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP कॉंफिगरेशन अयशस्वी"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"कमी दर्जाच्या नेटवर्कमुळे कनेक्ट केलेले नाही"</string>
<string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi कनेक्शन अयशस्वी"</string>
<string name="wifi_disabled_password_failure" msgid="6892387079613226738">"प्रमाणीकरण समस्या"</string>
@@ -97,7 +97,7 @@
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"श्रवण यंत्रांशी कनेक्ट केले आहे"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मीडिया ऑडिओवर कनेक्ट केले"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"फोन ऑडिओ वर कनेक्ट केले"</string>
- <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"फाईल स्थानांतर सर्व्हरवर कनेक्ट केले"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"फाइल स्थानांतर सर्व्हरवर कनेक्ट केले"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"नकाशाशी कनेक्ट केले"</string>
<string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"SAP शी कनेक्‍ट केले"</string>
<string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"फाइल स्थानांतर सर्व्हरशी कनेक्ट केले नाही"</string>
@@ -109,7 +109,7 @@
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"SIM प्रवेशासाठी वापरा"</string>
<string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"मीडिया ऑडिओसाठी वापरा"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"फोन ऑडिओसाठी वापरा"</string>
- <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"फाईल स्थानांतरणासाठी वापरा"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"फाइल स्थानांतरणासाठी वापरा"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"इनपुट साठी वापरा"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"श्रवण यंत्रांसाठी वापरा"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"पेअर करा"</string>
@@ -269,8 +269,8 @@
<string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"फोन किंवा हेडसेटला सपोर्ट करत नाही म्हणजे ती निकामी झाली आहे"</string>
<string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"प्रति पॅटर्न ब्लूटूध ऑडिओ बिट"</string>
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"ब्लूटूथ ऑडिओ Codec ट्रिगर करा\nनिवड: बिट प्रति नमुना"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"ब्लूटूथ ऑडिओ चॅनेल मोड"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ब्लूटूथ ऑडिओ Codec ट्रिगर करा\nनिवड: चॅनेल मोड"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"ब्लूटूथ ऑडिओ चॅनल मोड"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ब्लूटूथ ऑडिओ Codec ट्रिगर करा\nनिवड: चॅनल मोड"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ब्लूटूथ ऑडिओ LDAC कोडेक: प्लेबॅक गुणवत्ता"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ब्लूटूथ ऑडिओ LDAC\nकोडेक निवड ट्रिगर करा: प्लेबॅक गुणवत्ता"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"स्ट्रीमिंग: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
@@ -371,7 +371,7 @@
<string name="app_process_limit_title" msgid="8361367869453043007">"पार्श्वभूमी प्रक्रिया मर्यादा"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"बॅकग्राउंड ANR दाखवा"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"बॅकग्राउंड अ‍ॅप्ससाठी अ‍ॅप प्रतिसाद देत नाही दाखवते"</string>
- <string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना चॅनेल चेतावण्या दाखवा"</string>
+ <string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना चॅनल चेतावण्या दाखवा"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"एखादे अ‍ॅप वैध चॅनेलशिवाय सूचना पोस्ट करते तेव्हा स्क्रीनवर चेतावणी देते"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"बाह्यवर ॲप्सना अनुमती देण्याची सक्ती करा"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"manifest मूल्यांकडे दुर्लक्ष करून, कोणत्याही ॲपला बाह्य स्टोरेजवर लेखन केले जाण्यासाठी पात्र बनविते"</string>
@@ -405,11 +405,11 @@
<string name="select_webview_provider_title" msgid="3917815648099445503">"वेबदृश्य अंमलबजावणी"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"वेबदृश्य अंमलबजावणी सेट करा"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ही निवड यापुढे वैध असणार नाही. पुन्हा प्रयत्न करा."</string>
- <string name="convert_to_file_encryption" msgid="2828976934129751818">"फाईल कूटबद्धीकरणावर रूपांतरित करा"</string>
+ <string name="convert_to_file_encryption" msgid="2828976934129751818">"फाइल कूटबद्धीकरणावर रूपांतरित करा"</string>
<string name="convert_to_file_encryption_enabled" msgid="840757431284311754">"रूपांतरित करा..."</string>
- <string name="convert_to_file_encryption_done" msgid="8965831011811180627">"फाईल आधीपासून एंक्रिप्ट होती"</string>
- <string name="title_convert_fbe" msgid="5780013350366495149">"फाईल आधारित कूटबद्धीकरणावर रूपांतरित करणे"</string>
- <string name="convert_to_fbe_warning" msgid="34294381569282109">"फाईल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्‍या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्‍फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरू ठेवण्‍यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string>
+ <string name="convert_to_file_encryption_done" msgid="8965831011811180627">"फाइल आधीपासून एंक्रिप्ट होती"</string>
+ <string name="title_convert_fbe" msgid="5780013350366495149">"फाइल आधारित कूटबद्धीकरणावर रूपांतरित करणे"</string>
+ <string name="convert_to_fbe_warning" msgid="34294381569282109">"फाइल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्‍या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्‍फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरू ठेवण्‍यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string>
<string name="button_convert_fbe" msgid="1159861795137727671">"पुसा आणि रुपांतरित करा..."</string>
<string name="picture_color_mode" msgid="1013807330552931903">"चित्र रंग मोड"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB वापरा"</string>
@@ -526,7 +526,7 @@
<string name="accessor_expires_text" msgid="4625619273236786252">"भाडेपट्टी <xliff:g id="DATE">%s</xliff:g> रोजी एक्स्पायर होईल"</string>
<string name="delete_blob_text" msgid="2819192607255625697">"शेअर केलेला डेटा हटवा"</string>
<string name="delete_blob_confirmation_text" msgid="7807446938920827280">"तुम्हाला नक्की हा शेअर केलेला डेटा हटवायचा आहे का?"</string>
- <string name="user_add_user_item_summary" msgid="5748424612724703400">"वापरकर्त्यांकडे त्यांचे स्वत:चे अ‍ॅप्स आणि सामग्री आहे"</string>
+ <string name="user_add_user_item_summary" msgid="5748424612724703400">"वापरकर्त्यांकडे त्यांचे स्वत:चे अ‍ॅप्स आणि आशय आहे"</string>
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"तुम्ही आपल्या खात्यावरुन अ‍ॅप्स आणि सामग्रीमध्ये प्रवेश करण्यास प्रतिबंध करु शकता"</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"वापरकर्ता"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबंधित प्रोफाईल"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 4a2c1719aeb7..136c6fd7d900 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -89,7 +89,7 @@
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"सम्पर्क साझेदारी"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"सम्पर्क साझेदारीका लागि प्रयोग"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इन्टरनेट जडान साझेदारी गर्दै"</string>
- <string name="bluetooth_profile_map" msgid="8907204701162107271">"पाठ सन्देशहरू"</string>
+ <string name="bluetooth_profile_map" msgid="8907204701162107271">"टेक्स्ट म्यासेजहरू"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM पहुँच"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD अडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD अडियो"</string>
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"फाइल ट्रान्सफरका लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"इनपुटको लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"श्रवण यन्त्रहरूका लागि प्रयोग गर्नुहोस्"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"जोडी"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"जोडा बनाउनुहोस्"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"जोडी"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"रद्द गर्नुहोस्"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"जब जडान हुन्छ जोडी अनुदानले तपाईँको सम्पर्कहरू पहुँच गर्छ र इतिहास सम्झाउँछ।"</string>
@@ -143,9 +143,9 @@
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"हटाइएका एपहरू"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"एपहरू र प्रयोगकर्ताहरू हटाइयो।"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"प्रणालीसम्बन्धी अद्यावधिकहरू"</string>
- <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB टेथर गर्दै"</string>
+ <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB टेदर गर्दै"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"पोर्टेबल हटस्पट"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"ब्लुटुथ टेथर गर्दै"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"ब्लुटुथ टेदर गर्दै"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"टेदर गर्दै"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"टेदर गर्ने र पोर्टेबल हटस्पट"</string>
<string name="managed_user_title" msgid="449081789742645723">"कार्य प्रोफाइलका सबै एपहरू"</string>
@@ -306,7 +306,7 @@
<string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डिबगिङ डिभलपमेन्ट प्रयोजनका लागि मात्रै हो। यसलाई आफ्ना कम्प्युटर र उपकरणका बिच डेटा प्रतिलिपि गर्न, सूचना नदिई आफ्नो उपकरणमा एपहरू स्थापना गर्न र लग डेटा पढ्न प्रयोग गर्नुहोस्।"</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"तपाईं पहिले नै अधिकृत गर्नुभएका सबै कम्प्यूटरबाट USB डिबग गर्नको लागि पहुँच रद्द गर्ने हो?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"विकास सेटिङहरू अनुमति दिने हो?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"यी सेटिङहरू केवल विकास प्रयोगको लागि विचार गरिएको हो। तिनीहरूले तपाईंको उपकरण र अनुप्रयोगहरूलाई विच्छेदन गर्न वा दुर्व्यवहार गर्न सक्दछ।"</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"यी सेटिङहरू केवल विकास प्रयोगको लागि विचार गरिएको हो। तिनीहरूले तपाईंको उपकरण र एपहरूलाई विच्छेदन गर्न वा दुर्व्यवहार गर्न सक्दछ।"</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB मा एपहरू रुजु गर्नुहोस्"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"हानिकारक व्यवहारको लागि ADB/ADT को माध्यमबाट स्थापित अनुप्रयोगहरूको जाँच गर्नुहोस्।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू (MAC ठेगाना भएका मात्र) देखाइनेछ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 32cc39ec5b4f..044401c7b965 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -93,8 +93,8 @@
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Sim-toegang"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-audio"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Gehoorapparaten"</string>
- <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met gehoorapparaten"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hoortoestellen"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met hoortoestellen"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbonden met audio van medium"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Verbonden met audio van telefoon"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Verbonden met server voor bestandsoverdracht"</string>
@@ -111,7 +111,7 @@
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Gebruiken voor audio van telefoon"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gebruiken voor bestandsoverdracht"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gebruiken voor invoer"</string>
- <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gebruiken voor gehoorapparaten"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gebruiken voor hoortoestellen"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Koppelen"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"KOPPELEN"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuleren"</string>
@@ -127,8 +127,8 @@
<string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Hoofdtelefoon"</string>
<string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Randapparaat voor invoer"</string>
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth"</string>
- <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Linker gehoorapparaat koppelen…"</string>
- <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Rechter gehoorapparaat koppelen…"</string>
+ <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Linker hoortoestel koppelen…"</string>
+ <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Rechter hoortoestel koppelen…"</string>
<string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Links: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"Rechts: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="accessibility_wifi_off" msgid="1195445715254137155">"Wifi: uitgeschakeld."</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 1120c504717f..6d66e20b7fbd 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -148,7 +148,7 @@
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering przez Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering i punkt dostępu"</string>
- <string name="managed_user_title" msgid="449081789742645723">"Wszystkie aplikacje do pracy"</string>
+ <string name="managed_user_title" msgid="449081789742645723">"Wszystkie aplikacje służbowe"</string>
<string name="user_guest" msgid="6939192779649870792">"Gość"</string>
<string name="unknown" msgid="3544487229740637809">"Nieznana"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"Użytkownik: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 4214a2720813..10ad329eb324 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -147,7 +147,7 @@
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Ponto de acesso portátil"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e acesso portátil"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e ponto de acesso"</string>
<string name="managed_user_title" msgid="449081789742645723">"Todos os apps de trabalho"</string>
<string name="user_guest" msgid="6939192779649870792">"Convidado"</string>
<string name="unknown" msgid="3544487229740637809">"Desconhecido"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 4214a2720813..10ad329eb324 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -147,7 +147,7 @@
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Ponto de acesso portátil"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e acesso portátil"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e ponto de acesso"</string>
<string name="managed_user_title" msgid="449081789742645723">"Todos os apps de trabalho"</string>
<string name="user_guest" msgid="6939192779649870792">"Convidado"</string>
<string name="unknown" msgid="3544487229740637809">"Desconhecido"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index f39a741e3a4b..d2560d46d3c2 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Ľ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batérie, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batérie"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktívne"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medií"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk médií"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonické hovory"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos súborov"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupné zariadenie"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 74c2aec7c174..63baf1b60447 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -27,7 +27,7 @@
<string name="wifi_disabled_generic" msgid="2651916945380294607">"Онемогућено"</string>
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP конфигурација је отказала"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Није повезано због лошег квалитета мреже"</string>
- <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi веза је отказала"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi веза је отказала"</string>
<string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблем са потврдом идентитета"</string>
<string name="wifi_cant_connect" msgid="5718417542623056783">"Повезивање није успело"</string>
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string>
@@ -131,12 +131,12 @@
<string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Упаривање десног слушног апарата…"</string>
<string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Леви – ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_hearingaid_right_battery_level" msgid="1850094448499089312">"Десни – ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="accessibility_wifi_off" msgid="1195445715254137155">"Wi-Fi је искључен."</string>
- <string name="accessibility_no_wifi" msgid="5297119459491085771">"Wi-Fi веза је прекинута."</string>
- <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"Wi-Fi сигнал има једну црту."</string>
- <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi сигнал има две црте."</string>
- <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi сигнал има три црте."</string>
- <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi сигнал је најјачи."</string>
+ <string name="accessibility_wifi_off" msgid="1195445715254137155">"WiFi је искључен."</string>
+ <string name="accessibility_no_wifi" msgid="5297119459491085771">"WiFi веза је прекинута."</string>
+ <string name="accessibility_wifi_one_bar" msgid="6025652717281815212">"WiFi сигнал има једну црту."</string>
+ <string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi сигнал има две црте."</string>
+ <string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi сигнал има три црте."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi сигнал је најјачи."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Отворена мрежа"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Безбедна мрежа"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android ОС"</string>
@@ -232,7 +232,7 @@
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP адреса и порт"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Скенирај QR кôд"</string>
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Упарите уређај помоћу Wi‑Fi мреже тако што ћете скенирати QR кôд"</string>
- <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Повежите се на Wi-Fi мрежу"</string>
+ <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Повежите се на WiFi мрежу"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отклањање грешака, програмер"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Пречица за извештај о грешкама"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Прикажи дугме у менију напајања за прављење извештаја о грешкама"</string>
@@ -250,7 +250,7 @@
<string name="debug_networking_category" msgid="6829757985772659599">"Умрежавање"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Сертификација бежичног екрана"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"Успоравање Wi-Fi скенирања"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Успоравање WiFi скенирања"</string>
<string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Насумично MAC разврставање по Wi‑Fi‑ју"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилни подаци су увек активни"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Хардверско убрзање привезивања"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index fe1b0a856802..053579e9b4d9 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Använd för filöverföring"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Använd för inmatning"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Använd med hörapparater"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parkoppling"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Parkoppla"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PARKOPPLA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Om du kopplar enheten får du tillgång till dina kontakter och din samtalshistorik när du är ansluten."</string>
@@ -452,7 +452,7 @@
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laddas snabbt"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Laddas långsamt"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Laddar inte"</string>
- <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Inkopplad, kan inte laddas just nu"</string>
+ <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Ansluten, kan inte laddas just nu"</string>
<string name="battery_info_status_full" msgid="4443168946046847468">"Fullt"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Strys av administratören"</string>
<string name="disabled" msgid="8017887509554714950">"Inaktiverad"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 5c80627003cd..306c1fba031c 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -81,11 +81,11 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ya betri, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ya betri"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Kimeunganishwa"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media ya sauti"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Sauti ya maudhui"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Simu"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Uhamishaji wa faili"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kifaa cha kuingiza"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ufikiaji wa mtandao"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ufikiaji wa intaneti"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kushiriki anwani"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Tumia kwa kushiriki anwani"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Kushiriki muunganisho wa tovuti"</string>
@@ -107,7 +107,7 @@
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Tumia kuunganisha kwenye intaneti"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Tumia kwa ramani"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Tumia kwa ufikiaji wa SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Tumia kwa sauti ya media"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Tumia kwa sauti ya maudhui"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Tumia kwa sauti ya simu"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Tumia kwa hali faili"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Tumia kwa kuingiza"</string>
@@ -143,11 +143,11 @@
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Programu zilizoondolewa"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Watumiaji na programu ziilizoondolewa"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"Masasisho ya mfumo"</string>
- <string name="tether_settings_title_usb" msgid="3728686573430917722">"Shiriki intaneti kwa USB"</string>
+ <string name="tether_settings_title_usb" msgid="3728686573430917722">"Sambaza mtandao kwa USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Intaneti ya kusambazwa"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Shiriki intaneti kwa Bluetooth"</string>
- <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Inazuia"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Kushiriki na kusambaza intaneti"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Sambaza mtandao kwa Bluetooth"</string>
+ <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Kusambaza mtandao"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Kushiriki na kusambaza mtandao"</string>
<string name="managed_user_title" msgid="449081789742645723">"Programu zote za kazini"</string>
<string name="user_guest" msgid="6939192779649870792">"Mgeni"</string>
<string name="unknown" msgid="3544487229740637809">"Haijulikani"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 23256eeb7d03..a93defaea361 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -86,7 +86,7 @@
<item msgid="8147982633566548515">"map14"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_titles">
- <item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="4055460186095649420">"SBC"</item>
<item msgid="720249083677397051">"AAC"</item>
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
@@ -94,7 +94,7 @@
<item msgid="3825367753087348007">"LDAC"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
- <item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="9024885861221697796">"SBC"</item>
<item msgid="4688890470703790013">"AAC"</item>
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
@@ -102,38 +102,38 @@
<item msgid="2553206901068987657">"LDAC"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
- <item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="8003118270854840095">"44.1 kHz"</item>
<item msgid="3208896645474529394">"48.0 kHz"</item>
<item msgid="8420261949134022577">"88.2 kHz"</item>
<item msgid="8887519571067543785">"96.0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
- <item msgid="2284090879080331090">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="2284090879080331090">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="1872276250541651186">"44.1 kHz"</item>
<item msgid="8736780630001704004">"48.0 kHz"</item>
<item msgid="7698585706868856888">"88.2 kHz"</item>
<item msgid="8946330945963372966">"96.0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
- <item msgid="2574107108483219051">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="2574107108483219051">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="4671992321419011165">"16 బిట్‌లు/నమూనా"</item>
<item msgid="1933898806184763940">"24 బిట్‌లు/నమూనా"</item>
<item msgid="1212577207279552119">"32 బిట్‌లు/నమూనా"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
- <item msgid="9196208128729063711">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="9196208128729063711">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="1084497364516370912">"16 బిట్‌లు/నమూనా"</item>
<item msgid="2077889391457961734">"24 బిట్‌లు/నమూనా"</item>
<item msgid="3836844909491316925">"32 బిట్‌లు/నమూనా"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_titles">
- <item msgid="3014194562841654656">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="3014194562841654656">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="5982952342181788248">"మోనో"</item>
<item msgid="927546067692441494">"స్టీరియో"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
- <item msgid="1997302811102880485">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+ <item msgid="1997302811102880485">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
<item msgid="8005696114958453588">"మోనో"</item>
<item msgid="1333279807604675720">"స్టీరియో"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index a9ec2ea95ac5..4aa131d24cd4 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -156,14 +156,14 @@
<string name="launch_defaults_none" msgid="8049374306261262709">"ఆటోమేటిక్ ఆప్ష‌న్‌లు ఏవీ సెట్ చేయ‌‌లేదు"</string>
<string name="tts_settings" msgid="8130616705989351312">"వచనం నుండి ప్రసంగం సెట్టింగ్‌లు"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"టెక్స్ట్-టు-స్పీచ్ అవుట్‌పుట్"</string>
- <string name="tts_default_rate_title" msgid="3964187817364304022">"ప్రసంగం రేట్"</string>
+ <string name="tts_default_rate_title" msgid="3964187817364304022">"స్పీచ్ రేట్"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"వచనాన్ని చదివి వినిపించాల్సిన వేగం"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"పిచ్"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"సమన్వయం చేసిన ప్రసంగం యొక్క టోన్‌ను ప్రభావితం చేస్తుంది"</string>
<string name="tts_default_lang_title" msgid="4698933575028098940">"భాష"</string>
<string name="tts_lang_use_system" msgid="6312945299804012406">"సిస్టమ్ భాషను ఉపయోగించు"</string>
<string name="tts_lang_not_selected" msgid="7927823081096056147">"భాష ఎంచుకోబడలేదు"</string>
- <string name="tts_default_lang_summary" msgid="9042620014800063470">"చదవి వినిపించబడే వచనం కోసం భాష-నిర్దిష్ట వాయిస్‌ను సెట్ చేస్తుంది"</string>
+ <string name="tts_default_lang_summary" msgid="9042620014800063470">"టెక్స్ట్‌ను చదివి వినిపించేటప్పుడు, ఒక్కో భాషకు వాడాల్సిన నిర్దిష్ట వాయిస్‌ను సెట్ చేస్తుంది"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"ఒక ఉదాహరణ వినండి"</string>
<string name="tts_play_example_summary" msgid="634044730710636383">"ప్రసంగ సమన్వయం గురించి సంక్షిప్త ప్రదర్శనను ప్లే చేయి"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"వాయిస్ డేటాను ఇన్‌స్టాల్ చేయి"</string>
@@ -196,7 +196,7 @@
<string name="choose_profile" msgid="343803890897657450">"ప్రొఫైల్‌ను ఎంచుకోండి"</string>
<string name="category_personal" msgid="6236798763159385225">"వ్యక్తిగతం"</string>
<string name="category_work" msgid="4014193632325996115">"ఆఫీస్"</string>
- <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఎంపికలు"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఆప్షన్‌లు"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"డెవలపర్ ఎంపికలను ప్రారంభించండి"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"అనువర్తన అభివృద్ధి కోసం ఎంపికలను సెట్ చేయండి"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"ఈ వినియోగదారు కోసం డెవలపర్ ఎంపికలు అందుబాటులో లేవు"</string>
@@ -281,7 +281,7 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"ప్రైవేట్ DNS ప్రదాత హోస్ట్‌పేరు"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ప్రదాత యొక్క హోస్ట్‌పేరును నమోదు చేయండి"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్‌లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్‌లెస్ డిస్‌ప్లే సర్టిఫికేషన్ ఆప్షన్‌లను చూపు"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి &amp; నెట్‌వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string>
<string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"ఈ మోడ్ ఎనేబుల్ అయ్యాక, MAC ర్యాండమైజేషన్‌ను ఎనేబుల్ చేసిన నెట్‌వర్క్‌తో కనెక్ట్ అయ్యే ప్రతిసారీ ఈ పరికరం MAC అడ్రస్ మారవచ్చు."</string>
@@ -367,7 +367,7 @@
<string name="overlay_display_devices_title" msgid="5411894622334469607">"ప్రత్యామ్నాయ ప్రదర్శనలను అనుకరించండి"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"యాప్‌లు"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"కార్యకలాపాలను ఉంచవద్దు"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ప్రతి కార్యకలాపాన్ని వినియోగదారు నిష్క్రమించిన వెంటనే తొలగించండి"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీ తొలగింపు"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"బ్యాక్‌గ్రౌండ్ ప్రాసెస్ పరిమితి"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"బ్యాక్‌గ్రౌండ్ ANRలను చూపు"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"నేపథ్య యాప్‌ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్‌ను చూపు"</string>
@@ -473,7 +473,7 @@
<string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"చాలా పెద్దగా"</string>
<string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"అతి పెద్దగా"</string>
<string name="screen_zoom_summary_custom" msgid="3468154096832912210">"అనుకూలం (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
- <string name="content_description_menu_button" msgid="6254844309171779931">"మెను"</string>
+ <string name="content_description_menu_button" msgid="6254844309171779931">"మెనూ"</string>
<string name="retail_demo_reset_message" msgid="5392824901108195463">"డెమో మోడ్‌లో ఫ్యాక్టరీ రీసెట్‌ను నిర్వహించడానికి పాస్‌వర్డ్‌ను నమోదు చేయండి"</string>
<string name="retail_demo_reset_next" msgid="3688129033843885362">"తర్వాత"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"పాస్‌వర్డ్ అవసరం"</string>
@@ -511,7 +511,7 @@
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"ఫోన్ స్పీకర్"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"కనెక్ట్ చేయడంలో సమస్య ఉంది. పరికరాన్ని ఆఫ్ చేసి, ఆపై తిరిగి ఆన్ చేయండి"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"వైర్ గల ఆడియో పరికరం"</string>
- <string name="help_label" msgid="3528360748637781274">"సహాయం &amp; అభిప్రాయం"</string>
+ <string name="help_label" msgid="3528360748637781274">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
<string name="storage_category" msgid="2287342585424631813">"నిల్వ"</string>
<string name="shared_data_title" msgid="1017034836800864953">"షేర్ చేసిన డేటా"</string>
<string name="shared_data_summary" msgid="5516326713822885652">"షేర్ చేసిన డేటాను చూసి, సవరించండి"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 8aac165da6d3..6ade4deecb2d 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -138,15 +138,15 @@
<item msgid="1333279807604675720">"สเตอริโอ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="1241278021345116816">"เพิ่มประสิทธิภาพสำหรับคุณภาพเสียง (990 kbps/909 kbps)"</item>
+ <item msgid="1241278021345116816">"เพิ่มประสิทธิภาพเพื่อคุณภาพเสียง (990 kbps/909 kbps)"</item>
<item msgid="3523665555859696539">"คุณภาพเสียงและการเชื่อมต่อที่สมดุล (660 kbps/606 kbps)"</item>
- <item msgid="886408010459747589">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ (330 kbps/303 kbps)"</item>
+ <item msgid="886408010459747589">"เพิ่มประสิทธิภาพเพื่อคุณภาพการเชื่อมต่อ (330 kbps/303 kbps)"</item>
<item msgid="3808414041654351577">"ดีที่สุดเท่าที่ทำได้ (ปรับอัตราบิตอัตโนมัติ)"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="804499336721569838">"เพิ่มประสิทธิภาพสำหรับคุณภาพเสียง"</item>
+ <item msgid="804499336721569838">"เพิ่มประสิทธิภาพเพื่อคุณภาพเสียง"</item>
<item msgid="7451422070435297462">"คุณภาพเสียงและการเชื่อมต่อที่สมดุล"</item>
- <item msgid="6173114545795428901">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ"</item>
+ <item msgid="6173114545795428901">"เพิ่มประสิทธิภาพเพื่อคุณภาพการเชื่อมต่อ"</item>
<item msgid="4349908264188040530">"ดีที่สุดเท่าที่ทำได้ (ปรับอัตราบิตอัตโนมัติ)"</item>
</string-array>
<string-array name="bluetooth_audio_active_device_summaries">
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b8343c6a82e7..8510a919445b 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -143,7 +143,7 @@
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"แอปพลิเคชันที่นำออก"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"แอปพลิเคชันและผู้ใช้ที่นำออก"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"การอัปเดตระบบ"</string>
- <string name="tether_settings_title_usb" msgid="3728686573430917722">"ปล่อยสัญญาณผ่าน USB"</string>
+ <string name="tether_settings_title_usb" msgid="3728686573430917722">"เชื่อมต่อเน็ตผ่าน USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"ฮอตสปอตแบบพกพาได้"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"ปล่อยสัญญาณบลูทูธ"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"การปล่อยสัญญาณ"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index cf1fafd8f190..7318596b5a01 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -195,7 +195,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Вибрати профіль"</string>
<string name="category_personal" msgid="6236798763159385225">"Особисте"</string>
- <string name="category_work" msgid="4014193632325996115">"Робота"</string>
+ <string name="category_work" msgid="4014193632325996115">"Робоче"</string>
<string name="development_settings_title" msgid="140296922921597393">"Параметри розробника"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Увімкнути параметри розробника"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Установити параметри для розробки програми"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index b7fbe6fad392..07f4a5c267c0 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -197,9 +197,9 @@
<string name="category_personal" msgid="6236798763159385225">"ذاتی"</string>
<string name="category_work" msgid="4014193632325996115">"دفتر"</string>
<string name="development_settings_title" msgid="140296922921597393">"ڈویلپر کے اختیارات"</string>
- <string name="development_settings_enable" msgid="4285094651288242183">"ڈیولپر کے اختیارات فعال کریں"</string>
+ <string name="development_settings_enable" msgid="4285094651288242183">"ڈویلپر کے اختیارات فعال کریں"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ایپ ڈویلپمنٹ کیلئے اختیارات سیٹ کریں"</string>
- <string name="development_settings_not_available" msgid="355070198089140951">"اس صارف کیلئے ڈیولپر کے اختیارات دستیاب نہیں ہیں"</string>
+ <string name="development_settings_not_available" msgid="355070198089140951">"اس صارف کیلئے ڈویلپر کے اختیارات دستیاب نہیں ہیں"</string>
<string name="vpn_settings_not_available" msgid="2894137119965668920">"‏VPN ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
<string name="tethering_settings_not_available" msgid="266821736434699780">"ٹیدرنگ ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"رسائی کی جگہ کے نام کی ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index f81731ab2723..48940a214c2e 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -22,7 +22,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="2333336097603822490">"Tarmoqlarni tekshirib chiqishni iloji bo‘lmadi"</string>
<string name="wifi_security_none" msgid="7392696451280611452">"Hech qanday"</string>
- <string name="wifi_remembered" msgid="3266709779723179188">"Saqlandi"</string>
+ <string name="wifi_remembered" msgid="3266709779723179188">"Saqlangan"</string>
<string name="wifi_disconnected" msgid="7054450256284661757">"Ulanmagan"</string>
<string name="wifi_disabled_generic" msgid="2651916945380294607">"Yoqilmagan"</string>
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP manzilini sozlab bo‘lmadi"</string>
@@ -81,11 +81,11 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Faol"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"A2DP profili"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefon chaqiruvlari"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl uzatish"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Kiritish qurilmasi"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetga kirish"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetga ulanish"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Kontaktlarni ulashish"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Kontaktlarni ulashish uchun ishlatilsin"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet aloqasi ulashmasi"</string>
@@ -112,7 +112,7 @@
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Fayl almashinish uchun foydalanish"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Kiritish qurilmasi sifatida foydalanish"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Eshitish apparatlari uchun foydalanish"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Biriktirish"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"OK"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ULANISH"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Bekor qilish"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Agar ulanishga ruxsat bersangiz, ulangan vaqtda kontakt va qo‘ng‘iroqlaringiz tarixiga kirishi mumkin."</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index b7ccf8d85677..b6ac92f1cfd2 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -81,7 +81,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Trái: Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Phải: Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Đang hoạt động"</string>
- <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Âm thanh của phương tiện"</string>
+ <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Cuộc gọi điện thoại"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Chuyển tệp"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Thiết bị đầu vào"</string>
@@ -95,7 +95,7 @@
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Âm thanh HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Thiết bị trợ thính"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Đã kết nối với Thiết bị trợ thính"</string>
- <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh phương tiện"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Đã kết nối với âm thanh điện thoại"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Đã kết nối với máy chủ chuyển tệp"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Đã kết nối với bản đồ"</string>
@@ -107,7 +107,7 @@
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Sử dụng để truy cập Internet"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Sử dụng cho bản đồ"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Sử dụng để truy cập SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Sử dụng cho âm thanh phương tiện"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Sử dụng cho âm thanh nội dung nghe nhìn"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Sử dụng cho âm thanh điện thoại"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Sử dụng để chuyển tệp"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Sử dụng để nhập"</string>
@@ -306,7 +306,7 @@
<string name="adbwifi_warning_message" msgid="8005936574322702388">"Tính năng gỡ lỗi qua Wi-Fi chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị mà không thông báo và đọc dữ liệu nhật ký."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Cho phép cài đặt phát triển?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"Những cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động sai."</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"Những tùy chọn cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động không đúng cách."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Xác minh ứng dụng qua USB"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kiểm tra các ứng dụng được cài đặt qua ADB/ADT để xem có hoạt động gây hại hay không."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Các thiết bị Bluetooth không có tên (chỉ có địa chỉ MAC) sẽ được hiển thị"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 6b8739fd017a..237b5846e9d2 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -113,7 +113,7 @@
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Isetshenziselwa okufakwayo"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Sebenzisa izinsiza zokuzwa"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Bhangqa"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANQA"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANGQA"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Khansela"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Ukubhanqa kunika ukufinyelela koxhumana nabo nomlando wekholi uma uxhumekile."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Ayikwazanga ukuhlangana ne <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index c5d4fa9f1b40..cb610fc61142 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -89,15 +89,7 @@ public class SystemSettingsValidators {
return value == null || value.length() < MAX_LENGTH;
}
});
- VALIDATORS.put(
- System.FONT_SCALE,
- value -> {
- try {
- return Float.parseFloat(value) >= 0;
- } catch (NumberFormatException | NullPointerException e) {
- return false;
- }
- });
+ VALIDATORS.put(System.FONT_SCALE, new InclusiveFloatRangeValidator(0.85f, 1.3f));
VALIDATORS.put(System.DIM_SCREEN, BOOLEAN_VALIDATOR);
VALIDATORS.put(
System.DISPLAY_COLOR_MODE,
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 77cd5d2ffdab..526c1ca8e4a6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -135,8 +135,6 @@ import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.netlink.InetDiagMessage;
import android.net.shared.PrivateDnsConfig;
-import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult;
-import android.net.util.LinkPropertiesUtils.CompareResult;
import android.net.util.MultinetworkPolicyTracker;
import android.net.util.NetdService;
import android.os.Binder;
@@ -194,6 +192,8 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.LocationPermissionChecker;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.XmlUtils;
+import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
+import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.AutodestructReference;
import com.android.server.connectivity.DataConnectionStats;
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 4a1820a8e538..d90750548114 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -25,7 +25,6 @@ import android.net.Uri;
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
-import android.net.util.nsd.DnsSdTxtRecord;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -42,6 +41,7 @@ import com.android.internal.util.AsyncChannel;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.net.module.util.DnsSdTxtRecord;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e75d54f8ac9f..67c64e94db9b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7158,67 +7158,68 @@ public class ActivityManagerService extends IActivityManager.Stub
"getContentProviderImpl: after checkContentProviderPermission");
final long origId = Binder.clearCallingIdentity();
+ try {
+ checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
+
+ // Return the provider instance right away since it already exists.
+ conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage,
+ callingTag, stable);
+ if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
+ if (cpr.proc != null
+ && r != null && r.setAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
+ // If this is a perceptible app accessing the provider,
+ // make sure to count it as being accessed and thus
+ // back up on the LRU list. This is good because
+ // content providers are often expensive to start.
+ checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
+ mProcessList.updateLruProcessLocked(cpr.proc, false, null);
+ checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
+ }
+ }
- checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
-
- // In this case the provider instance already exists, so we can
- // return it right away.
- conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag,
- stable);
- if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
- if (cpr.proc != null
- && r != null && r.setAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
- // If this is a perceptible app accessing the provider,
- // make sure to count it as being accessed and thus
- // back up on the LRU list. This is good because
- // content providers are often expensive to start.
- checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
- mProcessList.updateLruProcessLocked(cpr.proc, false, null);
- checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
- }
- }
-
- checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
- final int verifiedAdj = cpr.proc.verifiedAdj;
- boolean success = updateOomAdjLocked(cpr.proc, true,
- OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
- // XXX things have changed so updateOomAdjLocked doesn't actually tell us
- // if the process has been successfully adjusted. So to reduce races with
- // it, we will check whether the process still exists. Note that this doesn't
- // completely get rid of races with LMK killing the process, but should make
- // them much smaller.
- if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
- success = false;
- }
- maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
- checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
- if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
- // NOTE: there is still a race here where a signal could be
- // pending on the process even though we managed to update its
- // adj level. Not sure what to do about this, but at least
- // the race is now smaller.
- if (!success) {
- // Uh oh... it looks like the provider's process
- // has been killed on us. We need to wait for a new
- // process to be started, and make sure its death
- // doesn't kill our process.
- Slog.wtf(TAG, "Existing provider " + cpr.name.flattenToShortString()
- + " is crashing; detaching " + r);
- boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
- if (!lastRef) {
- // This wasn't the last ref our process had on
- // the provider... we will be killed during cleaning up, bail.
- return null;
+ checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
+ final int verifiedAdj = cpr.proc.verifiedAdj;
+ boolean success = updateOomAdjLocked(cpr.proc, true,
+ OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
+ // XXX things have changed so updateOomAdjLocked doesn't actually tell us
+ // if the process has been successfully adjusted. So to reduce races with
+ // it, we will check whether the process still exists. Note that this doesn't
+ // completely get rid of races with LMK killing the process, but should make
+ // them much smaller.
+ if (success && verifiedAdj != cpr.proc.setAdj
+ && !isProcessAliveLocked(cpr.proc)) {
+ success = false;
+ }
+ maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
+ checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
+ if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
+ // NOTE: there is still a race here where a signal could be
+ // pending on the process even though we managed to update its
+ // adj level. Not sure what to do about this, but at least
+ // the race is now smaller.
+ if (!success) {
+ // Uh oh... it looks like the provider's process
+ // has been killed on us. We need to wait for a new
+ // process to be started, and make sure its death
+ // doesn't kill our process.
+ Slog.wtf(TAG, "Existing provider " + cpr.name.flattenToShortString()
+ + " is crashing; detaching " + r);
+ boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
+ if (!lastRef) {
+ // This wasn't the last ref our process had on
+ // the provider... we will be killed during cleaning up, bail.
+ return null;
+ }
+ // We'll just start a new process to host the content provider
+ providerRunning = false;
+ conn = null;
+ dyingProc = cpr.proc;
+ } else {
+ cpr.proc.verifiedAdj = cpr.proc.setAdj;
}
- // We'll just start a new process to host the content provider
- providerRunning = false;
- conn = null;
- dyingProc = cpr.proc;
- } else {
- cpr.proc.verifiedAdj = cpr.proc.setAdj;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
-
- Binder.restoreCallingIdentity(origId);
}
if (!providerRunning) {
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 103f659cc258..7d8bed39f146 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -60,12 +60,12 @@ import android.net.ipsec.ike.IkeTrafficSelector;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.net.util.IpRange;
import android.system.OsConstants;
import android.util.Log;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.HexDump;
+import com.android.net.module.util.IpRange;
import java.net.Inet4Address;
import java.net.Inet6Address;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 330f99523507..9f0efa5fad83 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -299,6 +299,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
final ArraySet<File> unclaimedStages = newArraySet(
stagingDir.listFiles(sStageFilter));
+ // We also need to clean up orphaned staging directory for staged sessions
+ final File stagedSessionStagingDir = Environment.getDataStagingDirectory(volumeUuid);
+ unclaimedStages.addAll(newArraySet(stagedSessionStagingDir.listFiles()));
+
// Ignore stages claimed by active sessions
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 280bbfc8260f..975fe41cdeaa 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1888,8 +1888,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -1941,8 +1941,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -2010,8 +2010,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -2088,8 +2088,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -2126,8 +2126,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -2210,8 +2210,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -2247,8 +2247,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -3853,8 +3853,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -3891,8 +3891,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -4145,8 +4145,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
@@ -4184,8 +4184,8 @@ public class TelephonyManager {
*
* <p>Starting with API level 29, persistent device identifiers are guarded behind additional
* restrictions, and apps are recommended to use resettable identifiers (see <a
- * href="c"> Best practices for unique identifiers</a>). This method can be invoked if one of
- * the following requirements is met:
+ * href="/training/articles/user-data-ids">Best practices for unique identifiers</a>). This
+ * method can be invoked if one of the following requirements is met:
* <ul>
* <li>If the calling app has been granted the READ_PRIVILEGED_PHONE_STATE permission; this
* is a privileged permission that can only be granted to apps preloaded on the device.
diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
index a67156a74d18..a5e44d59fcab 100644
--- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
+++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
@@ -53,8 +53,13 @@ class MatchAllNetworkSpecifierTest {
assertParcelSane(MatchAllNetworkSpecifier(), 0)
}
- @Test @IgnoreAfter(Build.VERSION_CODES.R)
- fun testCanBeSatisfiedBy_BeforeS() {
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ @IgnoreAfter(Build.VERSION_CODES.R)
+ // Only run this test on Android R.
+ // The method - satisfiedBy() has changed to canBeSatisfiedBy() starting from Android R, so the
+ // method - canBeSatisfiedBy() cannot be found when running this test on Android Q.
+ fun testCanBeSatisfiedBy_OnlyForR() {
// MatchAllNetworkSpecifier didn't follow its parent class to change the satisfiedBy() to
// canBeSatisfiedBy(), so if a caller calls MatchAllNetworkSpecifier#canBeSatisfiedBy(), the
// NetworkSpecifier#canBeSatisfiedBy() will be called actually, and false will be returned.
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index 91c9a2a38036..6de31f6b4be1 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -22,11 +22,11 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.net.util.MacAddressUtils;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.MacAddressUtils;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tools/stats_log_api_gen/.clang-format b/tools/stats_log_api_gen/.clang-format
deleted file mode 100644
index cead3a079435..000000000000
--- a/tools/stats_log_api_gen/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
- - Regex: '^"Log\.h"'
- Priority: -1
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
deleted file mode 100644
index e3b6db08c503..000000000000
--- a/tools/stats_log_api_gen/Android.bp
+++ /dev/null
@@ -1,131 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// ==========================================================
-// Build the host executable: stats-log-api-gen
-// ==========================================================
-cc_binary_host {
- name: "stats-log-api-gen",
- srcs: [
- "Collation.cpp",
- "java_writer.cpp",
- "java_writer_q.cpp",
- "main.cpp",
- "native_writer.cpp",
- "utils.cpp",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libstats_proto_host",
- "libprotobuf-cpp-full",
- "libbase",
- ],
-
- proto: {
- type: "full",
- },
-}
-
-// ==========================================================
-// Build the host test executable: stats-log-api-gen
-// ==========================================================
-cc_test_host {
- name: "stats-log-api-gen-test",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-g",
- "-DUNIT_TEST",
- ],
- srcs: [
- "Collation.cpp",
- "test_collation.cpp",
- "test.proto",
- ],
-
- static_libs: [
- "libgmock_host",
- ],
-
- shared_libs: [
- "libstats_proto_host",
- "libprotobuf-cpp-full",
- ],
-
- proto: {
- type: "full",
- include_dirs: [
- "external/protobuf/src",
- ],
- },
-}
-
-// ==========================================================
-// Native library
-// ==========================================================
-genrule {
- name: "statslog.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog.h",
- out: [
- "statslog.h",
- ],
-}
-
-genrule {
- name: "statslog.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog.cpp",
- out: [
- "statslog.cpp",
- ],
-}
-
-cc_library {
- name: "libstatslog",
- host_supported: true,
- generated_sources: [
- "statslog.cpp",
- ],
- generated_headers: [
- "statslog.h"
- ],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- export_generated_headers: [
- "statslog.h"
- ],
- shared_libs: [
- "liblog",
- "libcutils",
- ],
- target: {
- android: {
- shared_libs: ["libstatssocket"],
- },
- host: {
- static_libs: ["libstatssocket"],
- },
- },
-}
-
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
deleted file mode 100644
index a230de46dcf3..000000000000
--- a/tools/stats_log_api_gen/Collation.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Collation.h"
-
-#include <stdio.h>
-
-#include <map>
-
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using google::protobuf::EnumDescriptor;
-using google::protobuf::FieldDescriptor;
-using google::protobuf::FileDescriptor;
-using google::protobuf::SourceLocation;
-using std::make_shared;
-using std::map;
-
-const bool dbg = false;
-
-//
-// AtomDecl class
-//
-
-AtomDecl::AtomDecl() : code(0), name() {
-}
-
-AtomDecl::AtomDecl(const AtomDecl& that)
- : code(that.code),
- name(that.name),
- message(that.message),
- fields(that.fields),
- fieldNumberToAnnotations(that.fieldNumberToAnnotations),
- primaryFields(that.primaryFields),
- exclusiveField(that.exclusiveField),
- defaultState(that.defaultState),
- triggerStateReset(that.triggerStateReset),
- nested(that.nested),
- uidField(that.uidField) {
-}
-
-AtomDecl::AtomDecl(int c, const string& n, const string& m) : code(c), name(n), message(m) {
-}
-
-AtomDecl::~AtomDecl() {
-}
-
-/**
- * Print an error message for a FieldDescriptor, including the file name and
- * line number.
- */
-static void print_error(const FieldDescriptor* field, const char* format, ...) {
- const Descriptor* message = field->containing_type();
- const FileDescriptor* file = message->file();
-
- SourceLocation loc;
- if (field->GetSourceLocation(&loc)) {
- // TODO: this will work if we can figure out how to pass
- // --include_source_info to protoc
- fprintf(stderr, "%s:%d: ", file->name().c_str(), loc.start_line);
- } else {
- fprintf(stderr, "%s: ", file->name().c_str());
- }
- va_list args;
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
-}
-
-/**
- * Convert a protobuf type into a java type.
- */
-static java_type_t java_type(const FieldDescriptor* field) {
- int protoType = field->type();
- switch (protoType) {
- case FieldDescriptor::TYPE_DOUBLE:
- return JAVA_TYPE_DOUBLE;
- case FieldDescriptor::TYPE_FLOAT:
- return JAVA_TYPE_FLOAT;
- case FieldDescriptor::TYPE_INT64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_UINT64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_INT32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_FIXED64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_FIXED32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_BOOL:
- return JAVA_TYPE_BOOLEAN;
- case FieldDescriptor::TYPE_STRING:
- return JAVA_TYPE_STRING;
- case FieldDescriptor::TYPE_GROUP:
- return JAVA_TYPE_UNKNOWN;
- case FieldDescriptor::TYPE_MESSAGE:
- // TODO: not the final package name
- if (field->message_type()->full_name() == "android.os.statsd.AttributionNode") {
- return JAVA_TYPE_ATTRIBUTION_CHAIN;
- } else if (field->message_type()->full_name() == "android.os.statsd.KeyValuePair") {
- return JAVA_TYPE_KEY_VALUE_PAIR;
- } else if (field->options().GetExtension(os::statsd::log_mode) ==
- os::statsd::LogMode::MODE_BYTES) {
- return JAVA_TYPE_BYTE_ARRAY;
- } else {
- return JAVA_TYPE_OBJECT;
- }
- case FieldDescriptor::TYPE_BYTES:
- return JAVA_TYPE_BYTE_ARRAY;
- case FieldDescriptor::TYPE_UINT32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_ENUM:
- return JAVA_TYPE_ENUM;
- case FieldDescriptor::TYPE_SFIXED32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_SFIXED64:
- return JAVA_TYPE_LONG;
- case FieldDescriptor::TYPE_SINT32:
- return JAVA_TYPE_INT;
- case FieldDescriptor::TYPE_SINT64:
- return JAVA_TYPE_LONG;
- default:
- return JAVA_TYPE_UNKNOWN;
- }
-}
-
-/**
- * Gather the enums info.
- */
-void collate_enums(const EnumDescriptor& enumDescriptor, AtomField* atomField) {
- for (int i = 0; i < enumDescriptor.value_count(); i++) {
- atomField->enumValues[enumDescriptor.value(i)->number()] =
- enumDescriptor.value(i)->name().c_str();
- }
-}
-
-static void addAnnotationToAtomDecl(AtomDecl* atomDecl, const int fieldNumber,
- const AnnotationId annotationId,
- const AnnotationType annotationType,
- const AnnotationValue annotationValue) {
- if (dbg) {
- printf(" Adding annotation to %s: [%d] = {id: %d, type: %d}\n", atomDecl->name.c_str(),
- fieldNumber, annotationId, annotationType);
- }
- atomDecl->fieldNumberToAnnotations[fieldNumber].insert(
- make_shared<Annotation>(annotationId, atomDecl->code, annotationType, annotationValue));
-}
-
-static int collate_field_annotations(AtomDecl* atomDecl, const FieldDescriptor* field,
- const int fieldNumber, const java_type_t& javaType) {
- int errorCount = 0;
-
- if (field->options().HasExtension(os::statsd::state_field_option)) {
- const os::statsd::StateAtomFieldOption& stateFieldOption =
- field->options().GetExtension(os::statsd::state_field_option);
- const bool primaryField = stateFieldOption.primary_field();
- const bool exclusiveState = stateFieldOption.exclusive_state();
- const bool primaryFieldFirstUid = stateFieldOption.primary_field_first_uid();
-
- // Check the field is only one of primaryField, exclusiveState, or primaryFieldFirstUid.
- if (primaryField + primaryFieldFirstUid + exclusiveState > 1) {
- print_error(field,
- "Field can be max 1 of primary_field, exclusive_state, "
- "or primary_field_first_uid: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
-
- if (primaryField) {
- if (javaType == JAVA_TYPE_UNKNOWN || javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
- javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
- print_error(field, "Invalid primary state field: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- } else {
- atomDecl->primaryFields.push_back(fieldNumber);
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_PRIMARY_FIELD,
- ANNOTATION_TYPE_BOOL, AnnotationValue(true));
- }
- }
-
- if (primaryFieldFirstUid) {
- if (javaType != JAVA_TYPE_ATTRIBUTION_CHAIN) {
- print_error(field,
- "PRIMARY_FIELD_FIRST_UID annotation is only for AttributionChains: "
- "'%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- } else {
- atomDecl->primaryFields.push_back(FIRST_UID_IN_CHAIN_ID);
- addAnnotationToAtomDecl(atomDecl, fieldNumber,
- ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, ANNOTATION_TYPE_BOOL,
- AnnotationValue(true));
- }
- }
-
- if (exclusiveState) {
- if (javaType == JAVA_TYPE_UNKNOWN || javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
- javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
- print_error(field, "Invalid exclusive state field: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
-
- if (atomDecl->exclusiveField != 0) {
- print_error(field,
- "Cannot have more than one exclusive state field in an "
- "atom: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- } else {
- atomDecl->exclusiveField = fieldNumber;
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_EXCLUSIVE_STATE,
- ANNOTATION_TYPE_BOOL, AnnotationValue(true));
- }
-
- if (stateFieldOption.has_default_state_value()) {
- const int defaultState = stateFieldOption.default_state_value();
- atomDecl->defaultState = defaultState;
-
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_DEFAULT_STATE,
- ANNOTATION_TYPE_INT, AnnotationValue(defaultState));
- }
-
- if (stateFieldOption.has_trigger_state_reset_value()) {
- const int triggerStateReset = stateFieldOption.trigger_state_reset_value();
-
- atomDecl->triggerStateReset = triggerStateReset;
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_TRIGGER_STATE_RESET,
- ANNOTATION_TYPE_INT, AnnotationValue(triggerStateReset));
- }
-
- if (stateFieldOption.has_nested()) {
- const bool nested = stateFieldOption.nested();
- atomDecl->nested = nested;
-
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_STATE_NESTED,
- ANNOTATION_TYPE_BOOL, AnnotationValue(nested));
- }
- }
- }
-
- if (field->options().GetExtension(os::statsd::is_uid) == true) {
- if (javaType != JAVA_TYPE_INT) {
- print_error(field, "is_uid annotation can only be applied to int32 fields: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
-
- if (atomDecl->uidField == 0) {
- atomDecl->uidField = fieldNumber;
-
- addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_IS_UID,
- ANNOTATION_TYPE_BOOL, AnnotationValue(true));
- } else {
- print_error(field,
- "Cannot have more than one field in an atom with is_uid "
- "annotation: '%s'\n",
- atomDecl->message.c_str());
- errorCount++;
- }
- }
-
- return errorCount;
-}
-
-/**
- * Gather the info about an atom proto.
- */
-int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature) {
- int errorCount = 0;
-
- // Build a sorted list of the fields. Descriptor has them in source file
- // order.
- map<int, const FieldDescriptor*> fields;
- for (int j = 0; j < atom->field_count(); j++) {
- const FieldDescriptor* field = atom->field(j);
- fields[field->number()] = field;
- }
-
- // Check that the parameters start at 1 and go up sequentially.
- int expectedNumber = 1;
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const int number = it->first;
- const FieldDescriptor* field = it->second;
- if (number != expectedNumber) {
- print_error(field,
- "Fields must be numbered consecutively starting at 1:"
- " '%s' is %d but should be %d\n",
- field->name().c_str(), number, expectedNumber);
- errorCount++;
- expectedNumber = number;
- continue;
- }
- expectedNumber++;
- }
-
- // Check that only allowed types are present. Remove any invalid ones.
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const FieldDescriptor* field = it->second;
- bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
- os::statsd::LogMode::MODE_BYTES;
-
- java_type_t javaType = java_type(field);
-
- if (javaType == JAVA_TYPE_UNKNOWN) {
- print_error(field, "Unknown type for field: %s\n", field->name().c_str());
- errorCount++;
- continue;
- } else if (javaType == JAVA_TYPE_OBJECT && atomDecl->code < PULL_ATOM_START_ID) {
- // Allow attribution chain, but only at position 1.
- print_error(field, "Message type not allowed for field in pushed atoms: %s\n",
- field->name().c_str());
- errorCount++;
- continue;
- } else if (javaType == JAVA_TYPE_BYTE_ARRAY && !isBinaryField) {
- print_error(field, "Raw bytes type not allowed for field: %s\n", field->name().c_str());
- errorCount++;
- continue;
- }
-
- if (isBinaryField && javaType != JAVA_TYPE_BYTE_ARRAY) {
- print_error(field, "Cannot mark field %s as bytes.\n", field->name().c_str());
- errorCount++;
- continue;
- }
-
- // Doubles are not supported yet.
- if (javaType == JAVA_TYPE_DOUBLE) {
- print_error(field,
- "Doubles are not supported in atoms. Please change field %s "
- "to float\n",
- field->name().c_str());
- errorCount++;
- continue;
- }
-
- if (field->is_repeated() &&
- !(javaType == JAVA_TYPE_ATTRIBUTION_CHAIN || javaType == JAVA_TYPE_KEY_VALUE_PAIR)) {
- print_error(field,
- "Repeated fields are not supported in atoms. Please make "
- "field %s not "
- "repeated.\n",
- field->name().c_str());
- errorCount++;
- continue;
- }
- }
-
- // Check that if there's an attribution chain, it's at position 1.
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- int number = it->first;
- if (number != 1) {
- const FieldDescriptor* field = it->second;
- java_type_t javaType = java_type(field);
- if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- print_error(field,
- "AttributionChain fields must have field id 1, in message: '%s'\n",
- atom->name().c_str());
- errorCount++;
- }
- }
- }
-
- // Build the type signature and the atom data.
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const FieldDescriptor* field = it->second;
- java_type_t javaType = java_type(field);
- bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
- os::statsd::LogMode::MODE_BYTES;
-
- AtomField atField(field->name(), javaType);
-
- if (javaType == JAVA_TYPE_ENUM) {
- // All enums are treated as ints when it comes to function signatures.
- collate_enums(*field->enum_type(), &atField);
- }
-
- // Generate signature for pushed atoms
- if (atomDecl->code < PULL_ATOM_START_ID) {
- if (javaType == JAVA_TYPE_ENUM) {
- // All enums are treated as ints when it comes to function signatures.
- signature->push_back(JAVA_TYPE_INT);
- } else if (javaType == JAVA_TYPE_OBJECT && isBinaryField) {
- signature->push_back(JAVA_TYPE_BYTE_ARRAY);
- } else {
- signature->push_back(javaType);
- }
- }
-
- atomDecl->fields.push_back(atField);
-
- errorCount += collate_field_annotations(atomDecl, field, it->first, javaType);
- }
-
- return errorCount;
-}
-
-// This function flattens the fields of the AttributionNode proto in an Atom
-// proto and generates the corresponding atom decl and signature.
-bool get_non_chained_node(const Descriptor* atom, AtomDecl* atomDecl,
- vector<java_type_t>* signature) {
- // Build a sorted list of the fields. Descriptor has them in source file
- // order.
- map<int, const FieldDescriptor*> fields;
- for (int j = 0; j < atom->field_count(); j++) {
- const FieldDescriptor* field = atom->field(j);
- fields[field->number()] = field;
- }
-
- AtomDecl attributionDecl;
- vector<java_type_t> attributionSignature;
- collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl,
- &attributionSignature);
-
- // Build the type signature and the atom data.
- bool has_attribution_node = false;
- for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end();
- it++) {
- const FieldDescriptor* field = it->second;
- java_type_t javaType = java_type(field);
- if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- atomDecl->fields.insert(atomDecl->fields.end(), attributionDecl.fields.begin(),
- attributionDecl.fields.end());
- signature->insert(signature->end(), attributionSignature.begin(),
- attributionSignature.end());
- has_attribution_node = true;
-
- } else {
- AtomField atField(field->name(), javaType);
- if (javaType == JAVA_TYPE_ENUM) {
- // All enums are treated as ints when it comes to function signatures.
- signature->push_back(JAVA_TYPE_INT);
- collate_enums(*field->enum_type(), &atField);
- } else {
- signature->push_back(javaType);
- }
- atomDecl->fields.push_back(atField);
- }
- }
- return has_attribution_node;
-}
-
-static void populateFieldNumberToAtomDeclSet(const shared_ptr<AtomDecl>& atomDecl,
- FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet) {
- for (FieldNumberToAnnotations::const_iterator it = atomDecl->fieldNumberToAnnotations.begin();
- it != atomDecl->fieldNumberToAnnotations.end(); it++) {
- const int fieldNumber = it->first;
- (*fieldNumberToAtomDeclSet)[fieldNumber].insert(atomDecl);
- }
-}
-
-/**
- * Gather the info about the atoms.
- */
-int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms) {
- int errorCount = 0;
-
- for (int i = 0; i < descriptor->field_count(); i++) {
- const FieldDescriptor* atomField = descriptor->field(i);
-
- if (moduleName != DEFAULT_MODULE_NAME) {
- const int moduleCount = atomField->options().ExtensionSize(os::statsd::module);
- int j;
- for (j = 0; j < moduleCount; ++j) {
- const string atomModuleName =
- atomField->options().GetExtension(os::statsd::module, j);
- if (atomModuleName == moduleName) {
- break;
- }
- }
-
- // This atom is not in the module we're interested in; skip it.
- if (moduleCount == j) {
- if (dbg) {
- printf(" Skipping %s (%d)\n", atomField->name().c_str(), atomField->number());
- }
- continue;
- }
- }
-
- if (dbg) {
- printf(" %s (%d)\n", atomField->name().c_str(), atomField->number());
- }
-
- // StatsEvent only has one oneof, which contains only messages. Don't allow
- // other types.
- if (atomField->type() != FieldDescriptor::TYPE_MESSAGE) {
- print_error(atomField,
- "Bad type for atom. StatsEvent can only have message type "
- "fields: %s\n",
- atomField->name().c_str());
- errorCount++;
- continue;
- }
-
- const Descriptor* atom = atomField->message_type();
- shared_ptr<AtomDecl> atomDecl =
- make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());
-
- if (atomDecl->code < PULL_ATOM_START_ID &&
- atomField->options().GetExtension(os::statsd::truncate_timestamp)) {
- addAnnotationToAtomDecl(atomDecl.get(), ATOM_ID_FIELD_NUMBER,
- ANNOTATION_ID_TRUNCATE_TIMESTAMP, ANNOTATION_TYPE_BOOL,
- AnnotationValue(true));
- if (dbg) {
- printf("%s can have timestamp truncated\n", atomField->name().c_str());
- }
- }
-
- vector<java_type_t> signature;
- errorCount += collate_atom(atom, atomDecl.get(), &signature);
- if (atomDecl->primaryFields.size() != 0 && atomDecl->exclusiveField == 0) {
- print_error(atomField, "Cannot have a primary field without an exclusive field: %s\n",
- atomField->name().c_str());
- errorCount++;
- continue;
- }
-
- FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = atoms->signatureInfoMap[signature];
- populateFieldNumberToAtomDeclSet(atomDecl, &fieldNumberToAtomDeclSet);
-
- atoms->decls.insert(atomDecl);
-
- shared_ptr<AtomDecl> nonChainedAtomDecl =
- make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());
- vector<java_type_t> nonChainedSignature;
- if (get_non_chained_node(atom, nonChainedAtomDecl.get(), &nonChainedSignature)) {
- FieldNumberToAtomDeclSet& nonChainedFieldNumberToAtomDeclSet =
- atoms->nonChainedSignatureInfoMap[nonChainedSignature];
- populateFieldNumberToAtomDeclSet(nonChainedAtomDecl,
- &nonChainedFieldNumberToAtomDeclSet);
-
- atoms->non_chained_decls.insert(nonChainedAtomDecl);
- }
- }
-
- if (dbg) {
- printf("signatures = [\n");
- for (SignatureInfoMap::const_iterator it = atoms->signatureInfoMap.begin();
- it != atoms->signatureInfoMap.end(); it++) {
- printf(" ");
- for (vector<java_type_t>::const_iterator jt = it->first.begin(); jt != it->first.end();
- jt++) {
- printf(" %d", (int)*jt);
- }
- printf("\n");
- }
- printf("]\n");
- }
-
- return errorCount;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
deleted file mode 100644
index 10b34ecf5f54..000000000000
--- a/tools/stats_log_api_gen/Collation.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_STATS_LOG_API_GEN_COLLATION_H
-#define ANDROID_STATS_LOG_API_GEN_COLLATION_H
-
-#include <google/protobuf/descriptor.h>
-#include <stdint.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/atom_field_options.pb.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using google::protobuf::Descriptor;
-using google::protobuf::FieldDescriptor;
-using std::map;
-using std::set;
-using std::shared_ptr;
-using std::string;
-using std::vector;
-
-const int PULL_ATOM_START_ID = 10000;
-
-const int FIRST_UID_IN_CHAIN_ID = 0;
-
-enum AnnotationId : uint8_t {
- ANNOTATION_ID_IS_UID = 1,
- ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2,
- ANNOTATION_ID_PRIMARY_FIELD = 3,
- ANNOTATION_ID_EXCLUSIVE_STATE = 4,
- ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5,
- ANNOTATION_ID_DEFAULT_STATE = 6,
- ANNOTATION_ID_TRIGGER_STATE_RESET = 7,
- ANNOTATION_ID_STATE_NESTED = 8,
-};
-
-const int ATOM_ID_FIELD_NUMBER = -1;
-
-const string DEFAULT_MODULE_NAME = "DEFAULT";
-
-/**
- * The types for atom parameters.
- */
-typedef enum {
- JAVA_TYPE_UNKNOWN = 0,
-
- JAVA_TYPE_ATTRIBUTION_CHAIN = 1,
- JAVA_TYPE_BOOLEAN = 2,
- JAVA_TYPE_INT = 3,
- JAVA_TYPE_LONG = 4,
- JAVA_TYPE_FLOAT = 5,
- JAVA_TYPE_DOUBLE = 6,
- JAVA_TYPE_STRING = 7,
- JAVA_TYPE_ENUM = 8,
- JAVA_TYPE_KEY_VALUE_PAIR = 9,
-
- JAVA_TYPE_OBJECT = -1,
- JAVA_TYPE_BYTE_ARRAY = -2,
-} java_type_t;
-
-enum AnnotationType {
- ANNOTATION_TYPE_UNKNOWN = 0,
- ANNOTATION_TYPE_INT = 1,
- ANNOTATION_TYPE_BOOL = 2,
-};
-
-union AnnotationValue {
- int intValue;
- bool boolValue;
-
- AnnotationValue(const int value) : intValue(value) {
- }
- AnnotationValue(const bool value) : boolValue(value) {
- }
-};
-
-struct Annotation {
- const AnnotationId annotationId;
- const int atomId;
- AnnotationType type;
- AnnotationValue value;
-
- inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type,
- AnnotationValue value)
- : annotationId(annotationId), atomId(atomId), type(type), value(value) {
- }
- inline ~Annotation() {
- }
-
- inline bool operator<(const Annotation& that) const {
- return atomId == that.atomId ? annotationId < that.annotationId : atomId < that.atomId;
- }
-};
-
-struct SharedComparator {
- template <typename T>
- inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const {
- return (*lhs) < (*rhs);
- }
-};
-
-using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>;
-
-using FieldNumberToAnnotations = map<int, AnnotationSet>;
-
-/**
- * The name and type for an atom field.
- */
-struct AtomField {
- string name;
- java_type_t javaType;
-
- // If the field is of type enum, the following map contains the list of enum
- // values.
- map<int /* numeric value */, string /* value name */> enumValues;
-
- inline AtomField() : name(), javaType(JAVA_TYPE_UNKNOWN) {
- }
- inline AtomField(const AtomField& that)
- : name(that.name), javaType(that.javaType), enumValues(that.enumValues) {
- }
-
- inline AtomField(string n, java_type_t jt) : name(n), javaType(jt) {
- }
- inline ~AtomField() {
- }
-};
-
-/**
- * The name and code for an atom.
- */
-struct AtomDecl {
- int code;
- string name;
-
- string message;
- vector<AtomField> fields;
-
- FieldNumberToAnnotations fieldNumberToAnnotations;
-
- vector<int> primaryFields;
- int exclusiveField = 0;
- int defaultState = INT_MAX;
- int triggerStateReset = INT_MAX;
- bool nested = true;
-
- int uidField = 0;
-
- AtomDecl();
- AtomDecl(const AtomDecl& that);
- AtomDecl(int code, const string& name, const string& message);
- ~AtomDecl();
-
- inline bool operator<(const AtomDecl& that) const {
- return (code == that.code) ? (name < that.name) : (code < that.code);
- }
-};
-
-using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>;
-
-// Maps a field number to a set of atoms that have annotation(s) for their field with that field
-// number.
-using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>;
-
-using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>;
-
-struct Atoms {
- SignatureInfoMap signatureInfoMap;
- AtomDeclSet decls;
- AtomDeclSet non_chained_decls;
- SignatureInfoMap nonChainedSignatureInfoMap;
-};
-
-/**
- * Gather the information about the atoms. Returns the number of errors.
- */
-int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms);
-int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature);
-
-} // namespace stats_log_api_gen
-} // namespace android
-
-#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
deleted file mode 100644
index f4c937c3f599..000000000000
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "java_writer.h"
-
-#include "java_writer_q.h"
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static int write_java_q_logger_class(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl) {
- fprintf(out, "\n");
- fprintf(out, " // Write logging helper methods for statsd in Q and earlier.\n");
- fprintf(out, " private static class QLogger {\n");
-
- write_java_q_logging_constants(out, " ");
-
- // Print Q write methods.
- fprintf(out, "\n");
- fprintf(out, " // Write methods.\n");
- write_java_methods_q_schema(out, signatureInfoMap, attributionDecl, " ");
-
- fprintf(out, " }\n");
- return 0;
-}
-
-static void write_java_annotation_constants(FILE* out) {
- fprintf(out, " // Annotation constants.\n");
-
- for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) {
- fprintf(out, " public static final byte %s = %hhu;\n", name.c_str(), id);
- }
- fprintf(out, "\n");
-}
-
-static void write_annotations(FILE* out, int argIndex,
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet) {
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
- fieldNumberToAtomDeclSet.find(argIndex);
- if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) {
- return;
- }
- const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
- for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
- const string atomConstant = make_constant_name(atomDecl->name);
- fprintf(out, " if (%s == code) {\n", atomConstant.c_str());
- const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex);
- int resetState = -1;
- int defaultState = -1;
- for (const shared_ptr<Annotation>& annotation : annotations) {
- const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId);
- switch (annotation->type) {
- case ANNOTATION_TYPE_INT:
- if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) {
- resetState = annotation->value.intValue;
- } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) {
- defaultState = annotation->value.intValue;
- } else {
- fprintf(out, " builder.addIntAnnotation(%s, %d);\n",
- annotationConstant.c_str(), annotation->value.intValue);
- }
- break;
- case ANNOTATION_TYPE_BOOL:
- fprintf(out, " builder.addBooleanAnnotation(%s, %s);\n",
- annotationConstant.c_str(),
- annotation->value.boolValue ? "true" : "false");
- break;
- default:
- break;
- }
- }
- if (defaultState != -1 && resetState != -1) {
- const string& annotationConstant =
- ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET);
- fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState);
- fprintf(out, " builder.addIntAnnotation(%s, %d);\n",
- annotationConstant.c_str(), defaultState);
- fprintf(out, " }\n");
- }
- fprintf(out, " }\n");
- }
-}
-
-static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl, const bool supportQ) {
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- // Print method signature.
- fprintf(out, " public static void write(int code");
- const vector<java_type_t>& signature = signatureInfoMapIt->first;
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s", java_type_name(chainField.javaType),
- chainField.name.c_str());
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> valueMap");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- // Print method body.
- string indent("");
- if (supportQ) {
- fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n");
- indent = " ";
- }
-
- // Start StatsEvent.Builder.
- fprintf(out,
- "%s final StatsEvent.Builder builder = "
- "StatsEvent.newBuilder();\n",
- indent.c_str());
-
- // Write atom code.
- fprintf(out, "%s builder.setAtomId(code);\n", indent.c_str());
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet);
-
- // Write the args.
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, "%s builder.writeBoolean(arg%d);\n", indent.c_str(),
- argIndex);
- break;
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- fprintf(out, "%s builder.writeInt(arg%d);\n", indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, "%s builder.writeFloat(arg%d);\n", indent.c_str(),
- argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, "%s builder.writeLong(arg%d);\n", indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, "%s builder.writeString(arg%d);\n", indent.c_str(),
- argIndex);
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out,
- "%s builder.writeByteArray(null == arg%d ? new byte[0] : "
- "arg%d);\n",
- indent.c_str(), argIndex, argIndex);
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
-
- fprintf(out, "%s builder.writeAttributionChain(\n", indent.c_str());
- fprintf(out, "%s null == %s ? new int[0] : %s,\n",
- indent.c_str(), uidName, uidName);
- fprintf(out, "%s null == %s ? new String[0] : %s);\n",
- indent.c_str(), tagName, tagName);
- break;
- }
- case JAVA_TYPE_KEY_VALUE_PAIR:
- fprintf(out, "\n");
- fprintf(out, "%s // Write KeyValuePairs.\n", indent.c_str());
- fprintf(out, "%s final int count = valueMap.size();\n", indent.c_str());
- fprintf(out, "%s android.util.SparseIntArray intMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseLongArray longMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<String> stringMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<Float> floatMap = null;\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < count; i++) {\n", indent.c_str());
- fprintf(out, "%s final int key = valueMap.keyAt(i);\n",
- indent.c_str());
- fprintf(out, "%s final Object value = valueMap.valueAt(i);\n",
- indent.c_str());
- fprintf(out, "%s if (value instanceof Integer) {\n", indent.c_str());
- fprintf(out, "%s if (null == intMap) {\n", indent.c_str());
- fprintf(out,
- "%s intMap = new "
- "android.util.SparseIntArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s intMap.put(key, (Integer) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof Long) {\n",
- indent.c_str());
- fprintf(out, "%s if (null == longMap) {\n", indent.c_str());
- fprintf(out,
- "%s longMap = new "
- "android.util.SparseLongArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s longMap.put(key, (Long) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof String) {\n",
- indent.c_str());
- fprintf(out, "%s if (null == stringMap) {\n", indent.c_str());
- fprintf(out,
- "%s stringMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s stringMap.put(key, (String) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof Float) {\n",
- indent.c_str());
- fprintf(out, "%s if (null == floatMap) {\n", indent.c_str());
- fprintf(out,
- "%s floatMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s floatMap.put(key, (Float) value);\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out,
- "%s builder.writeKeyValuePairs("
- "intMap, longMap, stringMap, floatMap);\n",
- indent.c_str());
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE.
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet);
- argIndex++;
- }
-
- fprintf(out, "\n");
- fprintf(out, "%s builder.usePooledBuffer();\n", indent.c_str());
- fprintf(out, "%s StatsLog.write(builder.build());\n", indent.c_str());
-
- // Add support for writing using Q schema if this is not the default module.
- if (supportQ) {
- fprintf(out, " } else {\n");
- fprintf(out, " QLogger.write(code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out, ", %s, %s", uidName, tagName);
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- // Module logging does not yet support key value pair.
- fprintf(stderr, "Module logging does not yet support key value pair.\n");
- return 1;
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n"); // if
- }
-
- fprintf(out, " }\n"); // method
- fprintf(out, "\n");
- }
- return 0;
-}
-
-int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& javaClass, const string& javaPackage, const bool supportQ,
- const bool supportWorkSource) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package %s;\n", javaPackage.c_str());
- fprintf(out, "\n");
- fprintf(out, "\n");
- if (supportQ) {
- fprintf(out, "import android.os.Build;\n");
- fprintf(out, "import android.os.SystemClock;\n");
- }
-
- fprintf(out, "import android.util.StatsEvent;\n");
- fprintf(out, "import android.util.StatsLog;\n");
-
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * Utility class for logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "public class %s {\n", javaClass.c_str());
-
- write_java_atom_codes(out, atoms);
- write_java_enum_values(out, atoms);
- write_java_annotation_constants(out);
-
- int errors = 0;
-
- // Print write methods.
- fprintf(out, " // Write methods\n");
- errors += write_java_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ);
- errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
- if (supportWorkSource) {
- errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
- }
-
- if (supportQ) {
- errors += write_java_q_logger_class(out, atoms.signatureInfoMap, attributionDecl);
- }
-
- fprintf(out, "}\n");
-
- return errors;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h
deleted file mode 100644
index 8b3b50588efc..000000000000
--- a/tools/stats_log_api_gen/java_writer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& javaClass, const string& javaPackage, const bool supportQ,
- const bool supportWorkSource);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
deleted file mode 100644
index d21e2708b724..000000000000
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "java_writer_q.h"
-
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-void write_java_q_logging_constants(FILE* out, const string& indent) {
- fprintf(out, "%s// Payload limits.\n", indent.c_str());
- fprintf(out, "%sprivate static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n", indent.c_str());
- fprintf(out,
- "%sprivate static final int MAX_EVENT_PAYLOAD = "
- "LOGGER_ENTRY_MAX_PAYLOAD - 4;\n",
- indent.c_str());
-
- // Value types. Must match with EventLog.java and log.h.
- fprintf(out, "\n");
- fprintf(out, "%s// Value types.\n", indent.c_str());
- fprintf(out, "%sprivate static final byte INT_TYPE = 0;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte LONG_TYPE = 1;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte STRING_TYPE = 2;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte LIST_TYPE = 3;\n", indent.c_str());
- fprintf(out, "%sprivate static final byte FLOAT_TYPE = 4;\n", indent.c_str());
-
- // Size of each value type.
- // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for
- // the value.
- fprintf(out, "\n");
- fprintf(out, "%s// Size of each value type.\n", indent.c_str());
- fprintf(out, "%sprivate static final int INT_TYPE_SIZE = 5;\n", indent.c_str());
- fprintf(out, "%sprivate static final int FLOAT_TYPE_SIZE = 5;\n", indent.c_str());
- // Longs take 9 bytes, 1 for the type and 8 for the value.
- fprintf(out, "%sprivate static final int LONG_TYPE_SIZE = 9;\n", indent.c_str());
- // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the
- // length.
- fprintf(out, "%sprivate static final int STRING_TYPE_OVERHEAD = 5;\n", indent.c_str());
- fprintf(out, "%sprivate static final int LIST_TYPE_OVERHEAD = 2;\n", indent.c_str());
-}
-
-int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl, const string& indent) {
- int requiredHelpers = 0;
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- // Print method signature.
- vector<java_type_t> signature = signatureInfoMapIt->first;
- fprintf(out, "%spublic static void write(int code", indent.c_str());
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s", java_type_name(chainField.javaType),
- chainField.name.c_str());
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> valueMap");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- // Calculate the size of the buffer.
- fprintf(out, "%s // Initial overhead of the list, timestamp, and atom tag.\n",
- indent.c_str());
- fprintf(out,
- "%s int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + "
- "INT_TYPE_SIZE;\n",
- indent.c_str());
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- case JAVA_TYPE_INT:
- case JAVA_TYPE_FLOAT:
- case JAVA_TYPE_ENUM:
- fprintf(out, "%s needed += INT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_LONG:
- // Longs take 9 bytes, 1 for the type and 8 for the value.
- fprintf(out, "%s needed += LONG_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_STRING:
- // Strings take 5 metadata bytes + length of byte encoded string.
- fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex);
- fprintf(out, "%s arg%d = \"\";\n", indent.c_str(), argIndex);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out,
- "%s byte[] arg%dBytes = "
- "arg%d.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- // Byte arrays take 5 metadata bytes + length of byte array.
- fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex);
- fprintf(out, "%s arg%d = new byte[0];\n", indent.c_str(), argIndex);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%d.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- // Null checks on the params.
- fprintf(out, "%s if (%s == null) {\n", indent.c_str(), uidName);
- fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), uidName,
- java_type_name(attributionDecl.fields.front().javaType));
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s if (%s == null) {\n", indent.c_str(), tagName);
- fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), tagName,
- java_type_name(attributionDecl.fields.back().javaType));
- fprintf(out, "%s }\n", indent.c_str());
-
- // First check that the lengths of the uid and tag arrays are the
- // same.
- fprintf(out, "%s if (%s.length != %s.length) {\n", indent.c_str(), uidName,
- tagName);
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s int attrSize = LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(),
- tagName);
- fprintf(out, "%s String str%d = (%s[i] == null) ? \"\" : %s[i];\n",
- indent.c_str(), argIndex, tagName, tagName);
- fprintf(out,
- "%s int str%dlen = "
- "str%d.getBytes(java.nio.charset.StandardCharsets.UTF_8)."
- "length;\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out,
- "%s attrSize += "
- "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + "
- "str%dlen;\n",
- indent.c_str(), argIndex);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s needed += attrSize;\n", indent.c_str());
- break;
- }
- case JAVA_TYPE_KEY_VALUE_PAIR: {
- fprintf(out, "%s // Calculate bytes needed by Key Value Pairs.\n",
- indent.c_str());
- fprintf(out, "%s final int count = valueMap.size();\n", indent.c_str());
- fprintf(out, "%s android.util.SparseIntArray intMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseLongArray longMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<String> stringMap = null;\n",
- indent.c_str());
- fprintf(out, "%s android.util.SparseArray<Float> floatMap = null;\n",
- indent.c_str());
- fprintf(out, "%s int keyValuePairSize = LIST_TYPE_OVERHEAD;\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < count; i++) {\n", indent.c_str());
- fprintf(out, "%s final int key = valueMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final Object value = valueMap.valueAt(i);\n",
- indent.c_str());
- fprintf(out, "%s if (value instanceof Integer) {\n", indent.c_str());
- fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n",
- indent.c_str());
- fprintf(out, "%s + INT_TYPE_SIZE + INT_TYPE_SIZE;\n",
- indent.c_str());
- fprintf(out, "%s if (null == intMap) {\n", indent.c_str());
- fprintf(out, "%s intMap = new android.util.SparseIntArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s intMap.put(key, (Integer) value);\n",
- indent.c_str());
- fprintf(out, "%s } else if (value instanceof Long) {\n", indent.c_str());
- fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n",
- indent.c_str());
- fprintf(out, "%s + INT_TYPE_SIZE + LONG_TYPE_SIZE;\n",
- indent.c_str());
- fprintf(out, "%s if (null == longMap) {\n", indent.c_str());
- fprintf(out,
- "%s longMap = new "
- "android.util.SparseLongArray();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s longMap.put(key, (Long) value);\n", indent.c_str());
- fprintf(out, "%s } else if (value instanceof String) {\n",
- indent.c_str());
- fprintf(out,
- "%s final String str = (value == null) ? \"\" : "
- "(String) value;\n",
- indent.c_str());
- fprintf(out,
- "%s final int len = "
- "str.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;\n",
- indent.c_str());
- fprintf(out,
- "%s keyValuePairSize += LIST_TYPE_OVERHEAD + "
- "INT_TYPE_SIZE\n",
- indent.c_str());
- fprintf(out, "%s + STRING_TYPE_OVERHEAD + len;\n",
- indent.c_str());
- fprintf(out, "%s if (null == stringMap) {\n", indent.c_str());
- fprintf(out,
- "%s stringMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s stringMap.put(key, str);\n", indent.c_str());
- fprintf(out, "%s } else if (value instanceof Float) {\n",
- indent.c_str());
- fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n",
- indent.c_str());
- fprintf(out, "%s + INT_TYPE_SIZE + FLOAT_TYPE_SIZE;\n",
- indent.c_str());
- fprintf(out, "%s if (null == floatMap) {\n", indent.c_str());
- fprintf(out,
- "%s floatMap = new "
- "android.util.SparseArray<>();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s floatMap.put(key, (Float) value);\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s needed += keyValuePairSize;\n", indent.c_str());
- break;
- }
- default:
- // Unsupported types: OBJECT, DOUBLE.
- fprintf(stderr, "Module logging does not yet support Object and Double.\n");
- return 1;
- }
- argIndex++;
- }
-
- // Now we have the size that is needed. Check for overflow and return if
- // needed.
- fprintf(out, "%s if (needed > MAX_EVENT_PAYLOAD) {\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Create new buffer, and associated data types.
- fprintf(out, "%s byte[] buff = new byte[needed];\n", indent.c_str());
- fprintf(out, "%s int pos = 0;\n", indent.c_str());
-
- // Initialize the buffer with list data type.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = %zu;\n", indent.c_str(), signature.size() + 2);
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Write timestamp.
- fprintf(out, "%s long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyLong(buff, pos + 1, elapsedRealtime);\n", indent.c_str());
- fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str());
-
- // Write atom code.
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, code);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
-
- // Write the args.
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%d? 1 : 0);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%d);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_FLOAT:
- requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
- fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyFloat(buff, pos + 1, arg%d);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyLong(buff, pos + 1, arg%d);\n", indent.c_str(),
- argIndex);
- fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str());
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%dBytes.length);\n",
- indent.c_str(), argIndex);
- fprintf(out,
- "%s System.arraycopy("
- "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, "
- "arg%dBytes.length);\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, arg%d.length);\n", indent.c_str(),
- argIndex);
- fprintf(out,
- "%s System.arraycopy("
- "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n",
- indent.c_str(), argIndex, argIndex);
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%d.length;\n",
- indent.c_str(), argIndex);
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION;
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
-
- fprintf(out, "%s writeAttributionChain(buff, pos, %s, %s);\n",
- indent.c_str(), uidName, tagName);
- fprintf(out, "%s pos += attrSize;\n", indent.c_str());
- break;
- }
- case JAVA_TYPE_KEY_VALUE_PAIR:
- requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
- requiredHelpers |= JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS;
- fprintf(out,
- "%s writeKeyValuePairs(buff, pos, (byte) count, intMap, "
- "longMap, "
- "stringMap, floatMap);\n",
- indent.c_str());
- fprintf(out, "%s pos += keyValuePairSize;\n", indent.c_str());
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE.
- fprintf(stderr, "Object and Double are not supported in module logging");
- return 1;
- }
- argIndex++;
- }
-
- fprintf(out, "%s StatsLog.writeRaw(buff, pos);\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-
- write_java_helpers_for_q_schema_methods(out, attributionDecl, requiredHelpers, indent);
-
- return 0;
-}
-
-void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl,
- const int requiredHelpers, const string& indent) {
- fprintf(out, "\n");
- fprintf(out, "%s// Helper methods for copying primitives\n", indent.c_str());
- fprintf(out, "%sprivate static void copyInt(byte[] buff, int pos, int val) {\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
-
- fprintf(out, "%sprivate static void copyLong(byte[] buff, int pos, long val) {\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 4] = (byte) (val >> 32);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 5] = (byte) (val >> 40);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 6] = (byte) (val >> 48);\n", indent.c_str());
- fprintf(out, "%s buff[pos + 7] = (byte) (val >> 56);\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
-
- if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) {
- fprintf(out, "%sprivate static void copyFloat(byte[] buff, int pos, float val) {\n",
- indent.c_str());
- fprintf(out, "%s copyInt(buff, pos, Float.floatToIntBits(val));\n", indent.c_str());
- fprintf(out, "%s return;\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-
- if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) {
- fprintf(out, "%sprivate static void writeAttributionChain(byte[] buff, int pos",
- indent.c_str());
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s", java_type_name(chainField.javaType), chainField.name.c_str());
- }
- fprintf(out, ") {\n");
-
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
-
- // Write the first list begin.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) (%s.length);\n", indent.c_str(), tagName);
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Iterate through the attribution chain and write the nodes.
- fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(), tagName);
- // Write the list begin.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = %lu;\n", indent.c_str(),
- attributionDecl.fields.size());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Write the uid.
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, %s[i]);\n", indent.c_str(), uidName);
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
-
- // Write the tag.
- fprintf(out, "%s String %sStr = (%s[i] == null) ? \"\" : %s[i];\n", indent.c_str(),
- tagName, tagName, tagName);
- fprintf(out,
- "%s byte[] %sByte = "
- "%sStr.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n",
- indent.c_str(), tagName, tagName);
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, %sByte.length);\n", indent.c_str(), tagName);
- fprintf(out,
- "%s System.arraycopy("
- "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n",
- indent.c_str(), tagName, tagName);
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", indent.c_str(),
- tagName);
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-
- if (requiredHelpers & JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS) {
- fprintf(out,
- "%sprivate static void writeKeyValuePairs(byte[] buff, int pos, "
- "byte numPairs,\n",
- indent.c_str());
- fprintf(out, "%s final android.util.SparseIntArray intMap,\n", indent.c_str());
- fprintf(out, "%s final android.util.SparseLongArray longMap,\n", indent.c_str());
- fprintf(out, "%s final android.util.SparseArray<String> stringMap,\n",
- indent.c_str());
- fprintf(out, "%s final android.util.SparseArray<Float> floatMap) {\n",
- indent.c_str());
-
- // Start list of lists.
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) numPairs;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
-
- // Write integers.
- fprintf(out, "%s final int intMapSize = null == intMap ? 0 : intMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < intMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = intMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final int value = intMap.valueAt(i);\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, value);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Write longs.
- fprintf(out, "%s final int longMapSize = null == longMap ? 0 : longMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < longMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = longMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final long value = longMap.valueAt(i);\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyLong(buff, pos + 1, value);\n", indent.c_str());
- fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Write Strings.
- fprintf(out,
- "%s final int stringMapSize = null == stringMap ? 0 : "
- "stringMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < stringMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = stringMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final String value = stringMap.valueAt(i);\n", indent.c_str());
- fprintf(out,
- "%s final byte[] valueBytes = "
- "value.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n",
- indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, valueBytes.length);\n", indent.c_str());
- fprintf(out,
- "%s System.arraycopy("
- "valueBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, "
- "valueBytes.length);\n",
- indent.c_str());
- fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + valueBytes.length;\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
-
- // Write floats.
- fprintf(out,
- "%s final int floatMapSize = null == floatMap ? 0 : "
- "floatMap.size();\n",
- indent.c_str());
- fprintf(out, "%s for (int i = 0; i < floatMapSize; i++) {\n", indent.c_str());
- fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str());
- fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str());
- fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str());
- fprintf(out, "%s final int key = floatMap.keyAt(i);\n", indent.c_str());
- fprintf(out, "%s final float value = floatMap.valueAt(i);\n", indent.c_str());
- fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str());
- fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str());
- fprintf(out, "%s copyFloat(buff, pos + 1, value);\n", indent.c_str());
- fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "\n");
- }
-}
-
-// This method is called in main.cpp to generate StatsLog for modules that's
-// compatible with Q at compile-time.
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& javaClass,
- const string& javaPackage, const bool supportWorkSource) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package %s;\n", javaPackage.c_str());
- fprintf(out, "\n");
- fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
- fprintf(out, "\n");
- fprintf(out, "import android.util.StatsLog;\n");
- fprintf(out, "import android.os.SystemClock;\n");
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * Utility class for logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "public class %s {\n", javaClass.c_str());
-
- write_java_q_logging_constants(out, " ");
-
- write_java_atom_codes(out, atoms);
-
- write_java_enum_values(out, atoms);
-
- int errors = 0;
- // Print write methods
- fprintf(out, " // Write methods\n");
- errors += write_java_methods_q_schema(out, atoms.signatureInfoMap, attributionDecl, " ");
- errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
- if (supportWorkSource) {
- errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
- }
-
- fprintf(out, "}\n");
-
- return errors;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
deleted file mode 100644
index c511a8436416..000000000000
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-void write_java_q_logging_constants(FILE* out, const string& indent);
-
-int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl, const string& indent);
-
-void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl,
- const int requiredHelpers, const string& indent);
-
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& javaClass,
- const string& javaPackage, const bool supportWorkSource);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
deleted file mode 100644
index b888ce904b31..000000000000
--- a/tools/stats_log_api_gen/main.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
-#include "java_writer.h"
-#include "java_writer_q.h"
-#include "native_writer.h"
-#include "utils.h"
-
-using namespace google::protobuf;
-using namespace std;
-
-namespace android {
-namespace stats_log_api_gen {
-
-using android::os::statsd::Atom;
-
-static void print_usage() {
- fprintf(stderr, "usage: stats-log-api-gen OPTIONS\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "OPTIONS\n");
- fprintf(stderr, " --cpp FILENAME the header file to output for write helpers\n");
- fprintf(stderr, " --header FILENAME the cpp file to output for write helpers\n");
- fprintf(stderr, " --help this message\n");
- fprintf(stderr, " --java FILENAME the java file to output\n");
- fprintf(stderr, " --module NAME optional, module name to generate outputs for\n");
- fprintf(stderr,
- " --namespace COMMA,SEP,NAMESPACE required for cpp/header with "
- "module\n");
- fprintf(stderr,
- " comma separated namespace of "
- "the files\n");
- fprintf(stderr,
- " --importHeader NAME required for cpp/jni to say which header to "
- "import "
- "for write helpers\n");
- fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n");
- fprintf(stderr, " required for java with module\n");
- fprintf(stderr, " --javaClass CLASS the class name of the java class.\n");
- fprintf(stderr, " Optional for Java with module.\n");
- fprintf(stderr, " Default is \"StatsLogInternal\"\n");
- fprintf(stderr, " --supportQ Include runtime support for Android Q.\n");
- fprintf(stderr,
- " --worksource Include support for logging WorkSource "
- "objects.\n");
- fprintf(stderr,
- " --compileQ Include compile-time support for Android Q "
- "(Java only).\n");
-}
-
-/**
- * Do the argument parsing and execute the tasks.
- */
-static int run(int argc, char const* const* argv) {
- string cppFilename;
- string headerFilename;
- string javaFilename;
- string javaPackage;
- string javaClass;
-
- string moduleName = DEFAULT_MODULE_NAME;
- string cppNamespace = DEFAULT_CPP_NAMESPACE;
- string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
- bool supportQ = false;
- bool supportWorkSource = false;
- bool compileQ = false;
-
- int index = 1;
- while (index < argc) {
- if (0 == strcmp("--help", argv[index])) {
- print_usage();
- return 0;
- } else if (0 == strcmp("--cpp", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- cppFilename = argv[index];
- } else if (0 == strcmp("--header", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- headerFilename = argv[index];
- } else if (0 == strcmp("--java", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- javaFilename = argv[index];
- } else if (0 == strcmp("--module", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- moduleName = argv[index];
- } else if (0 == strcmp("--namespace", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- cppNamespace = argv[index];
- } else if (0 == strcmp("--importHeader", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- cppHeaderImport = argv[index];
- } else if (0 == strcmp("--javaPackage", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- javaPackage = argv[index];
- } else if (0 == strcmp("--javaClass", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- javaClass = argv[index];
- } else if (0 == strcmp("--supportQ", argv[index])) {
- supportQ = true;
- } else if (0 == strcmp("--worksource", argv[index])) {
- supportWorkSource = true;
- } else if (0 == strcmp("--compileQ", argv[index])) {
- compileQ = true;
- }
-
- index++;
- }
-
- if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0) {
- print_usage();
- return 1;
- }
-
- if (DEFAULT_MODULE_NAME == moduleName && (supportQ || compileQ)) {
- // Support for Q schema is not needed for default module.
- fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str());
- return 1;
- }
-
- if (supportQ && compileQ) {
- // Runtime Q support is redundant if compile-time Q support is required.
- fprintf(stderr, "Cannot specify compileQ and supportQ simultaneously.\n");
- return 1;
- }
-
- // Collate the parameters
- Atoms atoms;
- int errorCount = collate_atoms(Atom::descriptor(), moduleName, &atoms);
- if (errorCount != 0) {
- return 1;
- }
-
- AtomDecl attributionDecl;
- vector<java_type_t> attributionSignature;
- collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl,
- &attributionSignature);
-
- // Write the .cpp file
- if (cppFilename.size() != 0) {
- FILE* out = fopen(cppFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str());
- return 1;
- }
- // If this is for a specific module, the namespace must also be provided.
- if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) {
- fprintf(stderr, "Must supply --namespace if supplying a specific module\n");
- return 1;
- }
- // If this is for a specific module, the header file to import must also be
- // provided.
- if (moduleName != DEFAULT_MODULE_NAME && cppHeaderImport == DEFAULT_CPP_HEADER_IMPORT) {
- fprintf(stderr, "Must supply --headerImport if supplying a specific module\n");
- return 1;
- }
- errorCount = android::stats_log_api_gen::write_stats_log_cpp(
- out, atoms, attributionDecl, cppNamespace, cppHeaderImport, supportQ);
- fclose(out);
- }
-
- // Write the .h file
- if (headerFilename.size() != 0) {
- FILE* out = fopen(headerFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str());
- return 1;
- }
- // If this is for a specific module, the namespace must also be provided.
- if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) {
- fprintf(stderr, "Must supply --namespace if supplying a specific module\n");
- }
- errorCount = android::stats_log_api_gen::write_stats_log_header(out, atoms, attributionDecl,
- cppNamespace);
- fclose(out);
- }
-
- // Write the .java file
- if (javaFilename.size() != 0) {
- if (javaClass.size() == 0) {
- fprintf(stderr, "Must supply --javaClass if supplying a Java filename");
- return 1;
- }
-
- if (javaPackage.size() == 0) {
- fprintf(stderr, "Must supply --javaPackage if supplying a Java filename");
- return 1;
- }
-
- if (moduleName.size() == 0) {
- fprintf(stderr, "Must supply --module if supplying a Java filename");
- return 1;
- }
-
- FILE* out = fopen(javaFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
- return 1;
- }
-
- if (compileQ) {
- errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
- out, atoms, attributionDecl, javaClass, javaPackage, supportWorkSource);
- } else {
- errorCount = android::stats_log_api_gen::write_stats_log_java(
- out, atoms, attributionDecl, javaClass, javaPackage, supportQ,
- supportWorkSource);
- }
-
- fclose(out);
- }
-
- return errorCount;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
-
-/**
- * Main.
- */
-int main(int argc, char const* const* argv) {
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-
- return android::stats_log_api_gen::run(argc, argv);
-}
diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp
deleted file mode 100644
index 0c6c0099e459..000000000000
--- a/tools/stats_log_api_gen/native_writer.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "native_writer.h"
-
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static void write_native_annotation_constants(FILE* out) {
- fprintf(out, "// Annotation constants.\n");
-
- for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) {
- fprintf(out, "const uint8_t %s = %hhu;\n", name.c_str(), id);
- }
- fprintf(out, "\n");
-}
-
-static void write_annotations(FILE* out, int argIndex,
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet,
- const string& methodPrefix, const string& methodSuffix) {
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
- fieldNumberToAtomDeclSet.find(argIndex);
- if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) {
- return;
- }
- const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
- for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
- const string atomConstant = make_constant_name(atomDecl->name);
- fprintf(out, " if (%s == code) {\n", atomConstant.c_str());
- const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex);
- int resetState = -1;
- int defaultState = -1;
- for (const shared_ptr<Annotation>& annotation : annotations) {
- const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId);
- switch (annotation->type) {
- case ANNOTATION_TYPE_INT:
- if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) {
- resetState = annotation->value.intValue;
- } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) {
- defaultState = annotation->value.intValue;
- } else {
- fprintf(out, " %saddInt32Annotation(%s%s, %d);\n",
- methodPrefix.c_str(), methodSuffix.c_str(),
- annotationConstant.c_str(), annotation->value.intValue);
- }
- break;
- case ANNOTATION_TYPE_BOOL:
- // TODO(b/151786433): Write annotation constant name instead of
- // annotation id literal.
- fprintf(out, " %saddBoolAnnotation(%s%s, %s);\n", methodPrefix.c_str(),
- methodSuffix.c_str(), annotationConstant.c_str(),
- annotation->value.boolValue ? "true" : "false");
- break;
- default:
- break;
- }
- }
- if (defaultState != -1 && resetState != -1) {
- const string& annotationConstant =
- ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET);
- fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState);
- fprintf(out, " %saddInt32Annotation(%s%s, %d);\n", methodPrefix.c_str(),
- methodSuffix.c_str(), annotationConstant.c_str(), defaultState);
- fprintf(out, " }\n");
- }
- fprintf(out, " }\n");
- }
-}
-
-static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const bool supportQ) {
- fprintf(out, "\n");
- for (auto signatureInfoMapIt = atoms.signatureInfoMap.begin();
- signatureInfoMapIt != atoms.signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
- const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
- write_native_method_signature(out, "int stats_write", signature, attributionDecl, " {");
-
- int argIndex = 1;
- if (supportQ) {
- fprintf(out, " StatsEventCompat event;\n");
- fprintf(out, " event.setAtomId(code);\n");
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "event.", "");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- switch (*arg) {
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out, " event.writeAttributionChain(%s, %s_length, %s);\n",
- uidName, uidName, tagName);
- break;
- }
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out, " event.writeByteArray(arg%d.arg, arg%d.arg_length);\n",
- argIndex, argIndex);
- break;
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, " event.writeBool(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_INT: // Fall through.
- case JAVA_TYPE_ENUM:
- fprintf(out, " event.writeInt32(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, " event.writeFloat(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, " event.writeInt64(arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, " event.writeString(arg%d);\n", argIndex);
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS.
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "event.", "");
- argIndex++;
- }
- fprintf(out, " return event.writeToSocket();\n");
- } else {
- fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n");
- fprintf(out, " AStatsEvent_setAtomId(event, code);\n");
- write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_",
- "event, ");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- switch (*arg) {
- case JAVA_TYPE_ATTRIBUTION_CHAIN: {
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out,
- " AStatsEvent_writeAttributionChain(event, "
- "reinterpret_cast<const uint32_t*>(%s), %s.data(), "
- "static_cast<uint8_t>(%s_length));\n",
- uidName, tagName, uidName);
- break;
- }
- case JAVA_TYPE_BYTE_ARRAY:
- fprintf(out,
- " AStatsEvent_writeByteArray(event, "
- "reinterpret_cast<const uint8_t*>(arg%d.arg), "
- "arg%d.arg_length);\n",
- argIndex, argIndex);
- break;
- case JAVA_TYPE_BOOLEAN:
- fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_INT: // Fall through.
- case JAVA_TYPE_ENUM:
- fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_FLOAT:
- fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_LONG:
- fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex);
- break;
- case JAVA_TYPE_STRING:
- fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex);
- break;
- default:
- // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS
- fprintf(stderr, "Encountered unsupported type.");
- return 1;
- }
- write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_",
- "event, ");
- argIndex++;
- }
- fprintf(out, " const int ret = AStatsEvent_write(event);\n");
- fprintf(out, " AStatsEvent_release(event);\n");
- fprintf(out, " return ret;\n");
- }
- fprintf(out, "}\n\n");
- }
- return 0;
-}
-
-static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl) {
- fprintf(out, "\n");
- for (auto signature_it = atoms.nonChainedSignatureInfoMap.begin();
- signature_it != atoms.nonChainedSignatureInfoMap.end(); signature_it++) {
- vector<java_type_t> signature = signature_it->first;
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
-
- write_native_method_signature(out, "int stats_write_non_chained", signature,
- attributionDecl, " {");
-
- vector<java_type_t> newSignature;
-
- // First two args form the attribution node so size goes down by 1.
- newSignature.reserve(signature.size() - 1);
-
- // First arg is Attribution Chain.
- newSignature.push_back(JAVA_TYPE_ATTRIBUTION_CHAIN);
-
- // Followed by the originial signature except the first 2 args.
- newSignature.insert(newSignature.end(), signature.begin() + 2, signature.end());
-
- const char* uidName = attributionDecl.fields.front().name.c_str();
- const char* tagName = attributionDecl.fields.back().name.c_str();
- fprintf(out, " const int32_t* %s = &arg1;\n", uidName);
- fprintf(out, " const size_t %s_length = 1;\n", uidName);
- fprintf(out, " const std::vector<char const*> %s(1, arg2);\n", tagName);
- fprintf(out, " return ");
- write_native_method_call(out, "stats_write", newSignature, attributionDecl, 2);
-
- fprintf(out, "}\n\n");
- }
-}
-
-static void write_native_method_header(FILE* out, const string& methodName,
- const SignatureInfoMap& signatureInfoMap,
- const AtomDecl& attributionDecl) {
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
-
- // Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
- continue;
- }
- write_native_method_signature(out, methodName, signature, attributionDecl, ";");
- }
-}
-
-int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace, const string& importHeader,
- const bool supportQ) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
-
- fprintf(out, "#include <%s>\n", importHeader.c_str());
- if (supportQ) {
- fprintf(out, "#include <StatsEventCompat.h>\n");
- } else {
- fprintf(out, "#include <stats_event.h>\n");
- }
-
- fprintf(out, "\n");
- write_namespace(out, cppNamespace);
-
- write_native_stats_write_methods(out, atoms, attributionDecl, supportQ);
- write_native_stats_write_non_chained_methods(out, atoms, attributionDecl);
-
- // Print footer
- fprintf(out, "\n");
- write_closing_namespace(out, cppNamespace);
-
- return 0;
-}
-
-int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "#pragma once\n");
- fprintf(out, "\n");
- fprintf(out, "#include <stdint.h>\n");
- fprintf(out, "#include <vector>\n");
- fprintf(out, "#include <map>\n");
- fprintf(out, "#include <set>\n");
- fprintf(out, "\n");
-
- write_namespace(out, cppNamespace);
- fprintf(out, "\n");
- fprintf(out, "/*\n");
- fprintf(out, " * API For logging statistics events.\n");
- fprintf(out, " */\n");
- fprintf(out, "\n");
-
- write_native_atom_constants(out, atoms, attributionDecl);
-
- // Print constants for the enum values.
- fprintf(out, "//\n");
- fprintf(out, "// Constants for enum values\n");
- fprintf(out, "//\n\n");
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin();
- field != (*atomIt)->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ENUM) {
- fprintf(out, "// Values for %s.%s\n", (*atomIt)->message.c_str(),
- field->name.c_str());
- for (map<int, string>::const_iterator value = field->enumValues.begin();
- value != field->enumValues.end(); value++) {
- fprintf(out, "const int32_t %s__%s__%s = %d;\n",
- make_constant_name((*atomIt)->message).c_str(),
- make_constant_name(field->name).c_str(),
- make_constant_name(value->second).c_str(), value->first);
- }
- fprintf(out, "\n");
- }
- }
- }
-
- write_native_annotation_constants(out);
-
- fprintf(out, "struct BytesField {\n");
- fprintf(out,
- " BytesField(char const* array, size_t len) : arg(array), "
- "arg_length(len) {}\n");
- fprintf(out, " char const* arg;\n");
- fprintf(out, " size_t arg_length;\n");
- fprintf(out, "};\n");
- fprintf(out, "\n");
-
- // Print write methods
- fprintf(out, "//\n");
- fprintf(out, "// Write methods\n");
- fprintf(out, "//\n");
- write_native_method_header(out, "int stats_write", atoms.signatureInfoMap, attributionDecl);
-
- fprintf(out, "//\n");
- fprintf(out, "// Write flattened methods\n");
- fprintf(out, "//\n");
- write_native_method_header(out, "int stats_write_non_chained", atoms.nonChainedSignatureInfoMap,
- attributionDecl);
-
- fprintf(out, "\n");
- write_closing_namespace(out, cppNamespace);
-
- return 0;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/native_writer.h b/tools/stats_log_api_gen/native_writer.h
deleted file mode 100644
index 264d4db29fc9..000000000000
--- a/tools/stats_log_api_gen/native_writer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace, const string& importHeader,
- const bool supportQ);
-
-int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
- const string& cppNamespace);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
deleted file mode 100644
index aaa488e44fee..000000000000
--- a/tools/stats_log_api_gen/test.proto
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-import "frameworks/base/cmds/statsd/src/atoms.proto";
-import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
-
-package android.stats_log_api_gen;
-
-message IntAtom {
- optional int32 field1 = 1;
-}
-
-message AnotherIntAtom {
- optional int32 field1 = 1;
-}
-
-message OutOfOrderAtom {
- optional int32 field2 = 2;
- optional int32 field1 = 1;
-}
-
-enum AnEnum {
- VALUE0 = 0;
- VALUE1 = 1;
-}
-
-message AllTypesAtom {
- repeated android.os.statsd.AttributionNode attribution_chain = 1;
- optional float float_field = 2;
- optional int64 int64_field = 3;
- optional uint64 uint64_field = 4;
- optional int32 int32_field = 5;
- optional fixed64 fixed64_field = 6;
- optional fixed32 fixed32_field = 7;
- optional bool bool_field = 8;
- optional string string_field = 9;
- optional uint32 uint32_field = 10;
- optional AnEnum enum_field = 11;
- optional sfixed32 sfixed32_field = 12;
- optional sfixed64 sfixed64_field = 13;
- optional sint32 sint32_field = 14;
- optional sint64 sint64_field = 15;
-}
-
-message Event {
- oneof event {
- OutOfOrderAtom out_of_order_atom = 2;
- IntAtom int_atom = 1;
- AnotherIntAtom another_int_atom = 3;
- AllTypesAtom all_types_atom = 4;
- }
-}
-
-message BadTypesAtom {
- optional IntAtom bad_int_atom = 1;
- optional bytes bad_bytes = 2;
- repeated int32 repeated_field = 3;
- optional double double_field = 4;
-}
-
-message BadTypesEvent {
- oneof event {
- BadTypesAtom bad_types_atom = 1;
- }
-}
-
-message BadSkippedFieldSingleAtom {
- optional int32 field2 = 2;
-}
-
-message BadSkippedFieldSingle {
- oneof event {
- BadSkippedFieldSingleAtom bad = 1;
- }
-}
-
-message BadSkippedFieldMultipleAtom {
- optional int32 field1 = 1;
- optional int32 field3 = 3;
- optional int32 field5 = 5;
-}
-
-message BadSkippedFieldMultiple {
- oneof event {
- BadSkippedFieldMultipleAtom bad = 1;
- }
-}
-
-message BadAttributionNodePositionAtom {
- optional int32 field1 = 1;
- repeated android.os.statsd.AttributionNode attribution = 2;
-}
-
-message BadAttributionNodePosition {
- oneof event { BadAttributionNodePositionAtom bad = 1; }
-}
-
-message GoodEventWithBinaryFieldAtom {
- oneof event { GoodBinaryFieldAtom field1 = 1; }
-}
-
-message ComplexField {
- optional string str = 1;
-}
-
-message GoodBinaryFieldAtom {
- optional int32 field1 = 1;
- optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
-}
-
-message BadEventWithBinaryFieldAtom {
- oneof event { BadBinaryFieldAtom field1 = 1; }
-}
-
-message BadBinaryFieldAtom {
- optional int32 field1 = 1;
- optional ComplexField bf = 2;
-}
-
-message BadStateAtoms {
- oneof event {
- BadStateAtom1 bad1 = 1;
- BadStateAtom2 bad2 = 2;
- BadStateAtom3 bad3 = 3;
- }
-}
-
-message GoodStateAtoms {
- oneof event {
- GoodStateAtom1 good1 = 1;
- GoodStateAtom2 good2 = 2;
- }
-}
-
-// The atom has only primary field but no exclusive state field.
-message BadStateAtom1 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
-}
-
-// Only primative types can be annotated.
-message BadStateAtom2 {
- repeated android.os.statsd.AttributionNode attribution = 1
- [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-// Having 2 exclusive state field in the atom means the atom is badly designed.
-// E.g., putting bluetooth state and wifi state in the same atom.
-message BadStateAtom3 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
- optional int32 state2 = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-message GoodStateAtom1 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-// Atoms can have exclusive state field, but no primary field. That means
-// the state is globally exclusive (e.g., DisplayState).
-message GoodStateAtom2 {
- optional int32 uid = 1;
- optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-// We can have more than one primary fields. That means their combination is a
-// primary key.
-message GoodStateAtom3 {
- optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 tid = 2 [(android.os.statsd.state_field_option).primary_field = true];
- optional int32 state = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-message ModuleOneAtom {
- optional int32 field = 1 [(android.os.statsd.is_uid) = true];
-}
-
-message ModuleTwoAtom {
- optional int32 field = 1;
-}
-
-message ModuleOneAndTwoAtom {
- optional int32 field = 1 [(android.os.statsd.state_field_option).exclusive_state = true];
-}
-
-message NoModuleAtom {
- optional string field = 1;
-}
-
-message ModuleAtoms {
- oneof event {
- ModuleOneAtom module_one_atom = 1 [(android.os.statsd.module) = "module1"];
- ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.module) = "module2"];
- ModuleOneAndTwoAtom module_one_and_two_atom = 3 [
- (android.os.statsd.module) = "module1", (android.os.statsd.module) = "module2"
- ];
- NoModuleAtom no_module_atom = 4;
- }
-}
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
deleted file mode 100644
index dbae58889333..000000000000
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright (C) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "Collation.h"
-#include "frameworks/base/tools/stats_log_api_gen/test.pb.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using std::map;
-using std::set;
-using std::vector;
-
-/**
- * Return whether the map contains a vector of the elements provided.
- */
-static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) {
- va_list args;
- vector<java_type_t> v;
-
- va_start(args, count);
- for (int i = 0; i < count; i++) {
- v.push_back((java_type_t)va_arg(args, int));
- }
- va_end(args);
-
- return s.find(v) != s.end();
-}
-
-/**
- * Expect that the provided map contains the elements provided.
- */
-#define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...) \
- do { \
- int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int); \
- EXPECT_TRUE(map_contains_vector(s, count, __VA_ARGS__)); \
- } while (0)
-
-/** Expects that the provided atom has no enum values for any field. */
-#define EXPECT_NO_ENUM_FIELD(atom) \
- do { \
- for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
- field != atom->fields.end(); field++) { \
- EXPECT_TRUE(field->enumValues.empty()); \
- } \
- } while (0)
-
-/** Expects that exactly one specific field has expected enum values. */
-#define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \
- do { \
- for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
- field != atom->fields.end(); field++) { \
- if (field->name == field_name) { \
- EXPECT_EQ(field->enumValues, values); \
- } else { \
- EXPECT_TRUE(field->enumValues.empty()); \
- } \
- } \
- } while (0)
-
-/**
- * Test a correct collation, with all the types.
- */
-TEST(CollationTest, CollateStats) {
- Atoms atoms;
- int errorCount = collate_atoms(Event::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(0, errorCount);
- EXPECT_EQ(3ul, atoms.signatureInfoMap.size());
-
- // IntAtom, AnotherIntAtom
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
-
- // OutOfOrderAtom
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
-
- // AllTypesAtom
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap,
- JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain
- JAVA_TYPE_FLOAT, // float
- JAVA_TYPE_LONG, // int64
- JAVA_TYPE_LONG, // uint64
- JAVA_TYPE_INT, // int32
- JAVA_TYPE_LONG, // fixed64
- JAVA_TYPE_INT, // fixed32
- JAVA_TYPE_BOOLEAN, // bool
- JAVA_TYPE_STRING, // string
- JAVA_TYPE_INT, // uint32
- JAVA_TYPE_INT, // AnEnum
- JAVA_TYPE_INT, // sfixed32
- JAVA_TYPE_LONG, // sfixed64
- JAVA_TYPE_INT, // sint32
- JAVA_TYPE_LONG // sint64
- );
-
- EXPECT_EQ(4ul, atoms.decls.size());
-
- AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
- EXPECT_EQ(1, (*atomIt)->code);
- EXPECT_EQ("int_atom", (*atomIt)->name);
- EXPECT_EQ("IntAtom", (*atomIt)->message);
- EXPECT_NO_ENUM_FIELD((*atomIt));
- atomIt++;
-
- EXPECT_EQ(2, (*atomIt)->code);
- EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
- EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
- EXPECT_NO_ENUM_FIELD((*atomIt));
- atomIt++;
-
- EXPECT_EQ(3, (*atomIt)->code);
- EXPECT_EQ("another_int_atom", (*atomIt)->name);
- EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
- EXPECT_NO_ENUM_FIELD((*atomIt));
- atomIt++;
-
- EXPECT_EQ(4, (*atomIt)->code);
- EXPECT_EQ("all_types_atom", (*atomIt)->name);
- EXPECT_EQ("AllTypesAtom", (*atomIt)->message);
- map<int, string> enumValues;
- enumValues[0] = "VALUE0";
- enumValues[1] = "VALUE1";
- EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues);
- atomIt++;
-
- EXPECT_EQ(atoms.decls.end(), atomIt);
-}
-
-/**
- * Test that event class that contains stuff other than the atoms is rejected.
- */
-TEST(CollationTest, NonMessageTypeFails) {
- Atoms atoms;
- int errorCount = collate_atoms(IntAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(1, errorCount);
-}
-
-/**
- * Test that atoms that have non-primitive types or repeated fields are
- * rejected.
- */
-TEST(CollationTest, FailOnBadTypes) {
- Atoms atoms;
- int errorCount = collate_atoms(BadTypesEvent::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(4, errorCount);
-}
-
-/**
- * Test that atoms that skip field numbers (in the first position) are rejected.
- */
-TEST(CollationTest, FailOnSkippedFieldsSingle) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadSkippedFieldSingle::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(1, errorCount);
-}
-
-/**
- * Test that atoms that skip field numbers (not in the first position, and
- * multiple times) are rejected.
- */
-TEST(CollationTest, FailOnSkippedFieldsMultiple) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadSkippedFieldMultiple::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(2, errorCount);
-}
-
-/**
- * Test that atoms that have an attribution chain not in the first position are
- * rejected.
- */
-TEST(CollationTest, FailBadAttributionNodePosition) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadAttributionNodePosition::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(1, errorCount);
-}
-
-TEST(CollationTest, FailOnBadStateAtomOptions) {
- Atoms atoms;
- int errorCount = collate_atoms(BadStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
-
- EXPECT_EQ(3, errorCount);
-}
-
-TEST(CollationTest, PassOnGoodStateAtomOptions) {
- Atoms atoms;
- int errorCount = collate_atoms(GoodStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(0, errorCount);
-}
-
-TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
- Atoms atoms;
- int errorCount =
- collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(0, errorCount);
-}
-
-TEST(CollationTest, FailOnBadBinaryFieldAtom) {
- Atoms atoms;
- int errorCount =
- collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_TRUE(errorCount > 0);
-}
-
-TEST(CollationTest, PassOnLogFromModuleAtom) {
- Atoms atoms;
- int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 4ul);
-}
-
-TEST(CollationTest, RecognizeModuleAtom) {
- Atoms atoms;
- int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 4ul);
- EXPECT_EQ(atoms.signatureInfoMap.size(), 2u);
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING);
-
- SignatureInfoMap::const_iterator signatureInfoMapIt;
- const vector<java_type_t>* signature;
- const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
- const AtomDeclSet* atomDeclSet;
- AtomDeclSet::const_iterator atomDeclSetIt;
- AtomDecl* atomDecl;
- FieldNumberToAnnotations* fieldNumberToAnnotations;
- FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
- const AnnotationSet* annotationSet;
- AnnotationSet::const_iterator annotationSetIt;
- Annotation* annotation;
-
- signatureInfoMapIt = atoms.signatureInfoMap.begin();
- signature = &(signatureInfoMapIt->first);
- fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
- EXPECT_EQ(1ul, signature->size());
- EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
- EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
- fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
- EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
- atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
- EXPECT_EQ(2ul, atomDeclSet->size());
- atomDeclSetIt = atomDeclSet->begin();
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(1, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
- EXPECT_EQ(1, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-
- atomDeclSetIt++;
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(3, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
- EXPECT_EQ(3, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-
- signatureInfoMapIt++;
- signature = &signatureInfoMapIt->first;
- fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
- EXPECT_EQ(1ul, signature->size());
- EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0));
- EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size());
-}
-
-TEST(CollationTest, RecognizeModule1Atom) {
- Atoms atoms;
- const string moduleName = "module1";
- int errorCount = collate_atoms(ModuleAtoms::descriptor(), moduleName, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 2ul);
- EXPECT_EQ(atoms.signatureInfoMap.size(), 1u);
- EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
-
- SignatureInfoMap::const_iterator signatureInfoMapIt;
- const vector<java_type_t>* signature;
- const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
- FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
- const AtomDeclSet* atomDeclSet;
- AtomDeclSet::const_iterator atomDeclSetIt;
- AtomDecl* atomDecl;
- FieldNumberToAnnotations* fieldNumberToAnnotations;
- FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
- const AnnotationSet* annotationSet;
- AnnotationSet::const_iterator annotationSetIt;
- Annotation* annotation;
-
- signatureInfoMapIt = atoms.signatureInfoMap.begin();
- signature = &(signatureInfoMapIt->first);
- fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
- EXPECT_EQ(1ul, signature->size());
- EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
- EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
- fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
- EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
- atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
- EXPECT_EQ(2ul, atomDeclSet->size());
- atomDeclSetIt = atomDeclSet->begin();
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(1, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
- EXPECT_EQ(1, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-
- atomDeclSetIt++;
- atomDecl = atomDeclSetIt->get();
- EXPECT_EQ(3, atomDecl->code);
- fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
- fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
- EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
- annotationSet = &fieldNumberToAnnotationsIt->second;
- EXPECT_EQ(1ul, annotationSet->size());
- annotationSetIt = annotationSet->begin();
- annotation = annotationSetIt->get();
- EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
- EXPECT_EQ(3, annotation->atomId);
- EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
- EXPECT_TRUE(annotation->value.boolValue);
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
deleted file mode 100644
index abb89133e58e..000000000000
--- a/tools/stats_log_api_gen/utils.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "utils.h"
-
-#include "android-base/strings.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static void build_non_chained_decl_map(const Atoms& atoms,
- std::map<int, AtomDeclSet::const_iterator>* decl_map) {
- for (AtomDeclSet::const_iterator atomIt = atoms.non_chained_decls.begin();
- atomIt != atoms.non_chained_decls.end(); atomIt++) {
- decl_map->insert(std::make_pair((*atomIt)->code, atomIt));
- }
-}
-
-/**
- * Turn lower and camel case into upper case with underscores.
- */
-string make_constant_name(const string& str) {
- string result;
- const int N = str.size();
- bool underscore_next = false;
- for (int i = 0; i < N; i++) {
- char c = str[i];
- if (c >= 'A' && c <= 'Z') {
- if (underscore_next) {
- result += '_';
- underscore_next = false;
- }
- } else if (c >= 'a' && c <= 'z') {
- c = 'A' + c - 'a';
- underscore_next = true;
- } else if (c == '_') {
- underscore_next = false;
- }
- result += c;
- }
- return result;
-}
-
-const char* cpp_type_name(java_type_t type) {
- switch (type) {
- case JAVA_TYPE_BOOLEAN:
- return "bool";
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- return "int32_t";
- case JAVA_TYPE_LONG:
- return "int64_t";
- case JAVA_TYPE_FLOAT:
- return "float";
- case JAVA_TYPE_DOUBLE:
- return "double";
- case JAVA_TYPE_STRING:
- return "char const*";
- case JAVA_TYPE_BYTE_ARRAY:
- return "const BytesField&";
- default:
- return "UNKNOWN";
- }
-}
-
-const char* java_type_name(java_type_t type) {
- switch (type) {
- case JAVA_TYPE_BOOLEAN:
- return "boolean";
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- return "int";
- case JAVA_TYPE_LONG:
- return "long";
- case JAVA_TYPE_FLOAT:
- return "float";
- case JAVA_TYPE_DOUBLE:
- return "double";
- case JAVA_TYPE_STRING:
- return "java.lang.String";
- case JAVA_TYPE_BYTE_ARRAY:
- return "byte[]";
- default:
- return "UNKNOWN";
- }
-}
-
-// Native
-// Writes namespaces for the cpp and header files, returning the number of
-// namespaces written.
-void write_namespace(FILE* out, const string& cppNamespaces) {
- vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
- for (string cppNamespace : cppNamespaceVec) {
- fprintf(out, "namespace %s {\n", cppNamespace.c_str());
- }
-}
-
-// Writes namespace closing brackets for cpp and header files.
-void write_closing_namespace(FILE* out, const string& cppNamespaces) {
- vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
- for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) {
- fprintf(out, "} // namespace %s\n", it->c_str());
- }
-}
-
-static void write_cpp_usage(FILE* out, const string& method_name, const string& atom_code_name,
- const shared_ptr<AtomDecl> atom, const AtomDecl& attributionDecl) {
- fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), atom_code_name.c_str());
-
- for (vector<AtomField>::const_iterator field = atom->fields.begin();
- field != atom->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType),
- chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType), chainField.name.c_str(),
- chainField.name.c_str());
- }
- }
- } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out,
- ", const std::map<int, int32_t>& %s_int"
- ", const std::map<int, int64_t>& %s_long"
- ", const std::map<int, char const*>& %s_str"
- ", const std::map<int, float>& %s_float",
- field->name.c_str(), field->name.c_str(), field->name.c_str(),
- field->name.c_str());
- } else {
- fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str());
- }
- }
- fprintf(out, ");\n");
-}
-
-void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl) {
- fprintf(out, "/**\n");
- fprintf(out, " * Constants for atom codes.\n");
- fprintf(out, " */\n");
- fprintf(out, "enum {\n");
-
- std::map<int, AtomDeclSet::const_iterator> atom_code_to_non_chained_decl_map;
- build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map);
-
- size_t i = 0;
- // Print atom constants
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- string constant = make_constant_name((*atomIt)->name);
- fprintf(out, "\n");
- fprintf(out, " /**\n");
- fprintf(out, " * %s %s\n", (*atomIt)->message.c_str(), (*atomIt)->name.c_str());
- write_cpp_usage(out, "stats_write", constant, *atomIt, attributionDecl);
-
- auto non_chained_decl = atom_code_to_non_chained_decl_map.find((*atomIt)->code);
- if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
- write_cpp_usage(out, "stats_write_non_chained", constant, *non_chained_decl->second,
- attributionDecl);
- }
- fprintf(out, " */\n");
- char const* const comma = (i == atoms.decls.size() - 1) ? "" : ",";
- fprintf(out, " %s = %d%s\n", constant.c_str(), (*atomIt)->code, comma);
- i++;
- }
- fprintf(out, "\n");
- fprintf(out, "};\n");
- fprintf(out, "\n");
-}
-
-void write_native_method_signature(FILE* out, const string& methodName,
- const vector<java_type_t>& signature,
- const AtomDecl& attributionDecl, const string& closer) {
- fprintf(out, "%s(int32_t code", methodName.c_str());
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType),
- chainField.name.c_str());
- } else {
- fprintf(out, ", const %s* %s, size_t %s_length",
- cpp_type_name(chainField.javaType), chainField.name.c_str(),
- chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out,
- ", const std::map<int, int32_t>& arg%d_1, "
- "const std::map<int, int64_t>& arg%d_2, "
- "const std::map<int, char const*>& arg%d_3, "
- "const std::map<int, float>& arg%d_4",
- argIndex, argIndex, argIndex, argIndex);
- } else {
- fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ")%s\n", closer.c_str());
-}
-
-void write_native_method_call(FILE* out, const string& methodName,
- const vector<java_type_t>& signature, const AtomDecl& attributionDecl,
- int argIndex) {
- fprintf(out, "%s(code", methodName.c_str());
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", %s", chainField.name.c_str());
- } else {
- fprintf(out, ", %s, %s_length", chainField.name.c_str(),
- chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex, argIndex, argIndex,
- argIndex);
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
-}
-
-// Java
-void write_java_atom_codes(FILE* out, const Atoms& atoms) {
- fprintf(out, " // Constants for atom codes.\n");
-
- std::map<int, AtomDeclSet::const_iterator> atom_code_to_non_chained_decl_map;
- build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map);
-
- // Print constants for the atom codes.
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- string constant = make_constant_name((*atomIt)->name);
- fprintf(out, "\n");
- fprintf(out, " /**\n");
- fprintf(out, " * %s %s<br>\n", (*atomIt)->message.c_str(), (*atomIt)->name.c_str());
- write_java_usage(out, "write", constant, **atomIt);
- auto non_chained_decl = atom_code_to_non_chained_decl_map.find((*atomIt)->code);
- if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
- write_java_usage(out, "write_non_chained", constant, **(non_chained_decl->second));
- }
- fprintf(out, " */\n");
- fprintf(out, " public static final int %s = %d;\n", constant.c_str(), (*atomIt)->code);
- }
- fprintf(out, "\n");
-}
-
-void write_java_enum_values(FILE* out, const Atoms& atoms) {
- fprintf(out, " // Constants for enum values.\n\n");
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin();
- field != (*atomIt)->fields.end(); field++) {
- if (field->javaType == JAVA_TYPE_ENUM) {
- fprintf(out, " // Values for %s.%s\n", (*atomIt)->message.c_str(),
- field->name.c_str());
- for (map<int, string>::const_iterator value = field->enumValues.begin();
- value != field->enumValues.end(); value++) {
- fprintf(out, " public static final int %s__%s__%s = %d;\n",
- make_constant_name((*atomIt)->message).c_str(),
- make_constant_name(field->name).c_str(),
- make_constant_name(value->second).c_str(), value->first);
- }
- fprintf(out, "\n");
- }
- }
- }
-}
-
-void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name,
- const AtomDecl& atom) {
- fprintf(out, " * Usage: StatsLog.%s(StatsLog.%s", method_name.c_str(),
- atom_code_name.c_str());
- for (vector<AtomField>::const_iterator field = atom.fields.begin(); field != atom.fields.end();
- field++) {
- if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- fprintf(out, ", android.os.WorkSource workSource");
- } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> value_map");
- } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out, ", byte[] %s", field->name.c_str());
- } else {
- fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str());
- }
- }
- fprintf(out, ");<br>\n");
-}
-
-int write_java_non_chained_methods(FILE* out, const SignatureInfoMap& signatureInfoMap) {
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- // Print method signature.
- fprintf(out, " public static void write_non_chained(int code");
- vector<java_type_t> signature = signatureInfoMapIt->first;
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- fprintf(stderr, "Non chained signatures should not have attribution chains.\n");
- return 1;
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(stderr, "Module logging does not yet support key value pair.\n");
- return 1;
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- fprintf(out, " write(code");
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- // First two args are uid and tag of attribution chain.
- if (argIndex == 1) {
- fprintf(out, ", new int[] {arg%d}", argIndex);
- } else if (argIndex == 2) {
- fprintf(out, ", new java.lang.String[] {arg%d}", argIndex);
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n");
- fprintf(out, "\n");
- }
- return 0;
-}
-
-int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureInfoMap) {
- fprintf(out, " // WorkSource methods.\n");
- for (auto signatureInfoMapIt = signatureInfoMap.begin();
- signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
- vector<java_type_t> signature = signatureInfoMapIt->first;
- // Determine if there is Attribution in this signature.
- int attributionArg = -1;
- int argIndexMax = 0;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- argIndexMax++;
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- if (attributionArg > -1) {
- fprintf(stderr, "An atom contains multiple AttributionNode fields.\n");
- fprintf(stderr, "This is not supported. Aborting WorkSource method writing.\n");
- fprintf(out,
- "\n// Invalid for WorkSource: more than one attribution "
- "chain.\n");
- return 1;
- }
- attributionArg = argIndexMax;
- }
- }
- if (attributionArg < 0) {
- continue;
- }
-
- fprintf(out, "\n");
- // Method header (signature)
- fprintf(out, " public static void write(int code");
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
- arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- fprintf(out, ", android.os.WorkSource ws");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ") {\n");
-
- // write_non_chained() component. TODO: Remove when flat uids are no longer
- // needed.
- fprintf(out, " for (int i = 0; i < ws.size(); ++i) {\n");
- fprintf(out, " write_non_chained(code");
- for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
- if (argIndex == attributionArg) {
- fprintf(out, ", ws.getUid(i), ws.getPackageName(i)");
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n"); // close for-loop
-
- // write() component.
- fprintf(out,
- " java.util.List<android.os.WorkSource.WorkChain> workChains = "
- "ws.getWorkChains();\n");
- fprintf(out, " if (workChains != null) {\n");
- fprintf(out,
- " for (android.os.WorkSource.WorkChain wc : workChains) "
- "{\n");
- fprintf(out, " write(code");
- for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
- if (argIndex == attributionArg) {
- fprintf(out, ", wc.getUids(), wc.getTags()");
- } else {
- fprintf(out, ", arg%d", argIndex);
- }
- }
- fprintf(out, ");\n");
- fprintf(out, " }\n"); // close for-loop
- fprintf(out, " }\n"); // close if
- fprintf(out, " }\n"); // close method
- }
- return 0;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
deleted file mode 100644
index 73e0cb838227..000000000000
--- a/tools/stats_log_api_gen/utils.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-const string DEFAULT_CPP_NAMESPACE = "android,util";
-const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
-
-const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
-const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
-const int JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS = 0x04;
-
-const map<AnnotationId, string> ANNOTATION_ID_CONSTANTS = {
- {ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID"},
- {ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP"},
- {ANNOTATION_ID_PRIMARY_FIELD, "ANNOTATION_ID_PRIMARY_FIELD"},
- {ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, "ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID"},
- {ANNOTATION_ID_EXCLUSIVE_STATE, "ANNOTATION_ID_EXCLUSIVE_STATE"},
- {ANNOTATION_ID_TRIGGER_STATE_RESET, "ANNOTATION_ID_TRIGGER_STATE_RESET"},
- {ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED"}};
-
-string make_constant_name(const string& str);
-
-const char* cpp_type_name(java_type_t type);
-
-const char* java_type_name(java_type_t type);
-
-// Common Native helpers
-void write_namespace(FILE* out, const string& cppNamespaces);
-
-void write_closing_namespace(FILE* out, const string& cppNamespaces);
-
-void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl);
-
-void write_native_method_signature(FILE* out, const string& methodName,
- const vector<java_type_t>& signature,
- const AtomDecl& attributionDecl, const string& closer);
-
-void write_native_method_call(FILE* out, const string& methodName,
- const vector<java_type_t>& signature, const AtomDecl& attributionDecl,
- int argIndex = 1);
-
-// Common Java helpers.
-void write_java_atom_codes(FILE* out, const Atoms& atoms);
-
-void write_java_enum_values(FILE* out, const Atoms& atoms);
-
-void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name,
- const AtomDecl& atom);
-
-int write_java_non_chained_methods(FILE* out, const SignatureInfoMap& signatureInfoMap);
-
-int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureInfoMap);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index e253ae25659e..0568696559e4 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -114,8 +114,6 @@ rule fi.iki.elonen.** com.android.wifi.x.@0
## used by both framework-wifi and service-wifi ##
rule android.content.pm.BaseParceledListSlice* com.android.wifi.x.@0
rule android.content.pm.ParceledListSlice* com.android.wifi.x.@0
-rule android.net.util.MacAddressUtils* com.android.wifi.x.@0
-rule android.net.util.nsd.DnsSdTxtRecord* com.android.wifi.x.@0
rule android.os.HandlerExecutor* com.android.wifi.x.@0
rule android.telephony.Annotation* com.android.wifi.x.@0
rule com.android.internal.util.AsyncChannel* com.android.wifi.x.@0
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 7352dae06af9..70885af6c919 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -29,7 +29,6 @@ import android.net.NetworkSpecifier;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.Uri;
-import android.net.util.MacAddressUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,6 +40,7 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.MacAddressUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 90edc4523b7b..e127ea99c716 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -1335,6 +1335,16 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
+ * Initialize the value of the app installed device key and cert flag.
+ *
+ * @param isAppInstalledDeviceKeyAndCert true or false
+ * @hide
+ */
+ public void initIsAppInstalledDeviceKeyAndCert(boolean isAppInstalledDeviceKeyAndCert) {
+ mIsAppInstalledDeviceKeyAndCert = isAppInstalledDeviceKeyAndCert;
+ }
+
+ /**
* Check if CA certificate was installed by an app, or manually (not by an app). If true,
* CA certificate will be removed from key storage when this network is removed. If not,
* then certificates and keys remain persistent until the user manually removes them.
@@ -1348,6 +1358,16 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
+ * Initialize the value of the app installed root CA cert flag.
+ *
+ * @param isAppInstalledCaCert true or false
+ * @hide
+ */
+ public void initIsAppInstalledCaCert(boolean isAppInstalledCaCert) {
+ mIsAppInstalledCaCert = isAppInstalledCaCert;
+ }
+
+ /**
* Set the OCSP type.
* @param ocsp is one of {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS},
* {@link #OCSP_REQUIRE_CERT_STATUS} or
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
index dad431c1ca2c..e2f40cfa058c 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
@@ -17,10 +17,11 @@
package android.net.wifi.p2p.nsd;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.nsd.DnsSdTxtRecord;
import android.os.Build;
import android.text.TextUtils;
+import com.android.net.module.util.DnsSdTxtRecord;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index cb9693d3869e..b3979c7c6b62 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -34,6 +34,7 @@ android_test {
"guava",
"mockito-target-minus-junit4",
"net-tests-utils",
+ "net-utils-framework-common",
"frameworks-base-testutils",
"truth-prebuilt",
],
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index 62220a6237b1..d4b20519215c 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -33,13 +33,14 @@ import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
-import android.net.util.MacAddressUtils;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
+import com.android.net.module.util.MacAddressUtils;
+
import org.junit.Before;
import org.junit.Test;