Merge history of cts/hostsidetests/statsd
BUG: 167962588
Test: TH
Merged-In: If9619cb6ab2ae9c83cbfd0fcc1a6a19b9967c136
Change-Id: I587aefd8ab26a052b428e0aceeb4195776f2535e
Exempt-From-Owner-Approval: Code cleanup
diff --git a/hostsidetests/statsd/Android.bp b/hostsidetests/statsd/Android.bp
deleted file mode 100644
index dccd5be..0000000
--- a/hostsidetests/statsd/Android.bp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2014 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT 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_test_host {
- name: "CtsStatsdHostTestCases",
-
- srcs: ["src/**/*.java"],
-
- // tag this module as a cts test artifact
- test_suites: [
- "cts",
- "general-tests",
- "mts",
- ],
-
- libs: [
- "compatibility-host-util",
- "cts-tradefed",
- "host-libprotobuf-java-full",
- "platformprotos",
- "tradefed",
- "truth-prebuilt",
- ],
- static_libs: [
- "core_cts_test_resources",
- "perfetto_config-full",
- ],
- data: [
- "**/*.pbtxt",
- ":CtsStatsdApp",
- ":CtsStatsdEmptyApp",
- ":CtsStatsdEmptySplitApp",
- ],
-}
diff --git a/hostsidetests/statsd/AndroidTest.xml b/hostsidetests/statsd/AndroidTest.xml
deleted file mode 100644
index 451ad73..0000000
--- a/hostsidetests/statsd/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Config for CTS Statsd host test cases">
- <option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="statsd" />
- <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
- <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
- <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
- <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
- <option name="jar" value="CtsStatsdHostTestCases.jar" />
- </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/hostsidetests/statsd/BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt b/hostsidetests/statsd/BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt
deleted file mode 100644
index 4bad614..0000000
--- a/hostsidetests/statsd/BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt
+++ /dev/null
@@ -1,24 +0,0 @@
-id: 8835981461554930288
-count_metric {
- id: 543749824321007836
- what: 3909523419673092535
- bucket: ONE_DAY
-}
-atom_matcher {
- id: 3909523419673092535
- simple_atom_matcher {
- atom_id: 98
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt b/hostsidetests/statsd/BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt
deleted file mode 100644
index 4f13941..0000000
--- a/hostsidetests/statsd/BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt
+++ /dev/null
@@ -1,36 +0,0 @@
-id: 8835981461554930288
-count_metric {
- id: 543749824321007836
- what: 3909523419673092535
- dimensions_in_what {
- field: 100
- child {
- field: 1
- },
- child {
- field: 2
- },
- child {
- field: 3
- }
- }
- bucket: ONE_DAY
-}
-atom_matcher {
- id: 3909523419673092535
- simple_atom_matcher {
- atom_id: 100
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/BATTERYSTATS_SERVICE_START_COUNT.pbtxt b/hostsidetests/statsd/BATTERYSTATS_SERVICE_START_COUNT.pbtxt
deleted file mode 100644
index 87afb2d..0000000
--- a/hostsidetests/statsd/BATTERYSTATS_SERVICE_START_COUNT.pbtxt
+++ /dev/null
@@ -1,40 +0,0 @@
-id: 8835981461554930288
-count_metric {
- id: 543749824321007836
- what: 3909523419673092535
- dimensions_in_what {
- field: 99
- child {
- field: 1
- },
- child {
- field: 2
- },
- child {
- field: 3
- }
- }
- bucket: ONE_DAY
-}
-atom_matcher {
- id: 3909523419673092535
- simple_atom_matcher {
- atom_id: 99
- field_value_matcher: {
- eq_int: 1
- field: 4
- }
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/OWNERS b/hostsidetests/statsd/OWNERS
deleted file mode 100644
index 5e51cc4..0000000
--- a/hostsidetests/statsd/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-# Bug component: 366902
-jeffreyhuang@google.com
-muhammadq@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
diff --git a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_CACHED_EMPTY_DURATION.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_CACHED_EMPTY_DURATION.pbtxt
deleted file mode 100644
index 6655599..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_CACHED_EMPTY_DURATION.pbtxt
+++ /dev/null
@@ -1,70 +0,0 @@
-# DURATION_PROCESS_STATE_IN_CACHED_EMPTY_PER_PROC_NAME_PACKAGE_NAME_VERSION
-id: -6109199674574072698
-duration_metric {
- id: -7871805656933174442
- what: -4194528603977557137
- aggregation_type: SUM
- dimensions_in_what {
- field: 3
- child {
- field: 2
- }
- child {
- field: 3
- }
- child {
- field: 5
- }
- }
- bucket: ONE_MINUTE
-}
-# PROC_STATE NOT IN CACHED_EMPTY
-atom_matcher {
- id: -2354884036751182872
- combination {
- operation: NOT
- matcher: -7794766650955623092
- }
-}
-# PROC_STATE IN CACHED_EMPTY
-atom_matcher {
- id: -7794766650955623092
- simple_atom_matcher {
- atom_id: 3
- field_value_matcher {
- field: 4
- eq_int: 1018
- }
- }
-}
-predicate {
- id: -4194528603977557137
- simple_predicate {
- start: -7794766650955623092
- stop: -2354884036751182872
- count_nesting: false
- dimensions {
- field: 3
- child {
- field: 2
- }
- child {
- field: 3
- }
- child {
- field: 5
- }
- }
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt
deleted file mode 100644
index 7f071e3..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt
+++ /dev/null
@@ -1,45 +0,0 @@
-# VALUE_MAX_PSS_PER_PROC_NAME_PACKAGE_NAME_VERSION
-id: -6109199674574072698
-value_metric {
- id: 1867856787681329178
- what: -3480158308153459853
- value_field {
- field: 18
- child {
- field: 4
- }
- }
- dimensions_in_what {
- field: 18
- child {
- field: 2
- }
- child {
- field: 3
- }
- child {
- field: 9
- }
- }
- bucket: ONE_MINUTE
- aggregation_type: MAX
-}
-# PROCESS_MEMORY_STAT_REPORTED
-atom_matcher {
- id: -3480158308153459853
- simple_atom_matcher {
- atom_id: 18
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_TOP_DURATION.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_TOP_DURATION.pbtxt
deleted file mode 100644
index e388d54..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_TOP_DURATION.pbtxt
+++ /dev/null
@@ -1,91 +0,0 @@
-# DURATION_PROCESS_STATE_IN_TOP_PER_PROC_NAME_PACKAGE_NAME_VERSION
-id: -6109199674574072698
-duration_metric {
- id: -1365360216258753370
- what: -8800411078553365796
- aggregation_type: SUM
- dimensions_in_what {
- field: 3
- child {
- field: 2
- }
- child {
- field: 3
- }
- child {
- field: 5
- }
- }
- bucket: ONE_MINUTE
-}
-# PROC_STATE NOT IN TOP
-atom_matcher {
- id: -7829668247086356765
- combination {
- operation: NOT
- matcher: -2987742411590785849
- }
-}
-# PROCESS_STATE TOP
-atom_matcher {
- id: 509484152027467470
- simple_atom_matcher {
- atom_id: 3
- field_value_matcher {
- field: 4
- eq_int: 1002
- }
- }
-}
-# PROCESS_STATE TOP_SLEEPING
-atom_matcher {
- id: -3293304223207806916
- simple_atom_matcher {
- atom_id: 3
- field_value_matcher {
- field: 4
- eq_int: 1011
- }
- }
-}
-# PROC_STATE IN TOP
-atom_matcher {
- id: -2987742411590785849
- combination {
- operation: OR
- matcher: 509484152027467470
- matcher: -3293304223207806916
- }
-}
-predicate {
- id: -8800411078553365796
- simple_predicate {
- start: -2987742411590785849
- stop: -7829668247086356765
- count_nesting: false
- dimensions {
- field: 3
- child {
- field: 2
- }
- child {
- field: 3
- }
- child {
- field: 5
- }
- }
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PULL.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PULL.pbtxt
deleted file mode 100644
index 8444943..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PULL.pbtxt
+++ /dev/null
@@ -1,59 +0,0 @@
-id: 8835981461554930288
-gauge_metric {
- id: 543749824321007836
- what: 3909523419673092535
- gauge_fields_filter {
- include_all: true
- }
- bucket: ONE_DAY
- condition: -377136895
- sampling_type: CONDITION_CHANGE_TO_TRUE
- # Normal user should have <1000
- max_num_gauge_atoms_per_bucket: 2000
-}
-atom_matcher {
- id: 3909523419673092535
- simple_atom_matcher {
- atom_id: 10029
- }
-}
-atom_matcher {
- id: -1651300237
- simple_atom_matcher {
- atom_id: 47
- field_value_matcher {
- field: 2
- eq_int: 1
- }
- }
-}
-atom_matcher {
- id: -1651300236
- simple_atom_matcher {
- atom_id: 47
- field_value_matcher {
- field: 2
- eq_int: 2
- }
- }
-}
-predicate {
- id: -377136895
- simple_predicate {
- start: -1651300237
- stop: -1651300236
- count_nesting: false
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PULL_PKG_PROC.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PULL_PKG_PROC.pbtxt
deleted file mode 100644
index 1effda6..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PULL_PKG_PROC.pbtxt
+++ /dev/null
@@ -1,59 +0,0 @@
-id: 8835981461554930288
-gauge_metric {
- id: 543749824321007836
- what: 3909523419673092535
- gauge_fields_filter {
- include_all: true
- }
- bucket: ONE_DAY
- condition: -377136895
- sampling_type: CONDITION_CHANGE_TO_TRUE
- # Normal user should have <1000
- max_num_gauge_atoms_per_bucket: 2000
-}
-atom_matcher {
- id: 3909523419673092535
- simple_atom_matcher {
- atom_id: 10034
- }
-}
-atom_matcher {
- id: -1651300237
- simple_atom_matcher {
- atom_id: 47
- field_value_matcher {
- field: 2
- eq_int: 1
- }
- }
-}
-atom_matcher {
- id: -1651300236
- simple_atom_matcher {
- atom_id: 47
- field_value_matcher {
- field: 2
- eq_int: 2
- }
- }
-}
-predicate {
- id: -377136895
- simple_predicate {
- start: -1651300237
- stop: -1651300236
- count_nesting: false
- }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/apps/emptyapp/Android.bp b/hostsidetests/statsd/apps/emptyapp/Android.bp
deleted file mode 100644
index d01d14d2..0000000
--- a/hostsidetests/statsd/apps/emptyapp/Android.bp
+++ /dev/null
@@ -1,28 +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_helper_app {
- name: "CtsStatsdEmptyApp",
- defaults: ["cts_defaults"],
- sdk_version: "current",
- v4_signature: true,
-}
-
-android_test_helper_app {
- name: "CtsStatsdEmptySplitApp",
- defaults: ["cts_defaults"],
- sdk_version: "current",
- v4_signature: true,
- package_splits: ["pl"],
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml b/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
deleted file mode 100644
index f40d070..0000000
--- a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
+++ /dev/null
@@ -1,22 +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.cts.device.statsd.emptyapp">
- <application android:hasCode="false" android:label="Empty Test App" />
-</manifest>
-
diff --git a/hostsidetests/statsd/apps/statsdapp/Android.bp b/hostsidetests/statsd/apps/statsdapp/Android.bp
deleted file mode 100644
index 6e0ef51..0000000
--- a/hostsidetests/statsd/apps/statsdapp/Android.bp
+++ /dev/null
@@ -1,60 +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.
-
-cc_library_shared {
- name: "liblmkhelper",
- srcs: ["jni/alloc_stress_activity.cpp"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- header_libs: ["jni_headers"],
- shared_libs: ["liblog"],
- stl: "c++_static",
- sdk_version: "current",
-}
-
-android_test_helper_app {
- name: "CtsStatsdApp",
- defaults: ["cts_defaults"],
- platform_apis: true,
- min_sdk_version: "24",
- srcs: [
- "src/**/*.java",
- ":statslog-statsd-cts-java-gen",
- ],
- libs: [
- "android.test.runner",
- "junit",
- "org.apache.http.legacy",
- ],
- privileged: true,
- static_libs: [
- "ctstestrunner-axt",
- "compatibility-device-util-axt",
- "androidx.legacy_legacy-support-v4",
- "androidx.test.rules",
- "cts-net-utils",
- "BlobStoreTestUtils"
- ],
- jni_libs: ["liblmkhelper"],
- compile_multilib: "both",
-}
-
-genrule {
- name: "statslog-statsd-cts-java-gen",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --module cts --javaPackage com.android.server.cts.device.statsd --javaClass StatsLogStatsdCts",
- out: ["com/android/server/cts/device/statsd/StatsLogStatsdCts.java"],
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
deleted file mode 100644
index 2b479bd..0000000
--- a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.cts.device.statsd"
- android:versionCode="10" >
- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- <uses-permission android:name="android.permission.BLUETOOTH"/>
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
- <uses-permission android:name="android.permission.CAMERA"/>
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
- <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" />
- <uses-permission android:name="android.permission.DUMP" /> <!-- must be granted via pm grant -->
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.READ_SYNC_STATS" />
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- <uses-permission android:name="android.permission.VIBRATE" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
-
- <application android:label="@string/app_name">
- <uses-library android:name="android.test.runner" />
- <uses-library android:name="org.apache.http.legacy" android:required="false" />
-
- <service android:name=".StatsdCtsBackgroundService" android:exported="true" />
- <activity android:name=".StatsdCtsForegroundActivity" android:exported="true" />
- <service android:name=".StatsdCtsForegroundService"
- android:foregroundServiceType="camera" android:exported="true" />
-
- <activity
- android:name=".VideoPlayerActivity"
- android:label="@string/app_name"
- android:resizeableActivity="true"
- android:supportsPictureInPicture="true"
- android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
- android:launchMode="singleTop" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <activity android:name=".DaveyActivity" android:exported="true" />
- <activity android:name=".HiddenApiUsedActivity" android:exported="true" />
- <activity
- android:name=".ANRActivity"
- android:label="ANR Test Activity"
- android:launchMode="singleInstance"
- android:process=":ANRProcess"
- android:exported="true"
- />
-
- <service android:name=".StatsdAuthenticator"
- android:exported="false">
- <intent-filter>
- <action android:name="android.accounts.AccountAuthenticator" />
- </intent-filter>
-
- <meta-data android:name="android.accounts.AccountAuthenticator"
- android:resource="@xml/authenticator" />
- </service>
- <service android:name="StatsdSyncService"
- android:exported="false" >
- <intent-filter>
- <action android:name="android.content.SyncAdapter" />
- </intent-filter>
- <meta-data android:name="android.content.SyncAdapter"
- android:resource="@xml/syncadapter" />
- </service>
-
- <provider android:name=".StatsdProvider"
- android:authorities="com.android.server.cts.device.statsd.provider" />
-
- <service android:name=".StatsdJobService"
- android:permission="android.permission.BIND_JOB_SERVICE" />
-
- <service android:name=".DummyCallscreeningService"
- android:permission="android.permission.BIND_SCREENING_SERVICE">
- <intent-filter>
- <action android:name="android.telecom.CallScreeningService" />
- </intent-filter>
- </service>
-
- <service android:name=".IsolatedProcessService" android:isolatedProcess="true" />
- </application>
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.server.cts.device.statsd"
- android:label="CTS tests of android.os.statsd stats collection">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>/>
-</manifest>
diff --git a/hostsidetests/statsd/apps/statsdapp/jni/alloc_stress_activity.cpp b/hostsidetests/statsd/apps/statsdapp/jni/alloc_stress_activity.cpp
deleted file mode 100644
index b98a04b..0000000
--- a/hostsidetests/statsd/apps/statsdapp/jni/alloc_stress_activity.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 <algorithm>
-#include <cstring>
-#include <fstream>
-#include <iostream>
-#include <jni.h>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <tuple>
-#include <unistd.h>
-
-#include <android/log.h>
-#define LOG(...) __android_log_write(ANDROID_LOG_INFO, "ALLOC-STRESS", __VA_ARGS__)
-
-using namespace std;
-
-size_t s = 4 * (1 << 20); // 4 MB
-void *gptr;
-extern "C"
-JNIEXPORT void JNICALL
-Java_com_android_server_cts_device_statsd_StatsdCtsBackgroundService_cmain(JNIEnv* , jobject /* this */)
-{
- long long allocCount = 0;
- while (1) {
- char *ptr = (char *)malloc(s);
- memset(ptr, (int)allocCount >> 10, s);
- for (int i = 0; i < s; i += 4096) {
- *((long long *)&ptr[i]) = allocCount + i;
- }
- std::stringstream ss;
- ss << "total alloc: " << allocCount / (1 << 20);
- LOG(ss.str().c_str());
- gptr = ptr;
- allocCount += s;
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml b/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml
deleted file mode 100644
index bf43931..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:custom="http://schemas.android.com/apk/res/com.android.server.cts.device.statsd"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <com.android.server.cts.device.statsd.DaveyView
- android:id="@+id/davey_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- custom:causeDavey="false" />
-</LinearLayout>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_main.xml b/hostsidetests/statsd/apps/statsdapp/res/layout/activity_main.xml
deleted file mode 100644
index a029c80..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_main.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
-
- <FrameLayout
- android:id="@+id/video_frame"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <VideoView
- android:id="@+id/video_player_view"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
- </FrameLayout>
-</RelativeLayout>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/raw/colors_video.mp4 b/hostsidetests/statsd/apps/statsdapp/res/raw/colors_video.mp4
deleted file mode 100644
index 0bec670..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/raw/colors_video.mp4
+++ /dev/null
Binary files differ
diff --git a/hostsidetests/statsd/apps/statsdapp/res/raw/good.mp3 b/hostsidetests/statsd/apps/statsdapp/res/raw/good.mp3
deleted file mode 100644
index d20f772..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/raw/good.mp3
+++ /dev/null
Binary files differ
diff --git a/hostsidetests/statsd/apps/statsdapp/res/values/attrs.xml b/hostsidetests/statsd/apps/statsdapp/res/values/attrs.xml
deleted file mode 100644
index e769146..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/values/attrs.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources>
- <declare-styleable name="DaveyView">
- <attr name="causeDavey" format="boolean" />
- </declare-styleable>
-</resources>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/values/strings.xml b/hostsidetests/statsd/apps/statsdapp/res/values/strings.xml
deleted file mode 100644
index e40d2ac..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/values/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">CTS Statsd Atoms App</string>
-</resources>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/xml/authenticator.xml b/hostsidetests/statsd/apps/statsdapp/res/xml/authenticator.xml
deleted file mode 100644
index 71c73d7..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/xml/authenticator.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
- android:accountType="com.android.cts.statsd"
- android:label="@string/app_name" />
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/xml/syncadapter.xml b/hostsidetests/statsd/apps/statsdapp/res/xml/syncadapter.xml
deleted file mode 100644
index d8cb52e..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/xml/syncadapter.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
- android:contentAuthority= "com.android.server.cts.device.statsd.provider"
- android:accountType="com.android.cts.statsd"
-/>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/ANRActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/ANRActivity.java
deleted file mode 100644
index 78b2d2d..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/ANRActivity.java
+++ /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.
- */
-
-package com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.view.WindowManager;
-
-public class ANRActivity extends Activity {
- private static final String TAG = "ANRActivity";
- private static final String ACTION_ANR = "action_anr";
-
-
- @Override
- public void onCreate(Bundle bundle) {
- super.onCreate(bundle);
-
- registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- while (true) {
- SystemClock.sleep(2);
- }
- }
- }, new IntentFilter(ACTION_ANR));
-
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
- | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
- | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
deleted file mode 100644
index 4eb659c..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ /dev/null
@@ -1,1061 +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.cts.device.statsd;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.AlarmManager;
-import android.app.AppOpsManager;
-import android.app.PendingIntent;
-import android.app.blob.BlobStoreManager;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.le.BluetoothLeScanner;
-import android.bluetooth.le.ScanCallback;
-import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.le.ScanSettings;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.location.GnssStatus;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.media.MediaPlayer;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.cts.util.CtsNetUtils;
-import android.net.wifi.WifiManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.SystemClock;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.StatsEvent;
-import android.util.StatsLog;
-
-import androidx.annotation.NonNull;
-import androidx.test.InstrumentationRegistry;
-
-import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.utils.blob.DummyBlobData;
-
-import com.google.common.io.BaseEncoding;
-
-import org.junit.Test;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiConsumer;
-
-public class AtomTests {
- private static final String TAG = AtomTests.class.getSimpleName();
-
- private static final String MY_PACKAGE_NAME = "com.android.server.cts.device.statsd";
-
- private static final Map<String, Integer> APP_OPS_ENUM_MAP = new ArrayMap<>();
- static {
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_COARSE_LOCATION, 0);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_FINE_LOCATION, 1);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GPS, 2);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_VIBRATE, 3);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CONTACTS, 4);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CONTACTS, 5);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALL_LOG, 6);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALL_LOG, 7);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALENDAR, 8);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALENDAR, 9);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WIFI_SCAN, 10);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_POST_NOTIFICATION, 11);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NEIGHBORING_CELLS, 12);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CALL_PHONE, 13);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_SMS, 14);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SMS, 15);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_SMS, 16);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_EMERGENCY_BROADCAST, 17);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_MMS, 18);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_WAP_PUSH, 19);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SEND_SMS, 20);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_ICC_SMS, 21);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_ICC_SMS, 22);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SETTINGS, 23);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, 24);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS, 25);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CAMERA, 26);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECORD_AUDIO, 27);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PLAY_AUDIO, 28);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CLIPBOARD, 29);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CLIPBOARD, 30);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_MEDIA_BUTTONS, 31);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_AUDIO_FOCUS, 32);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MASTER_VOLUME, 33);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_VOICE_VOLUME, 34);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_RING_VOLUME, 35);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MEDIA_VOLUME, 36);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ALARM_VOLUME, 37);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_NOTIFICATION_VOLUME, 38);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_BLUETOOTH_VOLUME, 39);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WAKE_LOCK, 40);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_LOCATION, 41);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION, 42);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_USAGE_STATS, 43);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MUTE_MICROPHONE, 44);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TOAST_WINDOW, 45);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROJECT_MEDIA, 46);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_VPN, 47);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_WALLPAPER, 48);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_STRUCTURE, 49);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_SCREENSHOT, 50);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_STATE, 51);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ADD_VOICEMAIL, 52);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_SIP, 53);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROCESS_OUTGOING_CALLS, 54);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_FINGERPRINT, 55);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BODY_SENSORS, 56);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CELL_BROADCASTS, 57);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MOCK_LOCATION, 58);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, 59);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE, 60);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TURN_SCREEN_ON, 61);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_ACCOUNTS, 62);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_IN_BACKGROUND, 63);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ACCESSIBILITY_VOLUME, 64);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, 65);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES, 66);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, 67);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INSTANT_APP_START_FOREGROUND, 68);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ANSWER_PHONE_CALLS, 69);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, 70);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, 71);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, 72);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE, 73);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCEPT_HANDOVER, 74);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, 75);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_START_FOREGROUND, 76);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BLUETOOTH_SCAN, 77);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_BIOMETRIC, 78);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVITY_RECOGNITION, 79);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS, 80);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_AUDIO, 81);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_AUDIO, 82);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_VIDEO, 83);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_VIDEO, 84);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_IMAGES, 85);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES, 86);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LEGACY_STORAGE, 87);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY, 88);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, 89);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_MEDIA_LOCATION, 90);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_QUERY_ALL_PACKAGES, 91);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE, 92);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INTERACT_ACROSS_PROFILES, 93);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, 94);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LOADER_USAGE_STATS, 95);
- // Op 96 was deprecated/removed
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, 97);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, 98);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NO_ISOLATED_STORAGE, 99);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PHONE_CALL_CAMERA, 101);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD, 102);
- APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_ONGOING_CALLS, 103);
- }
-
- @Test
- public void testAudioState() {
- // TODO: This should surely be getTargetContext(), here and everywhere, but test first.
- Context context = InstrumentationRegistry.getContext();
- MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.good);
- mediaPlayer.start();
- sleep(2_000);
- mediaPlayer.stop();
- }
-
- @Test
- public void testBleScanOpportunistic() {
- ScanSettings scanSettings = new ScanSettings.Builder()
- .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC).build();
- performBleScan(scanSettings, null,false);
- }
-
- @Test
- public void testBleScanUnoptimized() {
- ScanSettings scanSettings = new ScanSettings.Builder()
- .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
- performBleScan(scanSettings, null, false);
- }
-
- @Test
- public void testBleScanResult() {
- ScanSettings scanSettings = new ScanSettings.Builder()
- .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
- ScanFilter.Builder scanFilter = new ScanFilter.Builder();
- performBleScan(scanSettings, Arrays.asList(scanFilter.build()), true);
- }
-
- @Test
- public void testBleScanInterrupted() throws Exception {
- performBleAction((bluetoothAdapter, bleScanner) -> {
- ScanSettings scanSettings = new ScanSettings.Builder()
- .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
- ScanCallback scanCallback = new ScanCallback() {
- @Override
- public void onScanResult(int callbackType, ScanResult result) {
- Log.v(TAG, "called onScanResult");
- }
- @Override
- public void onScanFailed(int errorCode) {
- Log.v(TAG, "called onScanFailed");
- }
- @Override
- public void onBatchScanResults(List<ScanResult> results) {
- Log.v(TAG, "called onBatchScanResults");
- }
- };
-
- int uid = Process.myUid();
- int whatAtomId = 9_999;
-
- // Change state to State.ON.
- bleScanner.startScan(null, scanSettings, scanCallback);
- sleep(500);
- writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
- writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
- bluetoothAdapter.disable();
- sleep(1500);
-
- // Trigger State.RESET so that new state is State.OFF.
- if (!bluetoothAdapter.enable()) {
- Log.e(TAG, "Could not enable bluetooth to trigger state reset");
- return;
- }
- sleep(3_000); // Wait for Bluetooth to fully turn on.
- writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
- writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
- writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
- });
- }
-
- private static void writeSliceByBleScanStateChangedAtom(int atomId, int firstUid,
- boolean field2, boolean field3,
- boolean field4) {
- final StatsEvent.Builder builder = StatsEvent.newBuilder()
- .setAtomId(atomId)
- .writeAttributionChain(new int[] {firstUid}, new String[] {"tag1"})
- .writeBoolean(field2)
- .writeBoolean(field3)
- .writeBoolean(field4)
- .usePooledBuffer();
-
- StatsLog.write(builder.build());
- }
-
- /**
- * Set up BluetoothLeScanner and perform the action in the callback.
- * Restore Bluetooth to original state afterwards.
- **/
- private static void performBleAction(BiConsumer<BluetoothAdapter, BluetoothLeScanner> actions) {
- BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- if (bluetoothAdapter == null) {
- Log.e(TAG, "Device does not support Bluetooth");
- return;
- }
- boolean bluetoothEnabledByTest = false;
- if (!bluetoothAdapter.isEnabled()) {
- if (!bluetoothAdapter.enable()) {
- Log.e(TAG, "Bluetooth is not enabled");
- return;
- }
- sleep(2_000); // Wait for Bluetooth to fully turn on.
- bluetoothEnabledByTest = true;
- }
- BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
- if (bleScanner == null) {
- Log.e(TAG, "Cannot access BLE scanner");
- return;
- }
-
- actions.accept(bluetoothAdapter, bleScanner);
-
- // Restore adapter state
- if (bluetoothEnabledByTest) {
- bluetoothAdapter.disable();
- }
- }
-
-
- private static void performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult) {
- performBleAction((bluetoothAdapter, bleScanner) -> {
- CountDownLatch resultsLatch = new CountDownLatch(1);
- ScanCallback scanCallback = new ScanCallback() {
- @Override
- public void onScanResult(int callbackType, ScanResult result) {
- Log.v(TAG, "called onScanResult");
- resultsLatch.countDown();
- }
- @Override
- public void onScanFailed(int errorCode) {
- Log.v(TAG, "called onScanFailed");
- }
- @Override
- public void onBatchScanResults(List<ScanResult> results) {
- Log.v(TAG, "called onBatchScanResults");
- resultsLatch.countDown();
- }
- };
-
- bleScanner.startScan(scanFilters, scanSettings, scanCallback);
- if (waitForResult) {
- waitForReceiver(InstrumentationRegistry.getContext(), 59_000, resultsLatch, null);
- } else {
- sleep(2_000);
- }
- bleScanner.stopScan(scanCallback);
- });
- }
-
- @Test
- public void testCameraState() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- CameraManager cam = context.getSystemService(CameraManager.class);
- String[] cameraIds = cam.getCameraIdList();
- if (cameraIds.length == 0) {
- Log.e(TAG, "No camera found on device");
- return;
- }
-
- CountDownLatch latch = new CountDownLatch(1);
- final CameraDevice.StateCallback cb = new CameraDevice.StateCallback() {
- @Override
- public void onOpened(CameraDevice cd) {
- Log.i(TAG, "CameraDevice " + cd.getId() + " opened");
- sleep(2_000);
- cd.close();
- }
- @Override
- public void onClosed(CameraDevice cd) {
- latch.countDown();
- Log.i(TAG, "CameraDevice " + cd.getId() + " closed");
- }
- @Override
- public void onDisconnected(CameraDevice cd) {
- Log.w(TAG, "CameraDevice " + cd.getId() + " disconnected");
- }
- @Override
- public void onError(CameraDevice cd, int error) {
- Log.e(TAG, "CameraDevice " + cd.getId() + "had error " + error);
- }
- };
-
- HandlerThread handlerThread = new HandlerThread("br_handler_thread");
- handlerThread.start();
- Looper looper = handlerThread.getLooper();
- Handler handler = new Handler(looper);
-
- cam.openCamera(cameraIds[0], cb, handler);
- waitForReceiver(context, 10_000, latch, null);
- }
-
- @Test
- public void testFlashlight() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- CameraManager cam = context.getSystemService(CameraManager.class);
- String[] cameraIds = cam.getCameraIdList();
- boolean foundFlash = false;
- for (int i = 0; i < cameraIds.length; i++) {
- String id = cameraIds[i];
- if(cam.getCameraCharacteristics(id).get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
- cam.setTorchMode(id, true);
- sleep(500);
- cam.setTorchMode(id, false);
- foundFlash = true;
- break;
- }
- }
- if(!foundFlash) {
- Log.e(TAG, "No flashlight found on device");
- }
- }
-
- @Test
- public void testForegroundService() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- // The service goes into foreground and exits shortly
- Intent intent = new Intent(context, StatsdCtsForegroundService.class);
- context.startService(intent);
- sleep(500);
- context.stopService(intent);
- }
-
- @Test
- public void testForegroundServiceAccessAppOp() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- Intent fgsIntent = new Intent(context, StatsdCtsForegroundService.class);
- AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-
- // No foreground service session
- noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION);
- sleep(500);
-
- // Foreground service session 1
- context.startService(fgsIntent);
- while (!checkIfServiceRunning(context, StatsdCtsForegroundService.class.getName())) {
- sleep(50);
- }
- noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA);
- noteAppOp(appOpsManager, AppOpsManager.OPSTR_FINE_LOCATION);
- noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA);
- startAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO);
- noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO);
- startAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA);
- sleep(500);
- context.stopService(fgsIntent);
-
- // No foreground service session
- noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION);
- sleep(500);
-
- // TODO(b/149098800): Start fgs a second time and log OPSTR_CAMERA again
- }
-
- @Test
- public void testAppOps() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-
- String[] opsList = appOpsManager.getOpStrs();
-
- for (int i = 0; i < opsList.length; i++) {
- String op = opsList[i];
- if (TextUtils.isEmpty(op)) {
- // Operation removed/deprecated
- continue;
- }
- int noteCount = APP_OPS_ENUM_MAP.getOrDefault(op, opsList.length) + 1;
- for (int j = 0; j < noteCount; j++) {
- try {
- noteAppOp(appOpsManager, opsList[i]);
- } catch (SecurityException e) {}
- }
- }
- }
-
- private void noteAppOp(AppOpsManager aom, String opStr) {
- aom.noteOp(opStr, android.os.Process.myUid(), MY_PACKAGE_NAME, null, "statsdTest");
- }
-
- private void startAppOp(AppOpsManager aom, String opStr) {
- aom.startOp(opStr, android.os.Process.myUid(), MY_PACKAGE_NAME, null, "statsdTest");
- }
-
- /** Check if service is running. */
- public boolean checkIfServiceRunning(Context context, String serviceName) {
- ActivityManager manager = context.getSystemService(ActivityManager.class);
- for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
- if (serviceName.equals(service.service.getClassName()) && service.foreground) {
- return true;
- }
- }
- return false;
- }
-
- @Test
- public void testGpsScan() {
- Context context = InstrumentationRegistry.getContext();
- final LocationManager locManager = context.getSystemService(LocationManager.class);
- if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
- Log.e(TAG, "GPS provider is not enabled");
- return;
- }
- CountDownLatch latch = new CountDownLatch(1);
-
- final LocationListener locListener = new LocationListener() {
- public void onLocationChanged(Location location) {
- Log.v(TAG, "onLocationChanged: location has been obtained");
- }
- public void onProviderDisabled(String provider) {
- Log.w(TAG, "onProviderDisabled " + provider);
- }
- public void onProviderEnabled(String provider) {
- Log.w(TAG, "onProviderEnabled " + provider);
- }
- public void onStatusChanged(String provider, int status, Bundle extras) {
- Log.w(TAG, "onStatusChanged " + provider + " " + status);
- }
- };
-
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- Looper.prepare();
- locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 990, 0,
- locListener);
- sleep(1_000);
- locManager.removeUpdates(locListener);
- latch.countDown();
- return null;
- }
- }.execute();
-
- waitForReceiver(context, 59_000, latch, null);
- }
-
- @Test
- public void testGpsStatus() {
- Context context = InstrumentationRegistry.getContext();
- final LocationManager locManager = context.getSystemService(LocationManager.class);
-
- if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
- Log.e(TAG, "GPS provider is not enabled");
- return;
- }
-
- // Time out set to 85 seconds (5 seconds for sleep and a possible 85 seconds if TTFF takes
- // max time which would be around 90 seconds.
- // This is based on similar location cts test timeout values.
- final int TIMEOUT_IN_MSEC = 85_000;
- final int SLEEP_TIME_IN_MSEC = 5_000;
-
- final CountDownLatch mLatchNetwork = new CountDownLatch(1);
-
- final LocationListener locListener = location -> {
- Log.v(TAG, "onLocationChanged: location has been obtained");
- mLatchNetwork.countDown();
- };
-
- // fetch the networklocation first to make sure the ttff is not flaky
- if (locManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
- Log.i(TAG, "Request Network Location updates.");
- locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
- 0 /* minTime*/,
- 0 /* minDistance */,
- locListener,
- Looper.getMainLooper());
- }
- waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchNetwork, null);
-
- // TTFF could take up to 90 seconds, thus we need to wait till TTFF does occur if it does
- // not occur in the first SLEEP_TIME_IN_MSEC
- final CountDownLatch mLatchTtff = new CountDownLatch(1);
-
- GnssStatus.Callback gnssStatusCallback = new GnssStatus.Callback() {
- @Override
- public void onStarted() {
- Log.v(TAG, "Gnss Status Listener Started");
- }
-
- @Override
- public void onStopped() {
- Log.v(TAG, "Gnss Status Listener Stopped");
- }
-
- @Override
- public void onFirstFix(int ttffMillis) {
- Log.v(TAG, "Gnss Status Listener Received TTFF");
- mLatchTtff.countDown();
- }
-
- @Override
- public void onSatelliteStatusChanged(GnssStatus status) {
- Log.v(TAG, "Gnss Status Listener Received Status Update");
- }
- };
-
- boolean gnssStatusCallbackAdded = locManager.registerGnssStatusCallback(
- gnssStatusCallback, new Handler(Looper.getMainLooper()));
- if (!gnssStatusCallbackAdded) {
- // Registration of GnssMeasurements listener has failed, this indicates a platform bug.
- Log.e(TAG, "Failed to start gnss status callback");
- }
-
- locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
- 0,
- 0 /* minDistance */,
- locListener,
- Looper.getMainLooper());
- sleep(SLEEP_TIME_IN_MSEC);
- waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchTtff, null);
- locManager.removeUpdates(locListener);
- locManager.unregisterGnssStatusCallback(gnssStatusCallback);
- }
-
- @Test
- public void testScreenBrightness() {
- Context context = InstrumentationRegistry.getContext();
- PowerManager pm = context.getSystemService(PowerManager.class);
- PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
- PowerManager.ACQUIRE_CAUSES_WAKEUP, "StatsdBrightnessTest");
- wl.acquire();
- sleep(500);
-
- setScreenBrightness(47);
- sleep(500);
- setScreenBrightness(100);
- sleep(500);
- setScreenBrightness(198);
- sleep(500);
-
-
- wl.release();
- }
-
- @Test
- public void testSyncState() throws Exception {
-
- Context context = InstrumentationRegistry.getContext();
- StatsdAuthenticator.removeAllAccounts(context);
- AccountManager am = context.getSystemService(AccountManager.class);
- CountDownLatch latch = StatsdSyncAdapter.resetCountDownLatch();
-
- Account account = StatsdAuthenticator.getTestAccount();
- StatsdAuthenticator.ensureTestAccount(context);
- sleep(500);
-
- // Just force set is syncable.
- ContentResolver.setMasterSyncAutomatically(true);
- sleep(500);
- ContentResolver.setIsSyncable(account, StatsdProvider.AUTHORITY, 1);
- // Wait for the first (automatic) sync to finish
- waitForReceiver(context, 120_000, latch, null);
-
- //Sleep for 500ms, since we assert each start/stop to be ~500ms apart.
- sleep(500);
-
- // Request and wait for the second sync to finish
- latch = StatsdSyncAdapter.resetCountDownLatch();
- StatsdSyncAdapter.requestSync(account);
- waitForReceiver(context, 120_000, latch, null);
- StatsdAuthenticator.removeAllAccounts(context);
- }
-
- @Test
- public void testScheduledJob() throws Exception {
- final ComponentName name = new ComponentName(MY_PACKAGE_NAME,
- StatsdJobService.class.getName());
-
- Context context = InstrumentationRegistry.getContext();
- JobScheduler js = context.getSystemService(JobScheduler.class);
- assertWithMessage("JobScheduler service not available").that(js).isNotNull();
-
- JobInfo.Builder builder = new JobInfo.Builder(1, name);
- builder.setOverrideDeadline(0);
- JobInfo job = builder.build();
-
- long startTime = System.currentTimeMillis();
- CountDownLatch latch = StatsdJobService.resetCountDownLatch();
- js.schedule(job);
- waitForReceiver(context, 5_000, latch, null);
- }
-
- @Test
- public void testVibratorState() {
- Context context = InstrumentationRegistry.getContext();
- Vibrator vib = context.getSystemService(Vibrator.class);
- if (vib.hasVibrator()) {
- vib.vibrate(VibrationEffect.createOneShot(
- 500 /* ms */, VibrationEffect.DEFAULT_AMPLITUDE));
- }
- }
-
- @Test
- public void testWakelockState() {
- Context context = InstrumentationRegistry.getContext();
- PowerManager pm = context.getSystemService(PowerManager.class);
- PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- "StatsdPartialWakelock");
- wl.acquire();
- sleep(500);
- wl.release();
- }
-
- @Test
- public void testSliceByWakelockState() {
- int uid = Process.myUid();
- int whatAtomId = 9_998;
- int wakelockType = PowerManager.PARTIAL_WAKE_LOCK;
- String tag = "StatsdPartialWakelock";
-
- Context context = InstrumentationRegistry.getContext();
- PowerManager pm = context.getSystemService(PowerManager.class);
- PowerManager.WakeLock wl = pm.newWakeLock(wakelockType, tag);
-
- wl.acquire();
- sleep(500);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- wl.acquire();
- sleep(500);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- wl.release();
- sleep(500);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- wl.release();
- sleep(500);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
- }
-
- private static void writeSliceByWakelockStateChangedAtom(int atomId, int firstUid,
- int field2, String field3) {
- final StatsEvent.Builder builder = StatsEvent.newBuilder()
- .setAtomId(atomId)
- .writeAttributionChain(new int[] {firstUid}, new String[] {"tag1"})
- .writeInt(field2)
- .writeString(field3)
- .usePooledBuffer();
-
- StatsLog.write(builder.build());
- }
-
-
- @Test
- public void testWakelockLoad() {
- final int NUM_THREADS = 16;
- CountDownLatch latch = new CountDownLatch(NUM_THREADS);
- for (int i = 0; i < NUM_THREADS; i++) {
- Thread t = new Thread(new WakelockLoadTestRunnable("StatsdPartialWakelock" + i, latch));
- t.start();
- }
- waitForReceiver(null, 120_000, latch, null);
- }
-
- @Test
- public void testWakeupAlarm() {
- Context context = InstrumentationRegistry.getContext();
- String name = "android.cts.statsd.testWakeupAlarm";
- CountDownLatch onReceiveLatch = new CountDownLatch(1);
- BroadcastReceiver receiver =
- registerReceiver(context, onReceiveLatch, new IntentFilter(name));
- AlarmManager manager = (AlarmManager) (context.getSystemService(AlarmManager.class));
- PendingIntent pintent = PendingIntent.getBroadcast(context, 0, new Intent(name), 0);
- manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + 2_000, pintent);
- waitForReceiver(context, 10_000, onReceiveLatch, receiver);
- }
-
- @Test
- public void testWifiLockHighPerf() {
- Context context = InstrumentationRegistry.getContext();
- WifiManager wm = context.getSystemService(WifiManager.class);
- WifiManager.WifiLock lock =
- wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "StatsdCTSWifiLock");
- lock.acquire();
- sleep(500);
- lock.release();
- }
-
- @Test
- public void testWifiLockLowLatency() {
- Context context = InstrumentationRegistry.getContext();
- WifiManager wm = context.getSystemService(WifiManager.class);
- WifiManager.WifiLock lock =
- wm.createWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "StatsdCTSWifiLock");
- lock.acquire();
- sleep(500);
- lock.release();
- }
-
- @Test
- public void testWifiMulticastLock() {
- Context context = InstrumentationRegistry.getContext();
- WifiManager wm = context.getSystemService(WifiManager.class);
- WifiManager.MulticastLock lock = wm.createMulticastLock("StatsdCTSMulticastLock");
- lock.acquire();
- sleep(500);
- lock.release();
- }
-
- @Test
- /** Does two wifi scans. */
- // TODO: Copied this from BatterystatsValidation but we probably don't need to wait for results.
- public void testWifiScan() {
- Context context = InstrumentationRegistry.getContext();
- IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
- // Sometimes a scan was already running (from a different uid), so the first scan doesn't
- // start when requested. Therefore, additionally wait for whatever scan is currently running
- // to finish, then request a scan again - at least one of these two scans should be
- // attributed to this app.
- for (int i = 0; i < 2; i++) {
- CountDownLatch onReceiveLatch = new CountDownLatch(1);
- BroadcastReceiver receiver = registerReceiver(context, onReceiveLatch, intentFilter);
- context.getSystemService(WifiManager.class).startScan();
- waitForReceiver(context, 60_000, onReceiveLatch, receiver);
- }
- }
-
- @Test
- public void testSimpleCpu() {
- long timestamp = System.currentTimeMillis();
- for (int i = 0; i < 10000; i ++) {
- timestamp += i;
- }
- Log.i(TAG, "The answer is " + timestamp);
- }
-
- @Test
- public void testWriteRawTestAtom() throws Exception {
- Context context = InstrumentationRegistry.getTargetContext();
- ApplicationInfo appInfo = context.getPackageManager()
- .getApplicationInfo(context.getPackageName(), 0);
- int[] uids = {1234, appInfo.uid};
- String[] tags = {"tag1", "tag2"};
- byte[] experimentIds = {8, 1, 8, 2, 8, 3}; // Corresponds to 1, 2, 3.
- StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, uids, tags, 42,
- Long.MAX_VALUE, 3.14f, "This is a basic test!", false,
- StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__ON, experimentIds);
-
- // All nulls. Should get dropped since cts app is not in the attribution chain.
- StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, null, null, 0, 0,
- 0f, null, false, StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__ON, null);
-
- // Null tag in attribution chain.
- int[] uids2 = {9999, appInfo.uid};
- String[] tags2 = {"tag9999", null};
- StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, uids2, tags2, 100,
- Long.MIN_VALUE, -2.5f, "Test null uid", true,
- StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__UNKNOWN, experimentIds);
-
- // Non chained non-null
- StatsLogStatsdCts.write_non_chained(StatsLogStatsdCts.TEST_ATOM_REPORTED,
- appInfo.uid, "tag1", -256, -1234567890L, 42.01f, "Test non chained", true,
- StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__OFF, experimentIds);
-
- // Non chained all null
- StatsLogStatsdCts.write_non_chained(StatsLogStatsdCts.TEST_ATOM_REPORTED, appInfo.uid, null,
- 0, 0, 0f, null, true, StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__OFF, null);
-
- }
-
- /**
- * Bring up and generate some traffic on cellular data connection.
- */
- @Test
- public void testGenerateMobileTraffic() throws Exception {
- final Context context = InstrumentationRegistry.getContext();
- doGenerateNetworkTraffic(context, NetworkCapabilities.TRANSPORT_CELLULAR);
- }
-
- // Constants which are locally used by doGenerateNetworkTraffic.
- private static final int NETWORK_TIMEOUT_MILLIS = 15000;
- private static final String HTTPS_HOST_URL =
- "https://connectivitycheck.gstatic.com/generate_204";
-
- private void doGenerateNetworkTraffic(@NonNull Context context,
- @NetworkCapabilities.Transport int transport) throws InterruptedException {
- final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
- final NetworkRequest request = new NetworkRequest.Builder().addCapability(
- NetworkCapabilities.NET_CAPABILITY_INTERNET).addTransportType(transport).build();
- final CtsNetUtils.TestNetworkCallback callback = new CtsNetUtils.TestNetworkCallback();
-
- // Request network, and make http query when the network is available.
- cm.requestNetwork(request, callback);
-
- // If network is not available, throws IllegalStateException.
- final Network network = callback.waitForAvailable();
- if (network == null) {
- throw new IllegalStateException("network "
- + NetworkCapabilities.transportNameOf(transport) + " is not available.");
- }
-
- final long startTime = SystemClock.elapsedRealtime();
- try {
- exerciseRemoteHost(cm, network, new URL(HTTPS_HOST_URL));
- Log.i(TAG, "exerciseRemoteHost successful in " + (SystemClock.elapsedRealtime()
- - startTime) + " ms");
- } catch (Exception e) {
- Log.e(TAG, "exerciseRemoteHost failed in " + (SystemClock.elapsedRealtime()
- - startTime) + " ms: " + e);
- } finally {
- cm.unregisterNetworkCallback(callback);
- }
- }
-
- /**
- * Generate traffic on specified network.
- */
- private void exerciseRemoteHost(@NonNull ConnectivityManager cm, @NonNull Network network,
- @NonNull URL url) throws Exception {
- cm.bindProcessToNetwork(network);
- HttpURLConnection urlc = null;
- try {
- urlc = (HttpURLConnection) network.openConnection(url);
- urlc.setConnectTimeout(NETWORK_TIMEOUT_MILLIS);
- urlc.setUseCaches(false);
- urlc.connect();
- } finally {
- if (urlc != null) {
- urlc.disconnect();
- }
- }
- }
-
- @Test
- public void testIsolatedProcessService() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- int uid = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).uid;
-
- // Start the isolated service, which logs an AppBreadcrumbReported atom, and then exit
- // shortly afterwards.
- Intent intent = new Intent(context, IsolatedProcessService.class);
- context.startService(intent);
- sleep(500);
- context.stopService(intent);
- }
-
-
- // Constants for testBlobStore
- private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5;
- private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000;
- private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L;
- private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000;
- private static final byte[] FAKE_PKG_CERT_SHA256 = BaseEncoding.base16().decode(
- "187E3D3172F2177D6FEC2EA53785BF1E25DFF7B2E5F6E59807E365A7A837E6C3");
-
- @Test
- public void testBlobStore() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- int uid = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).uid;
-
- BlobStoreManager bsm = context.getSystemService(BlobStoreManager.class);
- final long leaseExpiryMs = System.currentTimeMillis() + BLOB_LEASE_EXPIRY_DURATION_MS;
-
- final DummyBlobData blobData = new DummyBlobData.Builder(context).setExpiryDurationMs(
- BLOB_EXPIRY_DURATION_MS).setFileSize(BLOB_FILE_SIZE_BYTES).build();
-
- blobData.prepare();
- try {
- // Commit the Blob, should result in BLOB_COMMITTED atom event
- commitBlob(context, bsm, blobData);
-
- // Lease the Blob, should result in BLOB_LEASED atom event
- bsm.acquireLease(blobData.getBlobHandle(), "", leaseExpiryMs);
-
- // Open the Blob, should result in BLOB_OPENED atom event
- bsm.openBlob(blobData.getBlobHandle());
-
- } finally {
- blobData.delete();
- }
- }
-
- // ------- Helper methods
-
- /** Puts the current thread to sleep. */
- static void sleep(int millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException e) {
- Log.e(TAG, "Interrupted exception while sleeping", e);
- }
- }
-
- /** Register receiver to determine when given action is complete. */
- private static BroadcastReceiver registerReceiver(
- Context ctx, CountDownLatch onReceiveLatch, IntentFilter intentFilter) {
- BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received broadcast.");
- onReceiveLatch.countDown();
- }
- };
- // Run Broadcast receiver in a different thread since the main thread will wait.
- HandlerThread handlerThread = new HandlerThread("br_handler_thread");
- handlerThread.start();
- Looper looper = handlerThread.getLooper();
- Handler handler = new Handler(looper);
- ctx.registerReceiver(receiver, intentFilter, null, handler);
- return receiver;
- }
-
- /**
- * Uses the receiver to wait until the action is complete. ctx and receiver may be null if no
- * receiver is needed to be unregistered.
- */
- private static void waitForReceiver(Context ctx,
- int maxWaitTimeMs, CountDownLatch latch, BroadcastReceiver receiver) {
- try {
- boolean didFinish = latch.await(maxWaitTimeMs, TimeUnit.MILLISECONDS);
- if (didFinish) {
- Log.v(TAG, "Finished performing action");
- } else {
- // This is not necessarily a problem. If we just want to make sure a count was
- // recorded for the request, it doesn't matter if the action actually finished.
- Log.w(TAG, "Did not finish in specified time.");
- }
- } catch (InterruptedException e) {
- Log.e(TAG, "Interrupted exception while awaiting action to finish", e);
- }
- if (ctx != null && receiver != null) {
- ctx.unregisterReceiver(receiver);
- }
- }
-
- private static void setScreenBrightness(int brightness) {
- runShellCommand("settings put system screen_brightness " + brightness);
- }
-
-
- private void commitBlob(Context context, BlobStoreManager bsm, DummyBlobData blobData)
- throws Exception {;
- final long sessionId = bsm.createSession(blobData.getBlobHandle());
- try (BlobStoreManager.Session session = bsm.openSession(sessionId)) {
- blobData.writeToSession(session);
- session.allowPackageAccess("fake.package.name", FAKE_PKG_CERT_SHA256);
-
- final CompletableFuture<Integer> callback = new CompletableFuture<>();
- session.commit(context.getMainExecutor(), callback::complete);
- assertWithMessage("Session failed to commit within timeout").that(
- callback.get(BLOB_COMMIT_CALLBACK_TIMEOUT_SEC, TimeUnit.SECONDS)).isEqualTo(0);
- }
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java
deleted file mode 100644
index 3728cef..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java
+++ /dev/null
@@ -1,45 +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.server.cts.device.statsd;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.wifi.WifiManager;
-import android.os.Vibrator;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.Test;
-
-/**
- * Methods to check device properties. They pass iff the check returns true.
- */
-public class Checkers {
- private static final String TAG = Checkers.class.getSimpleName();
-
- @Test
- public void checkVibratorSupported() {
- Vibrator v = InstrumentationRegistry.getContext().getSystemService(Vibrator.class);
- assertThat(v.hasVibrator()).isTrue();
- }
-
- @Test
- public void checkWifiEnhancedPowerReportingSupported() {
- WifiManager wm = InstrumentationRegistry.getContext().getSystemService(WifiManager.class);
- assertThat(wm.isEnhancedPowerReportingSupported()).isTrue();
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyActivity.java
deleted file mode 100644
index e2ec7f7..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyActivity.java
+++ /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.
- */
-
-package com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.widget.VideoView;
-import android.util.Log;
-
-
-public class DaveyActivity extends Activity {
- private static final String TAG = "statsdDaveyActivity";
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_davey);
- DaveyView view = (DaveyView)findViewById(R.id.davey_view);
- view.causeDavey(true);
- }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyView.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyView.java
deleted file mode 100644
index bf1cd35..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyView.java
+++ /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.
- */
-
-package com.android.server.cts.device.statsd;
-
-import android.view.View;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.FontMetrics;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-
-
-public class DaveyView extends View {
-
- private static final String TAG = "statsdDaveyView";
-
- private static final long DAVEY_TIME_MS = 750; // A bit more than 700ms to be safe.
- private boolean mCauseDavey;
- private Paint mPaint;
- private int mTexty;
-
- public DaveyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- TypedArray a = context.getTheme().obtainStyledAttributes(
- attrs,
- R.styleable.DaveyView,
- 0, 0);
-
- try {
- mCauseDavey = a.getBoolean(R.styleable.DaveyView_causeDavey, false);
- } finally {
- a.recycle();
- }
-
- mPaint = new Paint();
- mPaint.setColor(Color.BLACK);
- mPaint.setTextSize(20);
- FontMetrics metric = mPaint.getFontMetrics();
- int textHeight = (int) Math.ceil(metric.descent - metric.ascent);
- mTexty = textHeight - (int) metric.descent;
- }
-
- public void causeDavey(boolean cause) {
- mCauseDavey = cause;
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (mCauseDavey) {
- canvas.drawText("Davey!", 0, mTexty, mPaint);
- SystemClock.sleep(DAVEY_TIME_MS);
- mCauseDavey = false;
- } else {
- canvas.drawText("No Davey", 0, mTexty, mPaint);
- }
- }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DirectoryTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DirectoryTests.java
deleted file mode 100644
index fd849c9..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DirectoryTests.java
+++ /dev/null
@@ -1,62 +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.server.cts.device.statsd;
-
-import org.junit.Test;
-
-import java.io.File;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class DirectoryTests {
-
- @Test
- public void testStatsActiveMetricDirectoryExists() {
- final File f = new File("/data/misc/stats-active-metric/");
- assertTrue(f.exists());
- assertFalse(f.isFile());
- }
-
- @Test
- public void testStatsDataDirectoryExists() {
- final File f = new File("/data/misc/stats-data/");
- assertTrue(f.exists());
- assertFalse(f.isFile());
- }
-
- @Test
- public void testStatsMetadataDirectoryExists() {
- final File f = new File("/data/misc/stats-metadata/");
- assertTrue(f.exists());
- assertFalse(f.isFile());
- }
-
- @Test
- public void testStatsServiceDirectoryExists() {
- final File f = new File("/data/misc/stats-service/");
- assertTrue(f.exists());
- assertFalse(f.isFile());
- }
-
- @Test
- public void testTrainInfoDirectoryExists() {
- final File f = new File("/data/misc/train-info/");
- assertTrue(f.exists());
- assertFalse(f.isFile());
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
deleted file mode 100644
index 3e52342..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
+++ /dev/null
@@ -1,28 +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.cts.device.statsd;
-
-import android.annotation.NonNull;
-import android.telecom.Call;
-import android.telecom.CallScreeningService;
-
-public class DummyCallscreeningService extends CallScreeningService {
- @Override
- public void onScreenCall(@NonNull Call.Details callDetails) {
-
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/HiddenApiUsedActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/HiddenApiUsedActivity.java
deleted file mode 100644
index 2132f3c..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/HiddenApiUsedActivity.java
+++ /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.
- */
-
-package com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import java.lang.reflect.Field;
-
-
-public class HiddenApiUsedActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- try {
- Field field = Activity.class.getDeclaredField("mWindow");
- field.setAccessible(true);
- Object object = field.get(this);
- } catch(NoSuchFieldException e) {
- } catch(IllegalAccessException e) {
- }
- finish();
- }
-
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/IsolatedProcessService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/IsolatedProcessService.java
deleted file mode 100644
index 086a3be..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/IsolatedProcessService.java
+++ /dev/null
@@ -1,37 +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.server.cts.device.statsd;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-import android.util.StatsLog;
-
-public class IsolatedProcessService extends Service {
- private static final String TAG = "IsolatedProcessService";
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- StatsLog.logStart(/*label=*/0);
- return START_NOT_STICKY;
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdAuthenticator.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdAuthenticator.java
deleted file mode 100644
index 85acd07..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdAuthenticator.java
+++ /dev/null
@@ -1,135 +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.server.cts.device.statsd;
-
-import android.accounts.AbstractAccountAuthenticator;
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorResponse;
-import android.accounts.AccountManager;
-import android.accounts.NetworkErrorException;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.util.Log;
-
-import java.util.Arrays;
-
-/**
- * Authenticator for the sync test.
- */
-public class StatsdAuthenticator extends Service {
- private static final String TAG = "AtomTestsAuthenticator";
-
- private static final String ACCOUNT_NAME = "StatsdCts";
- private static final String ACCOUNT_TYPE = "com.android.cts.statsd";
- private static Authenticator sInstance;
-
- @Override
- public IBinder onBind(Intent intent) {
- if (sInstance == null) {
- sInstance = new Authenticator(getApplicationContext());
-
- }
- return sInstance.getIBinder();
- }
-
- public static Account getTestAccount() {
- return new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
- }
-
- /**
- * Adds the test account, if it doesn't exist yet.
- */
- public static void ensureTestAccount(Context context) {
- final Account account = getTestAccount();
-
- Bundle result = new Bundle();
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-
- final AccountManager am = context.getSystemService(AccountManager.class);
-
- if (!Arrays.asList(am.getAccountsByType(account.type)).contains(account) ){
- am.addAccountExplicitly(account, "password", new Bundle());
- }
- }
-
- /**
- * Remove the test account.
- */
- public static void removeAllAccounts(Context context) {
- final AccountManager am = context.getSystemService(AccountManager.class);
-
- for (Account account : am.getAccountsByType(ACCOUNT_TYPE)) {
- Log.i(TAG, "Removing " + account + "...");
- am.removeAccountExplicitly(account);
- Log.i(TAG, "Removed");
- }
- }
-
- public static class Authenticator extends AbstractAccountAuthenticator {
-
- private final Context mContxet;
-
- public Authenticator(Context context) {
- super(context);
- mContxet = context;
- }
-
- @Override
- public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
- String authTokenType, String[] requiredFeatures, Bundle options)
- throws NetworkErrorException {
- return new Bundle();
- }
-
- @Override
- public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
- return new Bundle();
- }
-
- @Override
- public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
- String authTokenType, Bundle options) throws NetworkErrorException {
- return new Bundle();
- }
-
- @Override
- public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
- Bundle options) throws NetworkErrorException {
- return new Bundle();
- }
-
- @Override
- public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
- String authTokenType, Bundle options) throws NetworkErrorException {
- return new Bundle();
- }
-
- @Override
- public String getAuthTokenLabel(String authTokenType) {
- return "token_label";
- }
-
- @Override
- public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
- String[] features) throws NetworkErrorException {
- return new Bundle();
- }
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsBackgroundService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsBackgroundService.java
deleted file mode 100644
index ad018f9..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsBackgroundService.java
+++ /dev/null
@@ -1,67 +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.cts.device.statsd;
-
-import com.android.server.cts.device.statsd.AtomTests;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.util.Log;
-
-/** An service (to be run as a background process) which performs one of a number of actions. */
-public class StatsdCtsBackgroundService extends IntentService {
- private static final String TAG = StatsdCtsBackgroundService.class.getSimpleName();
-
- public static final String KEY_ACTION = "action";
- public static final String ACTION_BACKGROUND_SLEEP = "action.background_sleep";
- public static final String ACTION_END_IMMEDIATELY = "action.end_immediately";
- public static final String ACTION_LMK = "action.lmk";
-
- public static final int SLEEP_OF_ACTION_BACKGROUND_SLEEP = 2_000;
-
- static {
- System.loadLibrary("lmkhelper");
- }
-
- public StatsdCtsBackgroundService() {
- super(StatsdCtsBackgroundService.class.getName());
- }
-
- @Override
- public void onHandleIntent(Intent intent) {
- String action = intent.getStringExtra(KEY_ACTION);
- Log.i(TAG, "Starting " + action + " from background service.");
-
- switch (action) {
- case ACTION_BACKGROUND_SLEEP:
- AtomTests.sleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP);
- break;
- case ACTION_END_IMMEDIATELY:
- break;
- case ACTION_LMK:
- new Thread(this::cmain).start();
- break;
- default:
- Log.e(TAG, "Intent had invalid action");
- }
- }
-
- /**
- * Keep allocating memory until the process is killed by LMKD.
- **/
- public native void cmain();
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundActivity.java
deleted file mode 100644
index c8c02fc..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundActivity.java
+++ /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.
- */
-
-package com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.net.ConnectivityManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-
-/** An activity (to be run as a foreground process) which performs one of a number of actions. */
-public class StatsdCtsForegroundActivity extends Activity {
- private static final String TAG = StatsdCtsForegroundActivity.class.getSimpleName();
-
- public static final String KEY_ACTION = "action";
- public static final String ACTION_END_IMMEDIATELY = "action.end_immediately";
- public static final String ACTION_SLEEP_WHILE_TOP = "action.sleep_top";
- public static final String ACTION_LONG_SLEEP_WHILE_TOP = "action.long_sleep_top";
- public static final String ACTION_SHOW_APPLICATION_OVERLAY = "action.show_application_overlay";
- public static final String ACTION_SHOW_NOTIFICATION = "action.show_notification";
- public static final String ACTION_CRASH = "action.crash";
- public static final String ACTION_CREATE_CHANNEL_GROUP = "action.create_channel_group";
- public static final String ACTION_POLL_NETWORK_STATS = "action.poll_network_stats";
-
- public static final int SLEEP_OF_ACTION_SLEEP_WHILE_TOP = 2_000;
- public static final int SLEEP_OF_ACTION_SHOW_APPLICATION_OVERLAY = 2_000;
- public static final int LONG_SLEEP_WHILE_TOP = 60_000;
-
- @Override
- public void onCreate(Bundle bundle) {
- super.onCreate(bundle);
-
- Intent intent = this.getIntent();
- if (intent == null) {
- Log.e(TAG, "Intent was null.");
- finish();
- }
-
- String action = intent.getStringExtra(KEY_ACTION);
- Log.i(TAG, "Starting " + action + " from foreground activity.");
-
- switch (action) {
- case ACTION_END_IMMEDIATELY:
- finish();
- break;
- case ACTION_SLEEP_WHILE_TOP:
- doSleepWhileTop(SLEEP_OF_ACTION_SLEEP_WHILE_TOP);
- break;
- case ACTION_LONG_SLEEP_WHILE_TOP:
- doSleepWhileTop(LONG_SLEEP_WHILE_TOP);
- break;
- case ACTION_SHOW_APPLICATION_OVERLAY:
- doShowApplicationOverlay();
- break;
- case ACTION_SHOW_NOTIFICATION:
- doShowNotification();
- break;
- case ACTION_CRASH:
- doCrash();
- break;
- case ACTION_CREATE_CHANNEL_GROUP:
- doCreateChannelGroup();
- break;
- case ACTION_POLL_NETWORK_STATS:
- doPollNetworkStats();
- break;
- default:
- Log.e(TAG, "Intent had invalid action " + action);
- finish();
- }
- }
-
- /** Does nothing, but asynchronously. */
- private void doSleepWhileTop(int sleepTime) {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- AtomTests.sleep(sleepTime);
- return null;
- }
-
- @Override
- protected void onPostExecute(Void nothing) {
- finish();
- }
- }.execute();
- }
-
- private void doShowApplicationOverlay() {
- // Adapted from BatteryStatsBgVsFgActions.java.
- final WindowManager wm = getSystemService(WindowManager.class);
- Point size = new Point();
- wm.getDefaultDisplay().getSize(size);
-
- WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
- WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
- wmlp.width = size.x / 4;
- wmlp.height = size.y / 4;
- wmlp.gravity = Gravity.CENTER | Gravity.LEFT;
- wmlp.setTitle(getPackageName());
-
- ViewGroup.LayoutParams vglp = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
-
- View v = new View(this);
- v.setBackgroundColor(Color.GREEN);
- v.setLayoutParams(vglp);
- wm.addView(v, wmlp);
-
- // The overlay continues long after the finish. The following is just to end the activity.
- AtomTests.sleep(SLEEP_OF_ACTION_SHOW_APPLICATION_OVERLAY);
- finish();
- }
-
- private void doShowNotification() {
- final int notificationId = R.layout.activity_main;
- final String notificationChannelId = "StatsdCtsChannel";
-
- NotificationManager nm = getSystemService(NotificationManager.class);
- NotificationChannel channel = new NotificationChannel(notificationChannelId, "Statsd Cts",
- NotificationManager.IMPORTANCE_DEFAULT);
- channel.setDescription("Statsd Cts Channel");
- nm.createNotificationChannel(channel);
-
- nm.notify(
- notificationId,
- new Notification.Builder(this, notificationChannelId)
- .setSmallIcon(android.R.drawable.stat_notify_chat)
- .setContentTitle("StatsdCts")
- .setContentText("StatsdCts")
- .build());
- nm.cancel(notificationId);
- finish();
- }
-
- private void doCreateChannelGroup() {
- NotificationManager nm = getSystemService(NotificationManager.class);
- NotificationChannelGroup channelGroup = new NotificationChannelGroup("StatsdCtsGroup",
- "Statsd Cts Group");
- channelGroup.setDescription("StatsdCtsGroup Description");
- nm.createNotificationChannelGroup(channelGroup);
- finish();
- }
-
- // Trigger force poll on NetworkStatsService to make sure the service get most updated network
- // stats from lower layer on subsequent verifications.
- private void doPollNetworkStats() {
- final NetworkStatsManager nsm =
- (NetworkStatsManager) getSystemService(Context.NETWORK_STATS_SERVICE);
-
- // While the flag of force polling is the only important thing needed when making binder
- // call to service, the type, parameters and returned result of the query here do not
- // matter.
- try {
- nsm.setPollForce(true);
- nsm.querySummaryForUser(ConnectivityManager.TYPE_WIFI, null, Long.MIN_VALUE,
- Long.MAX_VALUE);
- } catch (RemoteException e) {
- Log.e(TAG, "doPollNetworkStats failed with " + e);
- } finally {
- finish();
- }
- }
-
- @SuppressWarnings("ConstantOverflow")
- private void doCrash() {
- Log.e(TAG, "About to crash the app with 1/0 " + (long) 1 / 0);
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundService.java
deleted file mode 100644
index ab46f5f..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundService.java
+++ /dev/null
@@ -1,125 +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.cts.device.statsd;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.util.Log;
-
-import com.android.compatibility.common.util.ApiLevelUtil;
-
-public class StatsdCtsForegroundService extends Service {
- private static final String TAG = "SimpleForegroundService";
- private static final String NOTIFICATION_CHANNEL_ID = "Foreground Service";
-
- // TODO: pass this in from host side.
- public static final int SLEEP_OF_FOREGROUND_SERVICE = 2_000;
-
- private Looper mServiceLooper;
- private ServiceHandler mServiceHandler;
- private boolean mChannelCreated;
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- Log.i(TAG, "Handling message.");
- // Sleep.
- try {
- Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE);
- } catch (InterruptedException e) {
- // Restore interrupt status.
- Thread.currentThread().interrupt();
- }
- Log.i(TAG, "Stopping service.");
- // Stop the service using the startId, so that we don't stop
- // the service in the middle of handling another job
- stopSelf(msg.arg1);
- }
- }
-
- @Override
- public void onCreate() {
- // Start up the thread running the service. Note that we create a
- // separate thread because the service normally runs in the process's
- // main thread, which we don't want to block. We also make it
- // background priority so CPU-intensive work will not disrupt our UI.
- HandlerThread thread = new HandlerThread("ServiceStartArguments",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
-
- // Get the HandlerThread's Looper and use it for our Handler
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
-
- if (ApiLevelUtil.isBefore(Build.VERSION_CODES.O_MR1)) {
- return;
- }
- // OMR1 requires notification channel to be set
- NotificationManager notificationManager =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
- NOTIFICATION_CHANNEL_ID,
- NotificationManager.IMPORTANCE_HIGH);
- notificationManager.createNotificationChannel(channel);
- mChannelCreated = true;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
- .setContentTitle("CTS Foreground")
- .setSmallIcon(android.R.drawable.ic_secure)
- .build();
- Log.i(TAG, "Starting Foreground.");
- startForeground(1, notification);
-
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- mServiceHandler.sendMessage(msg);
-
- return START_NOT_STICKY;
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public void onDestroy () {
- if (mChannelCreated) {
- NotificationManager notificationManager =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID);
- }
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
deleted file mode 100644
index d81040f..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
+++ /dev/null
@@ -1,87 +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.cts.device.statsd;
-
-import android.annotation.TargetApi;
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.Context;
-import android.os.Handler;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Handles callback from the framework {@link android.app.job.JobScheduler}.
- * Runs a job for 0.5 seconds. Provides a countdown latch to wait on, by the test that schedules it.
- */
-@TargetApi(21)
-public class StatsdJobService extends JobService {
- private static final String TAG = "AtomTestsJobService";
-
- JobInfo mRunningJobInfo;
- JobParameters mRunningParams;
-
- private static final Object sLock = new Object();
-
- @GuardedBy("sLock")
- private static CountDownLatch sLatch;
-
- final Handler mHandler = new Handler();
- final Runnable mWorker = new Runnable() {
- @Override public void run() {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- }
-
- jobFinished(mRunningParams, false);
-
- synchronized (sLock) {
- if (sLatch != null) {
- sLatch.countDown();
- }
- }
- }
- };
-
- public static synchronized CountDownLatch resetCountDownLatch() {
- synchronized (sLock) {
- if (sLatch == null || sLatch.getCount() == 0) {
- sLatch = new CountDownLatch(1);
- }
- }
- return sLatch;
- }
-
- @Override
- public boolean onStartJob(JobParameters params) {
- mRunningParams = params;
- mHandler.post(mWorker);
- return true;
- }
-
- @Override
- public boolean onStopJob(JobParameters params) {
- return false;
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdProvider.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdProvider.java
deleted file mode 100644
index bd652b2..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdProvider.java
+++ /dev/null
@@ -1,59 +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.server.cts.device.statsd;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-/**
- * Provider for the sync test.
- */
-public class StatsdProvider extends ContentProvider {
- public static final String AUTHORITY = "com.android.server.cts.device.statsd.provider";
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
deleted file mode 100644
index 6968307..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
+++ /dev/null
@@ -1,89 +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.server.cts.device.statsd;
-
-import android.accounts.Account;
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SyncResult;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.Log;
-
-import org.junit.Assert;
-
-import java.util.concurrent.CountDownLatch;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Sync adapter for the sync test.
- */
-public class StatsdSyncAdapter extends AbstractThreadedSyncAdapter {
- private static final String TAG = "AtomTestsSyncAdapter";
-
- private static final int TIMEOUT_SECONDS = 60 * 2;
-
- private static CountDownLatch sLatch;
-
- private static final Object sLock = new Object();
-
-
- public StatsdSyncAdapter(Context context) {
- // No need for auto-initialization because we set isSyncable in the test anyway.
- super(context, /* autoInitialize= */ false);
- }
-
- @Override
- public void onPerformSync(Account account, Bundle extras, String authority,
- ContentProviderClient provider, SyncResult syncResult) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- }
- synchronized (sLock) {
- Log.i(TAG, "onPerformSync");
- if (sLatch != null) {
- sLatch.countDown();
- } else {
- Log.w(TAG, "sLatch is null, resetCountDownLatch probably should have been called");
- }
- }
- }
-
- /**
- * Request a sync on the given account, and wait for it.
- */
- public static void requestSync(Account account) throws Exception {
- final Bundle extras = new Bundle();
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
-
- ContentResolver.requestSync(account, StatsdProvider.AUTHORITY, extras);
- }
-
- public static CountDownLatch resetCountDownLatch() {
- synchronized (sLock) {
- if (sLatch == null || sLatch.getCount() == 0) {
- sLatch = new CountDownLatch(1);
- }
- }
- return sLatch;
- }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncService.java
deleted file mode 100644
index ab06c6f..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncService.java
+++ /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.
- */
-package com.android.server.cts.device.statsd;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Service for the sync test.
- */
-public class StatsdSyncService extends Service {
-
- private static StatsdSyncAdapter sAdapter;
-
- @Override
- public synchronized IBinder onBind(Intent intent) {
- if (sAdapter == null) {
- sAdapter = new StatsdSyncAdapter(getApplicationContext());
- }
- return sAdapter.getSyncAdapterBinder();
- }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/VideoPlayerActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/VideoPlayerActivity.java
deleted file mode 100644
index ea1fcec..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/VideoPlayerActivity.java
+++ /dev/null
@@ -1,88 +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.cts.device.statsd;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.Log;
-import android.widget.VideoView;
-
-public class VideoPlayerActivity extends Activity {
- private static final String TAG = VideoPlayerActivity.class.getSimpleName();
-
- public static final String KEY_ACTION = "action";
- public static final String ACTION_PLAY_VIDEO = "action.play_video";
- public static final String ACTION_PLAY_VIDEO_PICTURE_IN_PICTURE_MODE =
- "action.play_video_picture_in_picture_mode";
-
- public static final int DELAY_MILLIS = 2000;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Intent intent = this.getIntent();
- if (intent == null) {
- Log.e(TAG, "Intent was null.");
- finish();
- }
-
- String action = intent.getStringExtra(KEY_ACTION);
- Log.i(TAG, "Starting " + action + " from foreground activity.");
-
- switch (action) {
- case ACTION_PLAY_VIDEO:
- playVideo();
- break;
- case ACTION_PLAY_VIDEO_PICTURE_IN_PICTURE_MODE:
- playVideo();
- this.enterPictureInPictureMode();
- break;
- default:
- Log.e(TAG, "Intent had invalid action " + action);
- finish();
- }
- delay();
- }
-
- private void playVideo() {
- setContentView(R.layout.activity_main);
- VideoView videoView = (VideoView)findViewById(R.id.video_player_view);
- videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.colors_video);
- videoView.start();
- }
-
- private void delay() {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- SystemClock.sleep(DELAY_MILLIS);
- return null;
- }
- @Override
- protected void onPostExecute(Void nothing) {
- finish();
- }
- }.execute();
- }
-}
-
-
-
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/WakelockLoadTestRunnable.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/WakelockLoadTestRunnable.java
deleted file mode 100644
index 1a3d32a..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/WakelockLoadTestRunnable.java
+++ /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.
- */
-package com.android.server.cts.device.statsd;
-
-import android.content.Context;
-import android.os.PowerManager;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.util.concurrent.CountDownLatch;
-
-public class WakelockLoadTestRunnable implements Runnable {
- String tag;
- CountDownLatch latch;
- WakelockLoadTestRunnable(String t, CountDownLatch l) {
- tag = t;
- latch = l;
- }
- @Override
- public void run() {
- Context context = InstrumentationRegistry.getContext();
- PowerManager pm = context.getSystemService(PowerManager.class);
- PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
- long sleepTimeNs = 700_000;
-
- for (int i = 0; i < 1000; i++) {
- wl.acquire();
- long startTime = System.nanoTime();
- while (System.nanoTime() - startTime < sleepTimeNs) {}
- wl.release();
- startTime = System.nanoTime();
- while (System.nanoTime() - startTime < sleepTimeNs) {}
- }
- latch.countDown();
- }
-
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java b/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
deleted file mode 100644
index 032297e..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
+++ /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.
- */
-package android.cts.statsd.alarm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.AtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.Alarm;
-import com.android.internal.os.StatsdConfigProto.IncidentdDetails;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.Subscription;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.util.List;
-
-/**
- * Statsd Anomaly Detection tests.
- */
-public class AlarmTests extends AtomTestCase {
-
- private static final String TAG = "Statsd.AnomalyDetectionTests";
-
- private static final boolean INCIDENTD_TESTS_ENABLED = false;
-
- // Config constants
- private static final int ALARM_ID = 11;
- private static final int SUBSCRIPTION_ID_INCIDENTD = 41;
- private static final int INCIDENTD_SECTION = -1;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- if (!INCIDENTD_TESTS_ENABLED) {
- CLog.w(TAG, TAG + " alarm tests are disabled by a flag. Change flag to true to run");
- }
- }
-
- public void testAlarm() throws Exception {
- StatsdConfig.Builder config = getBaseConfig();
- turnScreenOn();
- uploadConfig(config);
-
- String markTime = getCurrentLogcatDate();
- Thread.sleep(9_000);
-
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
- }
-
-
- private final StatsdConfig.Builder getBaseConfig() throws Exception {
- return createConfigBuilder()
- .addAlarm(Alarm.newBuilder().setId(ALARM_ID).setOffsetMillis(2).setPeriodMillis(
- 5_000) // every 5 seconds.
- )
- .addSubscription(Subscription.newBuilder()
- .setId(SUBSCRIPTION_ID_INCIDENTD)
- .setRuleType(Subscription.RuleType.ALARM)
- .setRuleId(ALARM_ID)
- .setIncidentdDetails(
- IncidentdDetails.newBuilder().addSection(INCIDENTD_SECTION)));
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java b/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
deleted file mode 100644
index d6c1107..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
+++ /dev/null
@@ -1,471 +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 android.cts.statsd.alert;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.AtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.Alert;
-import com.android.internal.os.StatsdConfigProto.CountMetric;
-import com.android.internal.os.StatsdConfigProto.DurationMetric;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.IncidentdDetails;
-import com.android.internal.os.StatsdConfigProto.PerfettoDetails;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.Subscription;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-import com.android.os.AtomsProto.AnomalyDetected;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.KernelWakelock;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.tradefed.log.LogUtil.CLog;
-import java.util.List;
-
-/**
- * Statsd Anomaly Detection tests.
- */
-public class AnomalyDetectionTests extends AtomTestCase {
-
- private static final String TAG = "Statsd.AnomalyDetectionTests";
-
- private static final boolean INCIDENTD_TESTS_ENABLED = false;
- private static final boolean PERFETTO_TESTS_ENABLED = true;
-
- private static final int WAIT_AFTER_BREADCRUMB_MS = 2000;
-
- // Config constants
- private static final int APP_BREADCRUMB_REPORTED_MATCH_START_ID = 1;
- private static final int APP_BREADCRUMB_REPORTED_MATCH_STOP_ID = 2;
- private static final int METRIC_ID = 8;
- private static final int ALERT_ID = 11;
- private static final int SUBSCRIPTION_ID_INCIDENTD = 41;
- private static final int SUBSCRIPTION_ID_PERFETTO = 42;
- private static final int ANOMALY_DETECT_MATCH_ID = 10;
- private static final int ANOMALY_EVENT_ID = 101;
- private static final int INCIDENTD_SECTION = -1;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- if (!INCIDENTD_TESTS_ENABLED) {
- CLog.w(TAG, TAG + " anomaly tests are disabled by a flag. Change flag to true to run");
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- if (PERFETTO_TESTS_ENABLED) {
- //Deadline to finish trace collection
- final long deadLine = System.currentTimeMillis() + 10000;
- while (isSystemTracingEnabled()) {
- if (System.currentTimeMillis() > deadLine) {
- CLog.w("/sys/kernel/debug/tracing/tracing_on is still 1 after 10 secs : " + isSystemTracingEnabled());
- break;
- }
- CLog.d("Waiting to finish collecting traces. ");
- Thread.sleep(WAIT_TIME_SHORT);
- }
- }
- }
-
- // Tests that anomaly detection for count works.
- // Also tests that anomaly detection works when spanning multiple buckets.
- public void testCountAnomalyDetection() throws Exception {
- StatsdConfig.Builder config = getBaseConfig(10, 20, 2 /* threshold: > 2 counts */)
- .addCountMetric(CountMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setBucket(TimeUnit.CTS) // 1 second
- // Slice by label
- .setDimensionsInWhat(FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
- )
- )
- );
- uploadConfig(config);
-
- String markTime = getCurrentLogcatDate();
- // count(label=6) -> 1 (not an anomaly, since not "greater than 2")
- doAppBreadcrumbReportedStart(6);
- Thread.sleep(500);
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
- // count(label=6) -> 2 (not an anomaly, since not "greater than 2")
- doAppBreadcrumbReportedStart(6);
- Thread.sleep(500);
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
- // count(label=12) -> 1 (not an anomaly, since not "greater than 2")
- doAppBreadcrumbReportedStart(12);
- Thread.sleep(1000);
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
- doAppBreadcrumbReportedStart(6); // count(label=6) -> 3 (anomaly, since "greater than 2"!)
- Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- assertWithMessage("Expected anomaly").that(data).hasSize(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
- }
-
- // Tests that anomaly detection for duration works.
- // Also tests that refractory periods in anomaly detection work.
- public void testDurationAnomalyDetection() throws Exception {
- final int APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE = 1423;
- StatsdConfig.Builder config =
- getBaseConfig(17, 17, 10_000_000_000L /*threshold: > 10 seconds in nanoseconds*/)
- .addDurationMetric(DurationMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE) // predicate below
- .setAggregationType(DurationMetric.AggregationType.SUM)
- .setBucket(TimeUnit.CTS) // 1 second
- )
- .addPredicate(StatsdConfigProto.Predicate.newBuilder()
- .setId(APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE)
- .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_MATCH_STOP_ID)
- )
- );
- uploadConfig(config);
-
- // Since timing is crucial and checking logcat for incidentd is slow, we don't test for it.
-
- // Test that alarm doesn't fire early.
- String markTime = getCurrentLogcatDate();
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(6_000); // Recorded duration at end: 6s
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
- doAppBreadcrumbReportedStop(1);
- Thread.sleep(4_000); // Recorded duration at end: 6s
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
- // Test that alarm does fire when it is supposed to (after 4s, plus up to 5s alarm delay).
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(9_000); // Recorded duration at end: 13s
- List<EventMetricData> data = getEventMetricDataList();
- assertWithMessage("Expected anomaly").that(data).hasSize(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-
- // Now test that the refractory period is obeyed.
- markTime = getCurrentLogcatDate();
- doAppBreadcrumbReportedStop(1);
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(3_000); // Recorded duration at end: 13s
- // NB: the previous getEventMetricDataList also removes the report, so size is back to 0.
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
- // Test that detection works again after refractory period finishes.
- doAppBreadcrumbReportedStop(1);
- Thread.sleep(8_000); // Recorded duration at end: 9s
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(15_000); // Recorded duration at end: 15s
- // We can do an incidentd test now that all the timing issues are done.
- data = getEventMetricDataList();
- assertWithMessage("Expected anomaly").that(data).hasSize(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
-
- doAppBreadcrumbReportedStop(1);
- }
-
- // Tests that anomaly detection for duration works even when the alarm fires too late.
- public void testDurationAnomalyDetectionForLateAlarms() throws Exception {
- final int APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE = 1423;
- StatsdConfig.Builder config =
- getBaseConfig(50, 0, 6_000_000_000L /* threshold: > 6 seconds in nanoseconds */)
- .addDurationMetric(DurationMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(
- APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE) // Predicate below.
- .setAggregationType(DurationMetric.AggregationType.SUM)
- .setBucket(TimeUnit.CTS) // 1 second
- )
- .addPredicate(StatsdConfigProto.Predicate.newBuilder()
- .setId(APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE)
- .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_MATCH_STOP_ID)
- )
- );
- uploadConfig(config);
-
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(5_000);
- doAppBreadcrumbReportedStop(1);
- Thread.sleep(2_000);
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
- // Test that alarm does fire when it is supposed to.
- // The anomaly occurs in 1s, but alarms won't fire that quickly.
- // It is likely that the alarm will only fire after this period is already over, but the
- // anomaly should nonetheless be detected when the event stops.
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(1_200);
- // Anomaly should be detected here if the alarm didn't fire yet.
- doAppBreadcrumbReportedStop(1);
- Thread.sleep(200);
- List<EventMetricData> data = getEventMetricDataList();
- if (data.size() == 2) {
- // Although we expect that the alarm won't fire, we certainly cannot demand that.
- CLog.w(TAG, "The anomaly was detected twice. Presumably the alarm did manage to fire.");
- }
- assertThat(data.size()).isAnyOf(1, 2);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
- }
-
- // Tests that anomaly detection for value works.
- public void testValueAnomalyDetection() throws Exception {
- StatsdConfig.Builder config = getBaseConfig(4, 0, 6 /* threshold: value > 6 */)
- .addValueMetric(ValueMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setBucket(TimeUnit.ONE_MINUTE)
- // Get the label field's value:
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
- )
-
- );
- uploadConfig(config);
-
- String markTime = getCurrentLogcatDate();
- doAppBreadcrumbReportedStart(6); // value = 6, which is NOT > trigger
- Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
- doAppBreadcrumbReportedStart(14); // value = 14 > trigger
- Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- assertWithMessage("Expected anomaly").that(data).hasSize(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
- }
-
- // Test that anomaly detection integrates with perfetto properly.
- public void testPerfetto() throws Exception {
- String chars = getDevice().getProperty("ro.build.characteristics");
- if (chars.contains("watch")) {
- return;
- }
-
- if (PERFETTO_TESTS_ENABLED) resetPerfettoGuardrails();
-
- StatsdConfig.Builder config = getBaseConfig(4, 0, 6 /* threshold: value > 6 */)
- .addSubscription(Subscription.newBuilder()
- .setId(SUBSCRIPTION_ID_PERFETTO)
- .setRuleType(Subscription.RuleType.ALERT)
- .setRuleId(ALERT_ID)
- .setPerfettoDetails(PerfettoDetails.newBuilder()
- .setTraceConfig(getPerfettoConfig()))
- )
- .addValueMetric(ValueMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setBucket(TimeUnit.ONE_MINUTE)
- // Get the label field's value:
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
- )
-
- );
- uploadConfig(config);
-
- String markTime = getCurrentLogcatDate();
- doAppBreadcrumbReportedStart(6); // value = 6, which is NOT > trigger
- Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
- if (PERFETTO_TESTS_ENABLED) assertThat(isSystemTracingEnabled()).isFalse();
-
- doAppBreadcrumbReportedStart(14); // value = 14 > trigger
- Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- assertWithMessage("Expected anomaly").that(data).hasSize(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-
- // Pool a few times to allow for statsd <-> traced <-> traced_probes communication to happen.
- if (PERFETTO_TESTS_ENABLED) {
- boolean tracingEnabled = false;
- for (int i = 0; i < 5; i++) {
- if (isSystemTracingEnabled()) {
- tracingEnabled = true;
- break;
- }
- Thread.sleep(1000);
- }
- assertThat(tracingEnabled).isTrue();
- }
- }
-
- // Tests that anomaly detection for gauge works.
- public void testGaugeAnomalyDetection() throws Exception {
- StatsdConfig.Builder config = getBaseConfig(1, 20, 6 /* threshold: value > 6 */)
- .addGaugeMetric(GaugeMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setBucket(TimeUnit.CTS)
- // Get the label field's value into the gauge:
- .setGaugeFieldsFilter(
- FieldFilter.newBuilder().setFields(FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
- )
- )
- );
- uploadConfig(config);
-
- String markTime = getCurrentLogcatDate();
- doAppBreadcrumbReportedStart(6); // gauge = 6, which is NOT > trigger
- Thread.sleep(Math.max(WAIT_AFTER_BREADCRUMB_MS, 1_100)); // Must be >1s to push next bucket.
- assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
- // We waited for >1s above, so we are now in the next bucket (which is essential).
- doAppBreadcrumbReportedStart(14); // gauge = 14 > trigger
- Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- assertWithMessage("Expected anomaly").that(data).hasSize(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
- if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
- }
-
- // Test that anomaly detection for pulled metrics work.
- public void testPulledAnomalyDetection() throws Exception {
- final int ATOM_ID = Atom.KERNEL_WAKELOCK_FIELD_NUMBER; // A pulled atom
- final int SLICE_BY_FIELD = KernelWakelock.NAME_FIELD_NUMBER;
- final int VALUE_FIELD = KernelWakelock.VERSION_FIELD_NUMBER; // Something that will be > 0.
- final int ATOM_MATCHER_ID = 300;
-
- StatsdConfig.Builder config = getBaseConfig(10, 20, 0 /* threshold: value > 0 */)
- .addAllowedLogSource("AID_SYSTEM")
- // Track the ATOM_ID pulled atom
- .addAtomMatcher(StatsdConfigProto.AtomMatcher.newBuilder()
- .setId(ATOM_MATCHER_ID)
- .setSimpleAtomMatcher(StatsdConfigProto.SimpleAtomMatcher.newBuilder()
- .setAtomId(ATOM_ID)))
- .addGaugeMetric(GaugeMetric.newBuilder()
- .setId(METRIC_ID)
- .setWhat(ATOM_MATCHER_ID)
- .setBucket(TimeUnit.CTS)
- .setSamplingType(GaugeMetric.SamplingType.RANDOM_ONE_SAMPLE)
- // Slice by SLICE_BY_FIELD (typical usecase)
- .setDimensionsInWhat(FieldMatcher.newBuilder()
- .setField(ATOM_ID)
- .addChild(FieldMatcher.newBuilder().setField(SLICE_BY_FIELD))
- )
- // Track the VALUE_FIELD (anomaly detection requires exactly one field here)
- .setGaugeFieldsFilter(
- FieldFilter.newBuilder().setFields(FieldMatcher.newBuilder()
- .setField(ATOM_ID)
- .addChild(FieldMatcher.newBuilder().setField(VALUE_FIELD))
- )
- )
- );
- uploadConfig(config);
-
- Thread.sleep(6_000); // Wait long enough to ensure AlarmManager signals >= 1 pull
-
- List<EventMetricData> data = getEventMetricDataList();
- // There will likely be many anomalies (one for each dimension). There must be at least one.
- assertThat(data.size()).isAtLeast(1);
- assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
- }
-
-
- private final StatsdConfig.Builder getBaseConfig(int numBuckets,
- int refractorySecs,
- long triggerIfSumGt) throws Exception {
- return createConfigBuilder()
- // Items of relevance for detecting the anomaly:
- .addAtomMatcher(
- StatsdConfigProto.AtomMatcher.newBuilder()
- .setId(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
- .setSimpleAtomMatcher(
- StatsdConfigProto.SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- // Event only when the uid is this app's uid.
- .addFieldValueMatcher(createFvm(AppBreadcrumbReported.UID_FIELD_NUMBER)
- .setEqInt(getHostUid()))
- .addFieldValueMatcher(
- createFvm(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .setEqInt(AppBreadcrumbReported.State.START.ordinal()))))
- .addAtomMatcher(
- StatsdConfigProto.AtomMatcher.newBuilder()
- .setId(APP_BREADCRUMB_REPORTED_MATCH_STOP_ID)
- .setSimpleAtomMatcher(
- StatsdConfigProto.SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- // Event only when the uid is this app's uid.
- .addFieldValueMatcher(createFvm(AppBreadcrumbReported.UID_FIELD_NUMBER)
- .setEqInt(getHostUid()))
- .addFieldValueMatcher(
- createFvm(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .setEqInt(AppBreadcrumbReported.State.STOP.ordinal()))))
- .addAlert(Alert.newBuilder()
- .setId(ALERT_ID)
- .setMetricId(METRIC_ID) // The metric itself must yet be added by the test.
- .setNumBuckets(numBuckets)
- .setRefractoryPeriodSecs(refractorySecs)
- .setTriggerIfSumGt(triggerIfSumGt))
- .addSubscription(
- Subscription.newBuilder()
- .setId(SUBSCRIPTION_ID_INCIDENTD)
- .setRuleType(Subscription.RuleType.ALERT)
- .setRuleId(ALERT_ID)
- .setIncidentdDetails(IncidentdDetails.newBuilder().addSection(INCIDENTD_SECTION)))
- // We want to trigger anomalies on METRIC_ID, but don't want the actual data.
- .addNoReportMetric(METRIC_ID)
-
- // Items of relevance to reporting the anomaly (we do want this data):
- .addAtomMatcher(
- StatsdConfigProto.AtomMatcher.newBuilder()
- .setId(ANOMALY_DETECT_MATCH_ID)
- .setSimpleAtomMatcher(
- StatsdConfigProto.SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.ANOMALY_DETECTED_FIELD_NUMBER)
- .addFieldValueMatcher(createFvm(AnomalyDetected.CONFIG_UID_FIELD_NUMBER)
- .setEqInt(getHostUid()))
- .addFieldValueMatcher(createFvm(AnomalyDetected.CONFIG_ID_FIELD_NUMBER)
- .setEqInt(CONFIG_ID))))
- .addEventMetric(StatsdConfigProto.EventMetric.newBuilder()
- .setId(ANOMALY_EVENT_ID)
- .setWhat(ANOMALY_DETECT_MATCH_ID));
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
deleted file mode 100644
index 8ce54f3..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ /dev/null
@@ -1,1164 +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.cts.statsd.atom;
-
-import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_APK;
-import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_PACKAGE;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.BatteryStatsProto;
-import android.os.StatsDataDumpProto;
-import android.service.battery.BatteryServiceDumpProto;
-import android.service.batterystats.BatteryStatsServiceDumpProto;
-import android.service.procstats.ProcessStatsServiceDumpProto;
-
-import com.android.annotations.Nullable;
-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.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.ProcessStatsPackageProto;
-import com.android.os.AtomsProto.ProcessStatsProto;
-import com.android.os.AtomsProto.ProcessStatsStateProto;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.DurationMetricData;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.CountMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.ValueMetricData;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-
-import com.google.common.collect.Range;
-import com.google.common.io.Files;
-import com.google.protobuf.ByteString;
-
-import perfetto.protos.PerfettoConfig.DataSourceConfig;
-import perfetto.protos.PerfettoConfig.FtraceConfig;
-import perfetto.protos.PerfettoConfig.TraceConfig;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Random;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-/**
- * Base class for testing Statsd atoms.
- * Validates reporting of statsd logging based on different events
- */
-public class AtomTestCase extends BaseTestCase {
-
- /**
- * Run tests that are optional; they are not valid CTS tests per se, since not all devices can
- * be expected to pass them, but can be run, if desired, to ensure they work when appropriate.
- */
- public static final boolean OPTIONAL_TESTS_ENABLED = false;
-
- public static final String UPDATE_CONFIG_CMD = "cmd stats config update";
- public static final String DUMP_REPORT_CMD = "cmd stats dump-report";
- public static final String DUMP_BATTERY_CMD = "dumpsys battery";
- public static final String DUMP_BATTERYSTATS_CMD = "dumpsys batterystats";
- public static final String DUMPSYS_STATS_CMD = "dumpsys stats";
- public static final String DUMP_PROCSTATS_CMD = "dumpsys procstats";
- public static final String REMOVE_CONFIG_CMD = "cmd stats config remove";
- /** ID of the config, which evaluates to -1572883457. */
- public static final long CONFIG_ID = "cts_config".hashCode();
-
- public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
- public static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
- public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
- public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
- public static final String FEATURE_CAMERA = "android.hardware.camera";
- public static final String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash";
- public static final String FEATURE_CAMERA_FRONT = "android.hardware.camera.front";
- public static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
- public static final String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
- public static final String FEATURE_PC = "android.hardware.type.pc";
- public static final String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
- public static final String FEATURE_TELEPHONY = "android.hardware.telephony";
- public static final String FEATURE_WATCH = "android.hardware.type.watch";
- public static final String FEATURE_WIFI = "android.hardware.wifi";
- public static final String FEATURE_INCREMENTAL_DELIVERY =
- "android.software.incremental_delivery";
-
- // Telephony phone types
- public static final int PHONE_TYPE_GSM = 1;
- public static final int PHONE_TYPE_CDMA = 2;
- public static final int PHONE_TYPE_CDMA_LTE = 6;
-
- protected static final int WAIT_TIME_SHORT = 1000;
- protected static final int WAIT_TIME_LONG = 2_000;
-
- protected static final long SCREEN_STATE_CHANGE_TIMEOUT = 4000;
- protected static final long SCREEN_STATE_POLLING_INTERVAL = 500;
-
- protected static final long NS_PER_SEC = (long) 1E+9;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- // Uninstall to clear the history in case it's still on the device.
- removeConfig(CONFIG_ID);
- getReportList(); // Clears data.
- }
-
- @Override
- protected void tearDown() throws Exception {
- removeConfig(CONFIG_ID);
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
- super.tearDown();
- }
-
- /**
- * Determines whether logcat indicates that incidentd fired since the given device date.
- */
- protected boolean didIncidentdFireSince(String date) throws Exception {
- final String INCIDENTD_TAG = "incidentd";
- final String INCIDENTD_STARTED_STRING = "reportIncident";
- // TODO: Do something more robust than this in case of delayed logging.
- Thread.sleep(1000);
- String log = getLogcatSince(date, String.format(
- "-s %s -e %s", INCIDENTD_TAG, INCIDENTD_STARTED_STRING));
- return log.contains(INCIDENTD_STARTED_STRING);
- }
-
- protected boolean checkDeviceFor(String methodName) throws Exception {
- try {
- installPackage(DEVICE_SIDE_TEST_APK, true);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".Checkers", methodName);
- // Test passes, meaning that the answer is true.
- LogUtil.CLog.d(methodName + "() indicates true.");
- return true;
- } catch (AssertionError e) {
- // Method is designed to fail if the answer is false.
- LogUtil.CLog.d(methodName + "() indicates false.");
- return false;
- }
- }
-
- /**
- * Returns a protobuf-encoded perfetto config that enables the kernel
- * ftrace tracer with sched_switch for 10 seconds.
- */
- protected ByteString getPerfettoConfig() {
- TraceConfig.Builder builder = TraceConfig.newBuilder();
-
- TraceConfig.BufferConfig buffer = TraceConfig.BufferConfig
- .newBuilder()
- .setSizeKb(128)
- .build();
- builder.addBuffers(buffer);
-
- FtraceConfig ftraceConfig = FtraceConfig.newBuilder()
- .addFtraceEvents("sched/sched_switch")
- .build();
- DataSourceConfig dataSourceConfig = DataSourceConfig.newBuilder()
- .setName("linux.ftrace")
- .setTargetBuffer(0)
- .setFtraceConfig(ftraceConfig)
- .build();
- TraceConfig.DataSource dataSource = TraceConfig.DataSource
- .newBuilder()
- .setConfig(dataSourceConfig)
- .build();
- builder.addDataSources(dataSource);
-
- builder.setDurationMs(10000);
- builder.setAllowUserBuildTracing(true);
-
- TraceConfig.IncidentReportConfig incident = TraceConfig.IncidentReportConfig
- .newBuilder()
- .setDestinationPackage("foo.bar.baz")
- .build();
- builder.setIncidentReportConfig(incident);
-
- // To avoid being hit with guardrails firing in multiple test runs back
- // to back, we set a unique session key for each config.
- Random random = new Random();
- StringBuilder sessionNameBuilder = new StringBuilder("statsd-cts-");
- sessionNameBuilder.append(random.nextInt() & Integer.MAX_VALUE);
- builder.setUniqueSessionName(sessionNameBuilder.toString());
-
- return builder.build().toByteString();
- }
-
- /**
- * Resets the state of the Perfetto guardrails. This avoids that the test fails if it's
- * run too close of for too many times and hits the upload limit.
- */
- protected void resetPerfettoGuardrails() throws Exception {
- final String cmd = "perfetto --reset-guardrails";
- CommandResult cr = getDevice().executeShellV2Command(cmd);
- if (cr.getStatus() != CommandStatus.SUCCESS)
- throw new Exception(String.format("Error while executing %s: %s %s", cmd, cr.getStdout(), cr.getStderr()));
- }
-
- private String probe(String path) throws Exception {
- return getDevice().executeShellCommand("if [ -e " + path + " ] ; then"
- + " cat " + path + " ; else echo -1 ; fi");
- }
-
- /**
- * Determines whether perfetto enabled the kernel ftrace tracer.
- */
- protected boolean isSystemTracingEnabled() throws Exception {
- final String traceFsPath = "/sys/kernel/tracing/tracing_on";
- String tracing_on = probe(traceFsPath);
- if (tracing_on.startsWith("0")) return false;
- if (tracing_on.startsWith("1")) return true;
-
- // fallback to debugfs
- LogUtil.CLog.d("Unexpected state for %s = %s. Falling back to debugfs", traceFsPath,
- tracing_on);
-
- final String debugFsPath = "/sys/kernel/debug/tracing/tracing_on";
- tracing_on = probe(debugFsPath);
- if (tracing_on.startsWith("0")) return false;
- if (tracing_on.startsWith("1")) return true;
- throw new Exception(String.format("Unexpected state for %s = %s", traceFsPath, tracing_on));
- }
-
- protected static StatsdConfig.Builder createConfigBuilder() {
- return StatsdConfig.newBuilder()
- .setId(CONFIG_ID)
- .addAllowedLogSource("AID_SYSTEM")
- .addAllowedLogSource("AID_BLUETOOTH")
- // TODO(b/134091167): Fix bluetooth source name issue in Auto platform.
- .addAllowedLogSource("com.android.bluetooth")
- .addAllowedLogSource("AID_LMKD")
- .addAllowedLogSource("AID_RADIO")
- .addAllowedLogSource("AID_ROOT")
- .addAllowedLogSource("AID_STATSD")
- .addAllowedLogSource("com.android.systemui")
- .addAllowedLogSource(DeviceAtomTestCase.DEVICE_SIDE_TEST_PACKAGE)
- .addDefaultPullPackages("AID_RADIO")
- .addDefaultPullPackages("AID_SYSTEM")
- .addWhitelistedAtomIds(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
- }
-
- protected void createAndUploadConfig(int atomTag) throws Exception {
- StatsdConfig.Builder conf = createConfigBuilder();
- addAtomEvent(conf, atomTag);
- uploadConfig(conf);
- }
-
- protected void uploadConfig(StatsdConfig.Builder config) throws Exception {
- uploadConfig(config.build());
- }
-
- protected void uploadConfig(StatsdConfig config) throws Exception {
- LogUtil.CLog.d("Uploading the following config:\n" + config.toString());
- File configFile = File.createTempFile("statsdconfig", ".config");
- configFile.deleteOnExit();
- Files.write(config.toByteArray(), configFile);
- String remotePath = "/data/local/tmp/" + configFile.getName();
- getDevice().pushFile(configFile, remotePath);
- getDevice().executeShellCommand(
- String.join(" ", "cat", remotePath, "|", UPDATE_CONFIG_CMD,
- String.valueOf(CONFIG_ID)));
- getDevice().executeShellCommand("rm " + remotePath);
- }
-
- protected void removeConfig(long configId) throws Exception {
- getDevice().executeShellCommand(
- String.join(" ", REMOVE_CONFIG_CMD, String.valueOf(configId)));
- }
-
- /** Gets the statsd report and sorts it. Note that this also deletes that report from statsd. */
- protected List<EventMetricData> getEventMetricDataList() throws Exception {
- ConfigMetricsReportList reportList = getReportList();
- return getEventMetricDataList(reportList);
- }
-
- /**
- * Gets a List of sorted ConfigMetricsReports from ConfigMetricsReportList.
- */
- protected List<ConfigMetricsReport> getSortedConfigMetricsReports(
- ConfigMetricsReportList configMetricsReportList) {
- return configMetricsReportList.getReportsList().stream()
- .sorted(Comparator.comparing(ConfigMetricsReport::getCurrentReportWallClockNanos))
- .collect(Collectors.toList());
- }
-
- /**
- * Extracts and sorts the EventMetricData from the given ConfigMetricsReportList (which must
- * contain a single report).
- */
- protected List<EventMetricData> getEventMetricDataList(ConfigMetricsReportList reportList)
- throws Exception {
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- ConfigMetricsReport report = reportList.getReports(0);
-
- List<EventMetricData> data = new ArrayList<>();
- for (StatsLogReport metric : report.getMetricsList()) {
- data.addAll(metric.getEventMetrics().getDataList());
- }
- data.sort(Comparator.comparing(EventMetricData::getElapsedTimestampNanos));
-
- LogUtil.CLog.d("Get EventMetricDataList as following:\n");
- for (EventMetricData d : data) {
- LogUtil.CLog.d("Atom at " + d.getElapsedTimestampNanos() + ":\n" + d.getAtom().toString());
- }
- return data;
- }
-
- protected List<Atom> getGaugeMetricDataList() throws Exception {
- return getGaugeMetricDataList(/*checkTimestampTruncated=*/false);
- }
-
- protected List<Atom> getGaugeMetricDataList(boolean checkTimestampTruncated) throws Exception {
- ConfigMetricsReportList reportList = getReportList();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
-
- // only config
- ConfigMetricsReport report = reportList.getReports(0);
- assertThat(report.getMetricsCount()).isEqualTo(1);
-
- List<Atom> data = new ArrayList<>();
- for (GaugeMetricData gaugeMetricData :
- report.getMetrics(0).getGaugeMetrics().getDataList()) {
- assertThat(gaugeMetricData.getBucketInfoCount()).isEqualTo(1);
- GaugeBucketInfo bucketInfo = gaugeMetricData.getBucketInfo(0);
- for (Atom atom : bucketInfo.getAtomList()) {
- data.add(atom);
- }
- if (checkTimestampTruncated) {
- for (long timestampNs: bucketInfo.getElapsedTimestampNanosList()) {
- assertTimestampIsTruncated(timestampNs);
- }
- }
- }
-
- LogUtil.CLog.d("Get GaugeMetricDataList as following:\n");
- for (Atom d : data) {
- LogUtil.CLog.d("Atom:\n" + d.toString());
- }
- return data;
- }
-
- /**
- * Gets the statsd report and extract duration metric data.
- * Note that this also deletes that report from statsd.
- */
- protected List<DurationMetricData> getDurationMetricDataList() throws Exception {
- ConfigMetricsReportList reportList = getReportList();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- ConfigMetricsReport report = reportList.getReports(0);
-
- List<DurationMetricData> data = new ArrayList<>();
- for (StatsLogReport metric : report.getMetricsList()) {
- data.addAll(metric.getDurationMetrics().getDataList());
- }
-
- LogUtil.CLog.d("Got DurationMetricDataList as following:\n");
- for (DurationMetricData d : data) {
- LogUtil.CLog.d("Duration " + d);
- }
- return data;
- }
-
- /**
- * Gets the statsd report and extract count metric data.
- * Note that this also deletes that report from statsd.
- */
- protected List<CountMetricData> getCountMetricDataList() throws Exception {
- ConfigMetricsReportList reportList = getReportList();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- ConfigMetricsReport report = reportList.getReports(0);
-
- List<CountMetricData> data = new ArrayList<>();
- for (StatsLogReport metric : report.getMetricsList()) {
- data.addAll(metric.getCountMetrics().getDataList());
- }
-
- LogUtil.CLog.d("Got CountMetricDataList as following:\n");
- for (CountMetricData d : data) {
- LogUtil.CLog.d("Count " + d);
- }
- return data;
- }
-
- /**
- * Gets the statsd report and extract value metric data.
- * Note that this also deletes that report from statsd.
- */
- protected List<ValueMetricData> getValueMetricDataList() throws Exception {
- ConfigMetricsReportList reportList = getReportList();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- ConfigMetricsReport report = reportList.getReports(0);
-
- List<ValueMetricData> data = new ArrayList<>();
- for (StatsLogReport metric : report.getMetricsList()) {
- data.addAll(metric.getValueMetrics().getDataList());
- }
-
- LogUtil.CLog.d("Got ValueMetricDataList as following:\n");
- for (ValueMetricData d : data) {
- LogUtil.CLog.d("Value " + d);
- }
- return data;
- }
-
- protected StatsLogReport getStatsLogReport() throws Exception {
- ConfigMetricsReport report = getConfigMetricsReport();
- assertThat(report.hasUidMap()).isTrue();
- assertThat(report.getMetricsCount()).isEqualTo(1);
- return report.getMetrics(0);
- }
-
- protected ConfigMetricsReport getConfigMetricsReport() throws Exception {
- ConfigMetricsReportList reportList = getReportList();
- assertThat(reportList.getReportsCount()).isEqualTo(1);
- return reportList.getReports(0);
- }
-
- /** Gets the statsd report. Note that this also deletes that report from statsd. */
- protected ConfigMetricsReportList getReportList() throws Exception {
- try {
- ConfigMetricsReportList reportList = getDump(ConfigMetricsReportList.parser(),
- String.join(" ", DUMP_REPORT_CMD, String.valueOf(CONFIG_ID),
- "--include_current_bucket", "--proto"));
- return reportList;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to fetch and parse the statsd output report. "
- + "Perhaps there is not a valid statsd config for the requested "
- + "uid=" + getHostUid() + ", id=" + CONFIG_ID + ".");
- throw (e);
- }
- }
-
- protected BatteryStatsProto getBatteryStatsProto() throws Exception {
- try {
- BatteryStatsProto batteryStatsProto = getDump(BatteryStatsServiceDumpProto.parser(),
- String.join(" ", DUMP_BATTERYSTATS_CMD,
- "--proto")).getBatterystats();
- LogUtil.CLog.d("Got batterystats:\n " + batteryStatsProto.toString());
- return batteryStatsProto;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to dump batterystats proto");
- throw (e);
- }
- }
-
- /** Gets reports from the statsd data incident section from the stats dumpsys. */
- protected List<ConfigMetricsReportList> getReportsFromStatsDataDumpProto() throws Exception {
- try {
- StatsDataDumpProto statsProto = getDump(StatsDataDumpProto.parser(),
- String.join(" ", DUMPSYS_STATS_CMD, "--proto"));
- // statsProto holds repeated bytes, which we must parse into ConfigMetricsReportLists.
- List<ConfigMetricsReportList> reports
- = new ArrayList<>(statsProto.getConfigMetricsReportListCount());
- for (ByteString reportListBytes : statsProto.getConfigMetricsReportListList()) {
- reports.add(ConfigMetricsReportList.parseFrom(reportListBytes));
- }
- LogUtil.CLog.d("Got dumpsys stats output:\n " + reports.toString());
- return reports;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to dumpsys stats proto");
- throw (e);
- }
- }
-
- protected List<ProcessStatsProto> getProcStatsProto() throws Exception {
- try {
-
- List<ProcessStatsProto> processStatsProtoList =
- new ArrayList<ProcessStatsProto>();
- android.service.procstats.ProcessStatsSectionProto sectionProto = getDump(
- ProcessStatsServiceDumpProto.parser(),
- String.join(" ", DUMP_PROCSTATS_CMD,
- "--proto")).getProcstatsNow();
- for (android.service.procstats.ProcessStatsProto stats :
- sectionProto.getProcessStatsList()) {
- ProcessStatsProto procStats = ProcessStatsProto.parser().parseFrom(
- stats.toByteArray());
- processStatsProtoList.add(procStats);
- }
- LogUtil.CLog.d("Got procstats:\n ");
- for (ProcessStatsProto processStatsProto : processStatsProtoList) {
- LogUtil.CLog.d(processStatsProto.toString());
- }
- return processStatsProtoList;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to dump procstats proto");
- throw (e);
- }
- }
-
- /*
- * Get all procstats package data in proto
- */
- protected List<ProcessStatsPackageProto> getAllProcStatsProto() throws Exception {
- try {
- android.service.procstats.ProcessStatsSectionProto sectionProto = getDump(
- ProcessStatsServiceDumpProto.parser(),
- String.join(" ", DUMP_PROCSTATS_CMD,
- "--proto")).getProcstatsOver24Hrs();
- List<ProcessStatsPackageProto> processStatsProtoList =
- new ArrayList<ProcessStatsPackageProto>();
- for (android.service.procstats.ProcessStatsPackageProto pkgStast :
- sectionProto.getPackageStatsList()) {
- ProcessStatsPackageProto pkgAtom =
- ProcessStatsPackageProto.parser().parseFrom(pkgStast.toByteArray());
- processStatsProtoList.add(pkgAtom);
- }
- LogUtil.CLog.d("Got procstats:\n ");
- for (ProcessStatsPackageProto processStatsProto : processStatsProtoList) {
- LogUtil.CLog.d(processStatsProto.toString());
- }
- return processStatsProtoList;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to dump procstats proto");
- throw (e);
- }
- }
-
- /*
- * Get all processes' procstats statsd data in proto
- */
- protected List<android.service.procstats.ProcessStatsProto> getAllProcStatsProtoForStatsd()
- throws Exception {
- try {
- android.service.procstats.ProcessStatsSectionProto sectionProto = getDump(
- android.service.procstats.ProcessStatsSectionProto.parser(),
- String.join(" ", DUMP_PROCSTATS_CMD,
- "--statsd"));
- List<android.service.procstats.ProcessStatsProto> processStatsProtoList
- = sectionProto.getProcessStatsList();
- LogUtil.CLog.d("Got procstats:\n ");
- for (android.service.procstats.ProcessStatsProto processStatsProto
- : processStatsProtoList) {
- LogUtil.CLog.d(processStatsProto.toString());
- }
- return processStatsProtoList;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to dump procstats proto");
- throw (e);
- }
- }
-
- protected boolean hasBattery() throws Exception {
- try {
- BatteryServiceDumpProto batteryProto = getDump(BatteryServiceDumpProto.parser(),
- String.join(" ", DUMP_BATTERY_CMD, "--proto"));
- LogUtil.CLog.d("Got battery service dump:\n " + batteryProto.toString());
- return batteryProto.getIsPresent();
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to dump batteryservice proto");
- throw (e);
- }
- }
-
- /** Creates a FieldValueMatcher.Builder corresponding to the given field. */
- protected static FieldValueMatcher.Builder createFvm(int field) {
- return FieldValueMatcher.newBuilder().setField(field);
- }
-
- protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag) throws Exception {
- addAtomEvent(conf, atomTag, new ArrayList<FieldValueMatcher.Builder>());
- }
-
- /**
- * Adds an event to the config for an atom that matches the given key.
- *
- * @param conf configuration
- * @param atomTag atom tag (from atoms.proto)
- * @param fvm FieldValueMatcher.Builder for the relevant key
- */
- protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag,
- FieldValueMatcher.Builder fvm)
- throws Exception {
- addAtomEvent(conf, atomTag, Arrays.asList(fvm));
- }
-
- /**
- * Adds an event to the config for an atom that matches the given keys.
- *
- * @param conf configuration
- * @param atomId atom tag (from atoms.proto)
- * @param fvms list of FieldValueMatcher.Builders to attach to the atom. May be null.
- */
- protected void addAtomEvent(StatsdConfig.Builder conf, int atomId,
- List<FieldValueMatcher.Builder> fvms) throws Exception {
-
- final String atomName = "Atom" + System.nanoTime();
- final String eventName = "Event" + System.nanoTime();
-
- SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(atomId);
- if (fvms != null) {
- for (FieldValueMatcher.Builder fvm : fvms) {
- sam.addFieldValueMatcher(fvm);
- }
- }
- conf.addAtomMatcher(AtomMatcher.newBuilder()
- .setId(atomName.hashCode())
- .setSimpleAtomMatcher(sam));
- conf.addEventMetric(EventMetric.newBuilder()
- .setId(eventName.hashCode())
- .setWhat(atomName.hashCode()));
- }
-
- /**
- * Adds an atom to a gauge metric of a config
- *
- * @param conf configuration
- * @param atomId atom id (from atoms.proto)
- * @param gaugeMetric the gauge metric to add
- */
- protected void addGaugeAtom(StatsdConfig.Builder conf, int atomId,
- GaugeMetric.Builder gaugeMetric) throws Exception {
- final String atomName = "Atom" + System.nanoTime();
- final String gaugeName = "Gauge" + System.nanoTime();
- final String predicateName = "APP_BREADCRUMB";
- SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(atomId);
- conf.addAtomMatcher(AtomMatcher.newBuilder()
- .setId(atomName.hashCode())
- .setSimpleAtomMatcher(sam));
- final String predicateTrueName = "APP_BREADCRUMB_1";
- final String predicateFalseName = "APP_BREADCRUMB_2";
- conf.addAtomMatcher(AtomMatcher.newBuilder()
- .setId(predicateTrueName.hashCode())
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
- .setEqInt(1)
- )
- )
- )
- // Used to trigger predicate
- .addAtomMatcher(AtomMatcher.newBuilder()
- .setId(predicateFalseName.hashCode())
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
- .setEqInt(2)
- )
- )
- );
- conf.addPredicate(Predicate.newBuilder()
- .setId(predicateName.hashCode())
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(predicateTrueName.hashCode())
- .setStop(predicateFalseName.hashCode())
- .setCountNesting(false)
- )
- );
- gaugeMetric
- .setId(gaugeName.hashCode())
- .setWhat(atomName.hashCode())
- .setCondition(predicateName.hashCode());
- conf.addGaugeMetric(gaugeMetric.build());
- }
-
- /**
- * Adds an atom to a gauge metric of a config
- *
- * @param conf configuration
- * @param atomId atom id (from atoms.proto)
- * @param dimension dimension is needed for most pulled atoms
- */
- protected void addGaugeAtomWithDimensions(StatsdConfig.Builder conf, int atomId,
- @Nullable FieldMatcher.Builder dimension) throws Exception {
- GaugeMetric.Builder gaugeMetric = GaugeMetric.newBuilder()
- .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build())
- .setSamplingType(GaugeMetric.SamplingType.CONDITION_CHANGE_TO_TRUE)
- .setMaxNumGaugeAtomsPerBucket(10000)
- .setBucket(TimeUnit.CTS);
- if (dimension != null) {
- gaugeMetric.setDimensionsInWhat(dimension.build());
- }
- addGaugeAtom(conf, atomId, gaugeMetric);
- }
-
- /**
- * Asserts that each set of states in stateSets occurs at least once in data.
- * Asserts that the states in data occur in the same order as the sets in stateSets.
- *
- * @param stateSets A list of set of states, where each set represents an equivalent
- * state of the device for the purpose of CTS.
- * @param data list of EventMetricData from statsd, produced by
- * getReportMetricListData()
- * @param wait expected duration (in ms) between state changes; asserts that the
- * actual wait
- * time was wait/2 <= actual_wait <= 5*wait. Use 0 to ignore this
- * assertion.
- * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
- */
- public void assertStatesOccurred(List<Set<Integer>> stateSets, List<EventMetricData> data,
- int wait, Function<Atom, Integer> getStateFromAtom) {
- // Sometimes, there are more events than there are states.
- // Eg: When the screen turns off, it may go into OFF and then DOZE immediately.
- assertWithMessage("Too few states found").that(data.size()).isAtLeast(stateSets.size());
- int stateSetIndex = 0; // Tracks which state set we expect the data to be in.
- for (int dataIndex = 0; dataIndex < data.size(); dataIndex++) {
- Atom atom = data.get(dataIndex).getAtom();
- int state = getStateFromAtom.apply(atom);
- // If state is in the current state set, we do not assert anything.
- // If it is not, we expect to have transitioned to the next state set.
- if (stateSets.get(stateSetIndex).contains(state)) {
- // No need to assert anything. Just log it.
- LogUtil.CLog.i("The following atom at dataIndex=" + dataIndex + " is "
- + "in stateSetIndex " + stateSetIndex + ":\n"
- + data.get(dataIndex).getAtom().toString());
- } else {
- stateSetIndex += 1;
- LogUtil.CLog.i("Assert that the following atom at dataIndex=" + dataIndex + " is"
- + " in stateSetIndex " + stateSetIndex + ":\n"
- + data.get(dataIndex).getAtom().toString());
- assertWithMessage("Missed first state").that(dataIndex).isNotEqualTo(0);
- assertWithMessage("Too many states").that(stateSetIndex)
- .isLessThan(stateSets.size());
- assertWithMessage(String.format("Is in wrong state (%d)", state))
- .that(stateSets.get(stateSetIndex)).contains(state);
- if (wait > 0) {
- assertTimeDiffBetween(data.get(dataIndex - 1), data.get(dataIndex),
- wait / 2, wait * 5);
- }
- }
- }
- assertWithMessage("Too few states").that(stateSetIndex).isEqualTo(stateSets.size() - 1);
- }
-
- /**
- * Removes all elements from data prior to the first occurrence of an element of state. After
- * this method is called, the first element of data (if non-empty) is guaranteed to be an
- * element in state.
- *
- * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
- */
- public void popUntilFind(List<EventMetricData> data, Set<Integer> state,
- Function<Atom, Integer> getStateFromAtom) {
- int firstStateIdx;
- for (firstStateIdx = 0; firstStateIdx < data.size(); firstStateIdx++) {
- Atom atom = data.get(firstStateIdx).getAtom();
- if (state.contains(getStateFromAtom.apply(atom))) {
- break;
- }
- }
- if (firstStateIdx == 0) {
- // First first element already is in state, so there's nothing to do.
- return;
- }
- data.subList(0, firstStateIdx).clear();
- }
-
- /**
- * Removes all elements from data after to the last occurrence of an element of state. After
- * this method is called, the last element of data (if non-empty) is guaranteed to be an
- * element in state.
- *
- * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
- */
- public void popUntilFindFromEnd(List<EventMetricData> data, Set<Integer> state,
- Function<Atom, Integer> getStateFromAtom) {
- int lastStateIdx;
- for (lastStateIdx = data.size() - 1; lastStateIdx >= 0; lastStateIdx--) {
- Atom atom = data.get(lastStateIdx).getAtom();
- if (state.contains(getStateFromAtom.apply(atom))) {
- break;
- }
- }
- if (lastStateIdx == data.size()-1) {
- // Last element already is in state, so there's nothing to do.
- return;
- }
- data.subList(lastStateIdx+1, data.size()).clear();
- }
-
- /** Returns the UID of the host, which should always either be SHELL (2000) or ROOT (0). */
- protected int getHostUid() throws DeviceNotAvailableException {
- String strUid = "";
- try {
- strUid = getDevice().executeShellCommand("id -u");
- return Integer.parseInt(strUid.trim());
- } catch (NumberFormatException e) {
- LogUtil.CLog.e("Failed to get host's uid via shell command. Found " + strUid);
- // Fall back to alternative method...
- if (getDevice().isAdbRoot()) {
- return 0; // ROOT
- } else {
- return 2000; // SHELL
- }
- }
- }
-
- protected String getProperty(String prop) throws Exception {
- return getDevice().executeShellCommand("getprop " + prop).replace("\n", "");
- }
-
- protected void turnScreenOn() throws Exception {
- getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
- getDevice().executeShellCommand("wm dismiss-keyguard");
- }
-
- protected void turnScreenOff() throws Exception {
- getDevice().executeShellCommand("input keyevent KEYCODE_SLEEP");
- }
-
- protected void setChargingState(int state) throws Exception {
- getDevice().executeShellCommand("cmd battery set status " + state);
- }
-
- protected void unplugDevice() throws Exception {
- // On batteryless devices on Android P or above, the 'unplug' command
- // alone does not simulate the really unplugged state.
- //
- // This is because charging state is left as "unknown". Unless a valid
- // state like 3 = BatteryManager.BATTERY_STATUS_DISCHARGING is set,
- // framework does not consider the device as running on battery.
- setChargingState(3);
-
- getDevice().executeShellCommand("cmd battery unplug");
- }
-
- protected void plugInAc() throws Exception {
- getDevice().executeShellCommand("cmd battery set ac 1");
- }
-
- protected void plugInUsb() throws Exception {
- getDevice().executeShellCommand("cmd battery set usb 1");
- }
-
- protected void plugInWireless() throws Exception {
- getDevice().executeShellCommand("cmd battery set wireless 1");
- }
-
- protected void enableLooperStats() throws Exception {
- getDevice().executeShellCommand("cmd looper_stats enable");
- }
-
- protected void resetLooperStats() throws Exception {
- getDevice().executeShellCommand("cmd looper_stats reset");
- }
-
- protected void disableLooperStats() throws Exception {
- getDevice().executeShellCommand("cmd looper_stats disable");
- }
-
- protected void enableBinderStats() throws Exception {
- getDevice().executeShellCommand("dumpsys binder_calls_stats --enable");
- }
-
- protected void resetBinderStats() throws Exception {
- getDevice().executeShellCommand("dumpsys binder_calls_stats --reset");
- }
-
- protected void disableBinderStats() throws Exception {
- getDevice().executeShellCommand("dumpsys binder_calls_stats --disable");
- }
-
- protected void binderStatsNoSampling() throws Exception {
- getDevice().executeShellCommand("dumpsys binder_calls_stats --no-sampling");
- }
-
- protected void setUpLooperStats() throws Exception {
- getDevice().executeShellCommand("cmd looper_stats enable");
- getDevice().executeShellCommand("cmd looper_stats sampling_interval 1");
- getDevice().executeShellCommand("cmd looper_stats reset");
- }
-
- protected void cleanUpLooperStats() throws Exception {
- getDevice().executeShellCommand("cmd looper_stats disable");
- }
-
- public void setAppBreadcrumbPredicate() throws Exception {
- doAppBreadcrumbReportedStart(1);
- }
-
- public void clearAppBreadcrumbPredicate() throws Exception {
- doAppBreadcrumbReportedStart(2);
- }
-
- public void doAppBreadcrumbReportedStart(int label) throws Exception {
- doAppBreadcrumbReported(label, AppBreadcrumbReported.State.START.ordinal());
- }
-
- public void doAppBreadcrumbReportedStop(int label) throws Exception {
- doAppBreadcrumbReported(label, AppBreadcrumbReported.State.STOP.ordinal());
- }
-
- public void doAppBreadcrumbReported(int label) throws Exception {
- doAppBreadcrumbReported(label, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
- }
-
- public void doAppBreadcrumbReported(int label, int state) throws Exception {
- getDevice().executeShellCommand(String.format(
- "cmd stats log-app-breadcrumb %d %d", label, state));
- }
-
- protected void setBatteryLevel(int level) throws Exception {
- getDevice().executeShellCommand("cmd battery set level " + level);
- }
-
- protected void resetBatteryStatus() throws Exception {
- getDevice().executeShellCommand("cmd battery reset");
- }
-
- protected int getScreenBrightness() throws Exception {
- return Integer.parseInt(
- getDevice().executeShellCommand("settings get system screen_brightness").trim());
- }
-
- protected void setScreenBrightness(int brightness) throws Exception {
- getDevice().executeShellCommand("settings put system screen_brightness " + brightness);
- }
-
- // Gets whether "Always on Display" setting is enabled.
- // In rare cases, this is different from whether the device can enter SCREEN_STATE_DOZE.
- protected String getAodState() throws Exception {
- return getDevice().executeShellCommand("settings get secure doze_always_on");
- }
-
- protected void setAodState(String state) throws Exception {
- getDevice().executeShellCommand("settings put secure doze_always_on " + state);
- }
-
- protected boolean isScreenBrightnessModeManual() throws Exception {
- String mode = getDevice().executeShellCommand("settings get system screen_brightness_mode");
- return Integer.parseInt(mode.trim()) == 0;
- }
-
- protected void setScreenBrightnessMode(boolean manual) throws Exception {
- getDevice().executeShellCommand(
- "settings put system screen_brightness_mode " + (manual ? 0 : 1));
- }
-
- protected void enterDozeModeLight() throws Exception {
- getDevice().executeShellCommand("dumpsys deviceidle force-idle light");
- }
-
- protected void enterDozeModeDeep() throws Exception {
- getDevice().executeShellCommand("dumpsys deviceidle force-idle deep");
- }
-
- protected void leaveDozeMode() throws Exception {
- getDevice().executeShellCommand("dumpsys deviceidle unforce");
- getDevice().executeShellCommand("dumpsys deviceidle disable");
- getDevice().executeShellCommand("dumpsys deviceidle enable");
- }
-
- protected void turnBatterySaverOn() throws Exception {
- unplugDevice();
- getDevice().executeShellCommand("settings put global low_power 1");
- }
-
- protected void turnBatterySaverOff() throws Exception {
- getDevice().executeShellCommand("settings put global low_power 0");
- getDevice().executeShellCommand("cmd battery reset");
- }
-
- protected void rebootDevice() throws Exception {
- getDevice().rebootUntilOnline();
- }
-
- /**
- * Asserts that the two events are within the specified range of each other.
- *
- * @param d0 the event that should occur first
- * @param d1 the event that should occur second
- * @param minDiffMs d0 should precede d1 by at least this amount
- * @param maxDiffMs d0 should precede d1 by at most this amount
- */
- public static void assertTimeDiffBetween(EventMetricData d0, EventMetricData d1,
- int minDiffMs, int maxDiffMs) {
- long diffMs = (d1.getElapsedTimestampNanos() - d0.getElapsedTimestampNanos()) / 1_000_000;
- assertWithMessage("Illegal time difference")
- .that(diffMs).isIn(Range.closed((long) minDiffMs, (long) maxDiffMs));
- }
-
- protected String getCurrentLogcatDate() throws Exception {
- // TODO: Do something more robust than this for getting logcat markers.
- long timestampMs = getDevice().getDeviceDate();
- return new SimpleDateFormat("MM-dd HH:mm:ss.SSS")
- .format(new Date(timestampMs));
- }
-
- protected String getLogcatSince(String date, String logcatParams) throws Exception {
- return getDevice().executeShellCommand(String.format(
- "logcat -v threadtime -t '%s' -d %s", date, logcatParams));
- }
-
- // TODO: Remove this and migrate all usages to createConfigBuilder()
- protected StatsdConfig.Builder getPulledConfig() {
- return createConfigBuilder();
- }
- /**
- * Determines if the device has the given feature.
- * Prints a warning if its value differs from requiredAnswer.
- */
- protected boolean hasFeature(String featureName, boolean requiredAnswer) throws Exception {
- final String features = getDevice().executeShellCommand("pm list features");
- boolean hasIt = features.contains(featureName);
- if (hasIt != requiredAnswer) {
- LogUtil.CLog.w("Device does " + (requiredAnswer ? "not " : "") + "have feature "
- + featureName);
- }
- return hasIt == requiredAnswer;
- }
-
- /**
- * Determines if the device has |file|.
- */
- protected boolean doesFileExist(String file) throws Exception {
- return getDevice().doesFileExist(file);
- }
-
- protected void turnOnAirplaneMode() throws Exception {
- getDevice().executeShellCommand("cmd connectivity airplane-mode enable");
- }
-
- protected void turnOffAirplaneMode() throws Exception {
- getDevice().executeShellCommand("cmd connectivity airplane-mode disable");
- }
-
- /**
- * Returns a list of fields and values for {@code className} from {@link TelephonyDebugService}
- * output.
- *
- * <p>Telephony dumpsys output does not support proto at the moment. This method provides
- * limited support for parsing its output. Specifically, it does not support arrays or
- * multi-line values.
- */
- private List<Map<String, String>> getTelephonyDumpEntries(String className) throws Exception {
- // Matches any line with indentation, except for lines with only spaces
- Pattern indentPattern = Pattern.compile("^(\\s*)[^ ].*$");
- // Matches pattern for class, e.g. " Phone:"
- Pattern classNamePattern = Pattern.compile("^(\\s*)" + Pattern.quote(className) + ":.*$");
- // Matches pattern for key-value pairs, e.g. " mPhoneId=1"
- Pattern keyValuePattern = Pattern.compile("^(\\s*)([a-zA-Z]+[a-zA-Z0-9_]*)\\=(.+)$");
- String response =
- getDevice().executeShellCommand("dumpsys activity service TelephonyDebugService");
- Queue<String> responseLines = new LinkedList<>(Arrays.asList(response.split("[\\r\\n]+")));
-
- List<Map<String, String>> results = new ArrayList<>();
- while (responseLines.peek() != null) {
- Matcher matcher = classNamePattern.matcher(responseLines.poll());
- if (matcher.matches()) {
- final int classIndentLevel = matcher.group(1).length();
- final Map<String, String> instanceEntries = new HashMap<>();
- while (responseLines.peek() != null) {
- // Skip blank lines
- matcher = indentPattern.matcher(responseLines.peek());
- if (responseLines.peek().length() == 0 || !matcher.matches()) {
- responseLines.poll();
- continue;
- }
- // Finish (without consuming the line) if already parsed past this instance
- final int indentLevel = matcher.group(1).length();
- if (indentLevel <= classIndentLevel) {
- break;
- }
- // Parse key-value pair if it belongs to the instance directly
- matcher = keyValuePattern.matcher(responseLines.poll());
- if (indentLevel == classIndentLevel + 1 && matcher.matches()) {
- instanceEntries.put(matcher.group(2), matcher.group(3));
- }
- }
- results.add(instanceEntries);
- }
- }
- return results;
- }
-
- protected int getActiveSimSlotCount() throws Exception {
- List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
- long count = slots.stream().filter(slot -> "true".equals(slot.get("mActive"))).count();
- return Math.toIntExact(count);
- }
-
- /**
- * Returns the upper bound of active SIM profile count.
- *
- * <p>The value is an upper bound as eSIMs without profiles are also counted in.
- */
- protected int getActiveSimCountUpperBound() throws Exception {
- List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
- long count = slots.stream().filter(slot ->
- "true".equals(slot.get("mActive"))
- && "CARDSTATE_PRESENT".equals(slot.get("mCardState"))).count();
- return Math.toIntExact(count);
- }
-
- /**
- * Returns the upper bound of active eSIM profile count.
- *
- * <p>The value is an upper bound as eSIMs without profiles are also counted in.
- */
- protected int getActiveEsimCountUpperBound() throws Exception {
- List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
- long count = slots.stream().filter(slot ->
- "true".equals(slot.get("mActive"))
- && "CARDSTATE_PRESENT".equals(slot.get("mCardState"))
- && "true".equals(slot.get("mIsEuicc"))).count();
- return Math.toIntExact(count);
- }
-
- protected boolean hasGsmPhone() throws Exception {
- // Not using log entries or ServiceState in the dump since they may or may not be present,
- // which can make the test flaky
- return getTelephonyDumpEntries("Phone").stream()
- .anyMatch(phone ->
- String.format("%d", PHONE_TYPE_GSM).equals(phone.get("getPhoneType()")));
- }
-
- protected boolean hasCdmaPhone() throws Exception {
- // Not using log entries or ServiceState in the dump due to the same reason as hasGsmPhone()
- return getTelephonyDumpEntries("Phone").stream()
- .anyMatch(phone ->
- String.format("%d", PHONE_TYPE_CDMA).equals(phone.get("getPhoneType()"))
- || String.format("%d", PHONE_TYPE_CDMA_LTE)
- .equals(phone.get("getPhoneType()")));
- }
-
- // Checks that a timestamp has been truncated to be a multiple of 5 min
- protected void assertTimestampIsTruncated(long timestampNs) {
- long fiveMinutesInNs = NS_PER_SEC * 5 * 60;
- assertWithMessage("Timestamp is not truncated")
- .that(timestampNs % fiveMinutesInNs).isEqualTo(0);
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
deleted file mode 100644
index 0c9921e..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.validation.ValidationTestUtil;
-
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.CollectingByteOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.MessageLite;
-import com.google.protobuf.Parser;
-
-import java.io.FileNotFoundException;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-// Largely copied from incident's ProtoDumpTestCase
-public class BaseTestCase extends DeviceTestCase implements IBuildReceiver {
-
- protected IBuildInfo mCtsBuild;
-
- private static final String TEST_RUNNER = "androidx.test.runner.AndroidJUnitRunner";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- assertThat(mCtsBuild).isNotNull();
- }
-
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mCtsBuild = buildInfo;
- }
-
- public IBuildInfo getBuild() {
- return mCtsBuild;
- }
-
- /**
- * Create and return {@link ValidationTestUtil} and give it the current build.
- */
- public ValidationTestUtil createValidationUtil() {
- ValidationTestUtil util = new ValidationTestUtil();
- util.setBuild(getBuild());
- return util;
- }
-
- /**
- * Call onto the device with an adb shell command and get the results of
- * that as a proto of the given type.
- *
- * @param parser A protobuf parser object. e.g. MyProto.parser()
- * @param command The adb shell command to run. e.g. "dumpsys fingerprint --proto"
- *
- * @throws DeviceNotAvailableException If there was a problem communicating with
- * the test device.
- * @throws InvalidProtocolBufferException If there was an error parsing
- * the proto. Note that a 0 length buffer is not necessarily an error.
- */
- public <T extends MessageLite> T getDump(Parser<T> parser, String command)
- throws DeviceNotAvailableException, InvalidProtocolBufferException {
- final CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
- getDevice().executeShellCommand(command, receiver);
- if (false) {
- CLog.d("Command output while parsing " + parser.getClass().getCanonicalName()
- + " for command: " + command + "\n"
- + BufferDebug.debugString(receiver.getOutput(), -1));
- }
- try {
- return parser.parseFrom(receiver.getOutput());
- } catch (Exception ex) {
- CLog.d("Error parsing " + parser.getClass().getCanonicalName() + " for command: "
- + command
- + BufferDebug.debugString(receiver.getOutput(), 16384));
- throw ex;
- }
- }
-
- /**
- * Install a device side test package.
- *
- * @param appFileName Apk file name, such as "CtsNetStatsApp.apk".
- * @param grantPermissions whether to give runtime permissions.
- */
- protected void installPackage(String appFileName, boolean grantPermissions)
- throws FileNotFoundException, DeviceNotAvailableException {
- CLog.d("Installing app " + appFileName);
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
- final String result = getDevice().installPackage(
- buildHelper.getTestFile(appFileName), true, grantPermissions);
- assertWithMessage(String.format("Failed to install %s: %s", appFileName, result))
- .that(result).isNull();
- }
-
- protected CompatibilityBuildHelper getBuildHelper() {
- return new CompatibilityBuildHelper(mCtsBuild);
- }
-
- /**
- * Run a device side test.
- *
- * @param pkgName Test package name, such as "com.android.server.cts.netstats".
- * @param testClassName Test class name; either a fully qualified name, or "." + a class name.
- * @param testMethodName Test method name.
- * @return {@link TestRunResult} of this invocation.
- * @throws DeviceNotAvailableException
- */
- @Nonnull
- protected TestRunResult runDeviceTests(@Nonnull String pkgName,
- @Nullable String testClassName, @Nullable String testMethodName)
- throws DeviceNotAvailableException {
- if (testClassName != null && testClassName.startsWith(".")) {
- testClassName = pkgName + testClassName;
- }
-
- RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
- pkgName, TEST_RUNNER, getDevice().getIDevice());
- if (testClassName != null && testMethodName != null) {
- testRunner.setMethodName(testClassName, testMethodName);
- } else if (testClassName != null) {
- testRunner.setClassName(testClassName);
- }
-
- CollectingTestListener listener = new CollectingTestListener();
- assertThat(getDevice().runInstrumentationTests(testRunner, listener)).isTrue();
-
- final TestRunResult result = listener.getCurrentRunResults();
- if (result.isRunFailure()) {
- throw new Error("Failed to successfully run device tests for "
- + result.getName() + ": " + result.getRunFailureMessage());
- }
- if (result.getNumTests() == 0) {
- throw new Error("No tests were run on the device");
- }
-
- if (result.hasFailedTests()) {
- // build a meaningful error message
- StringBuilder errorBuilder = new StringBuilder("On-device tests failed:\n");
- for (Map.Entry<TestDescription, TestResult> resultEntry :
- result.getTestResults().entrySet()) {
- if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
- errorBuilder.append(resultEntry.getKey().toString());
- errorBuilder.append(":\n");
- errorBuilder.append(resultEntry.getValue().getStackTrace());
- }
- }
- throw new AssertionError(errorBuilder.toString());
- }
-
- return result;
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/BufferDebug.java b/hostsidetests/statsd/src/android/cts/statsd/atom/BufferDebug.java
deleted file mode 100644
index 2b35052..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/BufferDebug.java
+++ /dev/null
@@ -1,144 +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.cts.statsd.atom;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Formatter;
-
-/**
- * Print utility for byte[].
- */
-public class BufferDebug {
- private static final int HALF_WIDTH = 8;
-
- /**
- * Number of bytes represented per row in hex output.
- */
- public static final int WIDTH = HALF_WIDTH * 2;
-
- /**
- * Return a string suitable for debugging.
- * - If the byte is printable as an ascii string, return that, in quotation marks,
- * with a newline at the end.
- * - Otherwise, return the hexdump -C style output.
- *
- * @param buf the buffer
- * @param max print up to _max_ bytes, or the length of the string. If max is 0,
- * print the whole contents of buf.
- */
- public static String debugString(byte[] buf, int max) {
- if (buf == null) {
- return "(null)";
- }
- if (buf.length == 0) {
- return "(length 0)";
- }
-
- int len = max;
- if (len <= 0 || len > buf.length) {
- max = len = buf.length;
- }
-
- if (isPrintable(buf, len)) {
- return "\"" + new String(buf, 0, len, StandardCharsets.UTF_8) + "\"\n";
- } else {
- return toHex(buf, len, max);
- }
- }
-
- private static String toHex(byte[] buf, int len, int max) {
- final StringBuilder str = new StringBuilder();
-
- // All but the last row
- int rows = len / WIDTH;
- for (int row = 0; row < rows; row++) {
- writeRow(str, buf, row * WIDTH, WIDTH, max);
- }
-
- // Last row
- if (len % WIDTH != 0) {
- writeRow(str, buf, rows * WIDTH, max - (rows * WIDTH), max);
- }
-
- // Final len
- str.append(String.format("%10d 0x%08x ", buf.length, buf.length));
- if (buf.length != max) {
- str.append(String.format("truncated to %d 0x%08x", max, max));
- }
- str.append('\n');
-
- return str.toString();
- }
-
- private static void writeRow(StringBuilder str, byte[] buf, int start, int len, int max) {
- final Formatter f = new Formatter(str);
-
- // Start index
- f.format("%10d 0x%08x ", start, start);
-
- // One past the last char we will print
- int end = start + len;
- // Number of missing caracters due to this being the last line.
- int padding = 0;
- if (start + WIDTH > max) {
- padding = WIDTH - (end % WIDTH);
- end = max;
- }
-
- // Hex
- for (int i = start; i < end; i++) {
- f.format("%02x ", buf[i]);
- if (i == start + HALF_WIDTH - 1) {
- str.append(" ");
- }
- }
- for (int i = 0; i < padding; i++) {
- str.append(" ");
- }
- if (padding >= HALF_WIDTH) {
- str.append(" ");
- }
-
- str.append(" ");
- for (int i = start; i < end; i++) {
- byte b = buf[i];
- if (isPrintable(b)) {
- str.append((char)b);
- } else {
- str.append('.');
- }
- if (i == start + HALF_WIDTH - 1) {
- str.append(" ");
- }
- }
-
- str.append('\n');
- }
-
- private static boolean isPrintable(byte[] buf, int len) {
- for (int i=0; i<len; i++) {
- if (!isPrintable(buf[i])) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean isPrintable(byte c) {
- return c >= 0x20 && c <= 0x7e;
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
deleted file mode 100644
index 035160f..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ /dev/null
@@ -1,323 +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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.MessageMatcher;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Base class for testing Statsd atoms that report a uid. Tests are performed via a device-side app.
- */
-public class DeviceAtomTestCase extends AtomTestCase {
-
- public static final String DEVICE_SIDE_TEST_APK = "CtsStatsdApp.apk";
- public static final String DEVICE_SIDE_TEST_PACKAGE =
- "com.android.server.cts.device.statsd";
- public static final long DEVICE_SIDE_TEST_PACKAGE_VERSION = 10;
- public static final String DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME =
- "com.android.server.cts.device.statsd.StatsdCtsForegroundService";
- private static final String DEVICE_SIDE_BG_SERVICE_COMPONENT =
- "com.android.server.cts.device.statsd/.StatsdCtsBackgroundService";
- public static final long DEVICE_SIDE_TEST_PKG_HASH =
- Long.parseUnsignedLong("15694052924544098582");
-
- // Constants from device side tests (not directly accessible here).
- public static final String KEY_ACTION = "action";
- public static final String ACTION_LMK = "action.lmk";
-
- public static final String CONFIG_NAME = "cts_config";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
- installTestApp();
- Thread.sleep(1000);
- }
-
- @Override
- protected void tearDown() throws Exception {
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
- super.tearDown();
- }
-
- /**
- * Performs a device-side test by calling a method on the app and returns its stats events.
- * @param methodName the name of the method in the app's AtomTests to perform
- * @param atom atom tag (from atoms.proto)
- * @param key atom's field corresponding to state
- * @param stateOn 'on' value
- * @param stateOff 'off' value
- * @param minTimeDiffMs max allowed time between start and stop
- * @param maxTimeDiffMs min allowed time between start and stop
- * @param demandExactlyTwo whether there must be precisely two events logged (1 start, 1 stop)
- * @return list of events with the app's uid matching the configuration defined by the params.
- */
- protected List<EventMetricData> doDeviceMethodOnOff(
- String methodName, int atom, int key, int stateOn, int stateOff,
- int minTimeDiffMs, int maxTimeDiffMs, boolean demandExactlyTwo) throws Exception {
- StatsdConfig.Builder conf = createConfigBuilder();
- addAtomEvent(conf, atom, createFvm(key).setEqInt(stateOn));
- addAtomEvent(conf, atom, createFvm(key).setEqInt(stateOff));
- List<EventMetricData> data = doDeviceMethod(methodName, conf);
-
- if (demandExactlyTwo) {
- assertThat(data).hasSize(2);
- } else {
- assertThat(data.size()).isAtLeast(2);
- }
- assertTimeDiffBetween(data.get(0), data.get(1), minTimeDiffMs, maxTimeDiffMs);
- return data;
- }
-
- /**
- *
- * @param methodName the name of the method in the app's AtomTests to perform
- * @param cfg statsd configuration
- * @return list of events with the app's uid matching the configuration.
- */
- protected List<EventMetricData> doDeviceMethod(String methodName, StatsdConfig.Builder cfg)
- throws Exception {
- removeConfig(CONFIG_ID);
- getReportList(); // Clears previous data on disk.
- uploadConfig(cfg);
- int appUid = getUid();
- LogUtil.CLog.d("\nPerforming device-side test of " + methodName + " for uid " + appUid);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", methodName);
-
- return getEventMetricDataList();
- }
-
- protected void createAndUploadConfig(int atomTag, boolean useAttribution) throws Exception {
- StatsdConfig.Builder conf = createConfigBuilder();
- addAtomEvent(conf, atomTag, useAttribution);
- uploadConfig(conf);
- }
-
- /**
- * Adds an event to the config for an atom that matches the given key AND has the app's uid.
- * @param conf configuration
- * @param atomTag atom tag (from atoms.proto)
- * @param fvm FieldValueMatcher.Builder for the relevant key
- */
- @Override
- protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag, FieldValueMatcher.Builder fvm)
- throws Exception {
-
- final int UID_KEY = 1;
- FieldValueMatcher.Builder fvmUid = createAttributionFvm(UID_KEY);
- addAtomEvent(conf, atomTag, Arrays.asList(fvm, fvmUid));
- }
-
- /**
- * Adds an event to the config for an atom that matches the app's uid.
- * @param conf configuration
- * @param atomTag atom tag (from atoms.proto)
- * @param useAttribution If true, the atom has a uid within an attribution node. Else, the atom
- * has a uid but not in an attribution node.
- */
- protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag,
- boolean useAttribution) throws Exception {
- final int UID_KEY = 1;
- FieldValueMatcher.Builder fvmUid;
- if (useAttribution) {
- fvmUid = createAttributionFvm(UID_KEY);
- } else {
- fvmUid = createFvm(UID_KEY).setEqString(DEVICE_SIDE_TEST_PACKAGE);
- }
- addAtomEvent(conf, atomTag, Arrays.asList(fvmUid));
- }
-
- /**
- * Creates a FieldValueMatcher for atoms that use AttributionNode
- */
- protected FieldValueMatcher.Builder createAttributionFvm(int field) {
- final int ATTRIBUTION_NODE_UID_KEY = 1;
- return createFvm(field).setPosition(Position.ANY)
- .setMatchesTuple(MessageMatcher.newBuilder()
- .addFieldValueMatcher(createFvm(ATTRIBUTION_NODE_UID_KEY)
- .setEqString(DEVICE_SIDE_TEST_PACKAGE)));
- }
-
- /**
- * Gets the uid of the test app.
- */
- protected int getUid() throws Exception {
- int currentUser = getDevice().getCurrentUser();
- String uidLine = getDevice().executeShellCommand("cmd package list packages -U --user "
- + currentUser + " " + DEVICE_SIDE_TEST_PACKAGE);
- String[] uidLineParts = uidLine.split(":");
- // 3rd entry is package uid
- assertThat(uidLineParts.length).isGreaterThan(2);
- int uid = Integer.parseInt(uidLineParts[2].trim());
- assertThat(uid).isGreaterThan(10000);
- return uid;
- }
-
- /**
- * Installs the test apk.
- */
- protected void installTestApp() throws Exception {
- installPackage(DEVICE_SIDE_TEST_APK, true);
- LogUtil.CLog.i("Installing device-side test app with uid " + getUid());
- allowBackgroundServices();
- }
-
- /**
- * Uninstalls the test apk.
- */
- protected void uninstallPackage() throws Exception{
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
- }
-
- /**
- * Required to successfully start a background service from adb in O.
- */
- protected void allowBackgroundServices() throws Exception {
- getDevice().executeShellCommand(String.format(
- "cmd deviceidle tempwhitelist %s", DEVICE_SIDE_TEST_PACKAGE));
- }
-
- /**
- * Runs a (background) service to perform the given action.
- * @param actionValue the action code constants indicating the desired action to perform.
- */
- protected void executeBackgroundService(String actionValue) throws Exception {
- allowBackgroundServices();
- getDevice().executeShellCommand(String.format(
- "am startservice -n '%s' -e %s %s",
- DEVICE_SIDE_BG_SERVICE_COMPONENT,
- KEY_ACTION, actionValue));
- }
-
-
- /** Make the test app standby-active so it can run syncs and jobs immediately. */
- protected void allowImmediateSyncs() throws Exception {
- getDevice().executeShellCommand("am set-standby-bucket "
- + DEVICE_SIDE_TEST_PACKAGE + " active");
- }
-
- /**
- * Runs the specified activity.
- */
- protected void runActivity(String activity, String actionKey, String actionValue)
- throws Exception {
- runActivity(activity, actionKey, actionValue, WAIT_TIME_LONG);
- }
-
- /**
- * Runs the specified activity.
- */
- protected void runActivity(String activity, String actionKey, String actionValue,
- long waitTime) throws Exception {
- try (AutoCloseable a = withActivity(activity, actionKey, actionValue)) {
- Thread.sleep(waitTime);
- }
- }
-
- /**
- * Starts the specified activity and returns an {@link AutoCloseable} that stops the activity
- * when closed.
- *
- * <p>Example usage:
- * <pre>
- * try (AutoClosable a = withActivity("activity", "action", "action-value")) {
- * doStuff();
- * }
- * </pre>
- */
- protected AutoCloseable withActivity(String activity, String actionKey, String actionValue)
- throws Exception {
- String intentString = null;
- if (actionKey != null && actionValue != null) {
- intentString = actionKey + " " + actionValue;
- }
- if (intentString == null) {
- getDevice().executeShellCommand(
- "am start -n " + DEVICE_SIDE_TEST_PACKAGE + "/." + activity);
- } else {
- getDevice().executeShellCommand(
- "am start -n " + DEVICE_SIDE_TEST_PACKAGE + "/." + activity + " -e " +
- intentString);
- }
- return () -> {
- getDevice().executeShellCommand(
- "am force-stop " + DEVICE_SIDE_TEST_PACKAGE);
- Thread.sleep(WAIT_TIME_SHORT);
- };
- }
-
- protected void resetBatteryStats() throws Exception {
- getDevice().executeShellCommand("dumpsys batterystats --reset");
- }
-
- protected void clearProcStats() throws Exception {
- getDevice().executeShellCommand("dumpsys procstats --clear");
- }
-
- protected void startProcStatsTesting() throws Exception {
- getDevice().executeShellCommand("dumpsys procstats --start-testing");
- }
-
- protected void stopProcStatsTesting() throws Exception {
- getDevice().executeShellCommand("dumpsys procstats --stop-testing");
- }
-
- protected void commitProcStatsToDisk() throws Exception {
- getDevice().executeShellCommand("dumpsys procstats --commit");
- }
-
- protected void rebootDeviceAndWaitUntilReady() throws Exception {
- rebootDevice();
- // Wait for 2 mins.
- assertWithMessage("Device failed to boot")
- .that(getDevice().waitForBootComplete(120_000)).isTrue();
- assertWithMessage("Stats service failed to start")
- .that(waitForStatsServiceStart(60_000)).isTrue();
- Thread.sleep(2_000);
- }
-
- protected boolean waitForStatsServiceStart(final long waitTime) throws Exception {
- LogUtil.CLog.i("Waiting %d ms for stats service to start", waitTime);
- int counter = 1;
- long startTime = System.currentTimeMillis();
- while ((System.currentTimeMillis() - startTime) < waitTime) {
- if ("running".equals(getProperty("init.svc.statsd"))) {
- return true;
- }
- Thread.sleep(Math.min(200 * counter, 2_000));
- counter++;
- }
- LogUtil.CLog.w("Stats service did not start after %d ms", waitTime);
- return false;
- }
-
- boolean getNetworkStatsCombinedSubTypeEnabled() throws Exception {
- final String output = getDevice().executeShellCommand(
- "settings get global netstats_combine_subtype_enabled").trim();
- return output.equals("1");
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java
deleted file mode 100644
index ee86f01c..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.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.cts.statsd.atom;
-
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-
-import java.util.List;
-
-/**
- * Verifies that Automotive's Garage Mode reports its status.
- * Statsd atom tests are done via adb (hostside).
- */
-public class GarageModeAtomTests extends AtomTestCase {
-
- private static final String TAG = "Statsd.GarageModeAtomTests";
- private static final int SHORT_SLEEP = 100; // Milliseconds
- private static final int TRY_LIMIT = WAIT_TIME_SHORT / SHORT_SLEEP;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- public void testGarageModeOnOff() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, true)) {
- return;
- }
-
- final int atomTag = Atom.GARAGE_MODE_INFO_FIELD_NUMBER;
- createAndUploadConfig(atomTag);
-
- // Flush any old metrics
- List<EventMetricData> data = getEventMetricDataList();
-
- turnOnGarageMode();
- waitForGarageModeState(true);
-
- turnOffGarageMode();
- waitForGarageModeState(false);
- }
-
- private void turnOnGarageMode() throws Exception {
- getDevice().executeShellCommand("cmd car_service garage-mode on");
- }
- private void turnOffGarageMode() throws Exception {
- getDevice().executeShellCommand("cmd car_service garage-mode off");
- }
-
- private void waitForGarageModeState(boolean requiredState) throws Exception {
- for (int tryCount = 0; tryCount < TRY_LIMIT; tryCount++) {
- List<EventMetricData> data = getEventMetricDataList();
- for (EventMetricData d : data) {
- boolean isGarageMode = d.getAtom().getGarageModeInfo().getIsGarageMode();
- if (isGarageMode == requiredState) {
- return;
- }
- }
- Thread.sleep(SHORT_SLEEP);
- }
- assertTrue("Did not receive an atom with Garage Mode "
- + (requiredState ? "ON" : "OFF"), false);
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
deleted file mode 100644
index ee6f324..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ /dev/null
@@ -1,699 +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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.BatteryPluggedStateEnum;
-import android.os.BatteryStatusEnum;
-import android.platform.test.annotations.RestrictedBuildTest;
-import android.server.DeviceIdleModeEnum;
-import android.view.DisplayStateEnum;
-import android.telephony.NetworkTypeEnum;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.BatterySaverModeStateChanged;
-import com.android.os.AtomsProto.BuildInformation;
-import com.android.os.AtomsProto.ConnectivityStateChanged;
-import com.android.os.AtomsProto.SimSlotState;
-import com.android.os.AtomsProto.SupportedRadioAccessFamily;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.EventMetricData;
-
-import com.google.common.collect.Range;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Statsd atom tests that are done via adb (hostside).
- */
-public class HostAtomTests extends AtomTestCase {
-
- private static final String TAG = "Statsd.HostAtomTests";
-
- // Either file must exist to read kernel wake lock stats.
- private static final String WAKE_LOCK_FILE = "/proc/wakelocks";
- private static final String WAKE_SOURCES_FILE = "/d/wakeup_sources";
-
- // Bitmask of radio access technologies that all GSM phones should at least partially support
- protected static final long NETWORK_TYPE_BITMASK_GSM_ALL =
- (1 << (NetworkTypeEnum.NETWORK_TYPE_GSM_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_GPRS_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_EDGE_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_UMTS_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSDPA_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSUPA_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSPA_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSPAP_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_TD_SCDMA_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_LTE_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_LTE_CA_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_NR_VALUE - 1));
- // Bitmask of radio access technologies that all CDMA phones should at least partially support
- protected static final long NETWORK_TYPE_BITMASK_CDMA_ALL =
- (1 << (NetworkTypeEnum.NETWORK_TYPE_CDMA_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_1XRTT_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_EVDO_0_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_EVDO_A_VALUE - 1))
- | (1 << (NetworkTypeEnum.NETWORK_TYPE_EHRPD_VALUE - 1));
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- public void testScreenStateChangedAtom() throws Exception {
- // Setup, make sure the screen is off and turn off AoD if it is on.
- // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
- // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
- String aodState = getAodState();
- setAodState("0");
- turnScreenOn();
- Thread.sleep(WAIT_TIME_SHORT);
- turnScreenOff();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final int atomTag = Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER;
-
- Set<Integer> screenOnStates = new HashSet<>(
- Arrays.asList(DisplayStateEnum.DISPLAY_STATE_ON_VALUE,
- DisplayStateEnum.DISPLAY_STATE_ON_SUSPEND_VALUE,
- DisplayStateEnum.DISPLAY_STATE_VR_VALUE));
- Set<Integer> screenOffStates = new HashSet<>(
- Arrays.asList(DisplayStateEnum.DISPLAY_STATE_OFF_VALUE,
- DisplayStateEnum.DISPLAY_STATE_DOZE_VALUE,
- DisplayStateEnum.DISPLAY_STATE_DOZE_SUSPEND_VALUE,
- DisplayStateEnum.DISPLAY_STATE_UNKNOWN_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(screenOnStates, screenOffStates);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Trigger events in same order.
- turnScreenOn();
- Thread.sleep(WAIT_TIME_LONG);
- turnScreenOff();
- Thread.sleep(WAIT_TIME_LONG);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
- // reset screen to on
- turnScreenOn();
- // Restores AoD to initial state.
- setAodState(aodState);
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
- atom -> atom.getScreenStateChanged().getState().getNumber());
- }
-
- public void testChargingStateChangedAtom() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- // Setup, set charging state to full.
- setChargingState(5);
- Thread.sleep(WAIT_TIME_SHORT);
-
- final int atomTag = Atom.CHARGING_STATE_CHANGED_FIELD_NUMBER;
-
- Set<Integer> batteryUnknownStates = new HashSet<>(
- Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_UNKNOWN_VALUE));
- Set<Integer> batteryChargingStates = new HashSet<>(
- Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_CHARGING_VALUE));
- Set<Integer> batteryDischargingStates = new HashSet<>(
- Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_DISCHARGING_VALUE));
- Set<Integer> batteryNotChargingStates = new HashSet<>(
- Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_NOT_CHARGING_VALUE));
- Set<Integer> batteryFullStates = new HashSet<>(
- Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_FULL_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(batteryUnknownStates, batteryChargingStates,
- batteryDischargingStates, batteryNotChargingStates, batteryFullStates);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Trigger events in same order.
- setChargingState(1);
- Thread.sleep(WAIT_TIME_SHORT);
- setChargingState(2);
- Thread.sleep(WAIT_TIME_SHORT);
- setChargingState(3);
- Thread.sleep(WAIT_TIME_SHORT);
- setChargingState(4);
- Thread.sleep(WAIT_TIME_SHORT);
- setChargingState(5);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Unfreeze battery state after test
- resetBatteryStatus();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getChargingStateChanged().getState().getNumber());
- }
-
- public void testPluggedStateChangedAtom() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- // Setup, unplug device.
- unplugDevice();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final int atomTag = Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER;
-
- Set<Integer> unpluggedStates = new HashSet<>(
- Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_NONE_VALUE));
- Set<Integer> acStates = new HashSet<>(
- Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_AC_VALUE));
- Set<Integer> usbStates = new HashSet<>(
- Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_USB_VALUE));
- Set<Integer> wirelessStates = new HashSet<>(
- Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_WIRELESS_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(acStates, unpluggedStates, usbStates,
- unpluggedStates, wirelessStates, unpluggedStates);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Trigger events in same order.
- plugInAc();
- Thread.sleep(WAIT_TIME_SHORT);
- unplugDevice();
- Thread.sleep(WAIT_TIME_SHORT);
- plugInUsb();
- Thread.sleep(WAIT_TIME_SHORT);
- unplugDevice();
- Thread.sleep(WAIT_TIME_SHORT);
- plugInWireless();
- Thread.sleep(WAIT_TIME_SHORT);
- unplugDevice();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Unfreeze battery state after test
- resetBatteryStatus();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getPluggedStateChanged().getState().getNumber());
- }
-
- public void testBatteryLevelChangedAtom() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- // Setup, set battery level to full.
- setBatteryLevel(100);
- Thread.sleep(WAIT_TIME_SHORT);
-
- final int atomTag = Atom.BATTERY_LEVEL_CHANGED_FIELD_NUMBER;
-
- Set<Integer> batteryLow = new HashSet<>(Arrays.asList(2));
- Set<Integer> battery25p = new HashSet<>(Arrays.asList(25));
- Set<Integer> battery50p = new HashSet<>(Arrays.asList(50));
- Set<Integer> battery75p = new HashSet<>(Arrays.asList(75));
- Set<Integer> batteryFull = new HashSet<>(Arrays.asList(100));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(batteryLow, battery25p, battery50p,
- battery75p, batteryFull);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Trigger events in same order.
- setBatteryLevel(2);
- Thread.sleep(WAIT_TIME_SHORT);
- setBatteryLevel(25);
- Thread.sleep(WAIT_TIME_SHORT);
- setBatteryLevel(50);
- Thread.sleep(WAIT_TIME_SHORT);
- setBatteryLevel(75);
- Thread.sleep(WAIT_TIME_SHORT);
- setBatteryLevel(100);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Unfreeze battery state after test
- resetBatteryStatus();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getBatteryLevelChanged().getBatteryLevel());
- }
-
- public void testDeviceIdleModeStateChangedAtom() throws Exception {
- // Setup, leave doze mode.
- leaveDozeMode();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final int atomTag = Atom.DEVICE_IDLE_MODE_STATE_CHANGED_FIELD_NUMBER;
-
- Set<Integer> dozeOff = new HashSet<>(
- Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_OFF_VALUE));
- Set<Integer> dozeLight = new HashSet<>(
- Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_LIGHT_VALUE));
- Set<Integer> dozeDeep = new HashSet<>(
- Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_DEEP_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(dozeLight, dozeDeep, dozeOff);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Trigger events in same order.
- enterDozeModeLight();
- Thread.sleep(WAIT_TIME_SHORT);
- enterDozeModeDeep();
- Thread.sleep(WAIT_TIME_SHORT);
- leaveDozeMode();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();;
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getDeviceIdleModeStateChanged().getState().getNumber());
- }
-
- public void testBatterySaverModeStateChangedAtom() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- // Setup, turn off battery saver.
- turnBatterySaverOff();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final int atomTag = Atom.BATTERY_SAVER_MODE_STATE_CHANGED_FIELD_NUMBER;
-
- Set<Integer> batterySaverOn = new HashSet<>(
- Arrays.asList(BatterySaverModeStateChanged.State.ON_VALUE));
- Set<Integer> batterySaverOff = new HashSet<>(
- Arrays.asList(BatterySaverModeStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(batterySaverOn, batterySaverOff);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Trigger events in same order.
- turnBatterySaverOn();
- Thread.sleep(WAIT_TIME_LONG);
- turnBatterySaverOff();
- Thread.sleep(WAIT_TIME_LONG);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
- atom -> atom.getBatterySaverModeStateChanged().getState().getNumber());
- }
-
- @RestrictedBuildTest
- public void testRemainingBatteryCapacity() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
-
- assertThat(data).isNotEmpty();
- Atom atom = data.get(0);
- assertThat(atom.getRemainingBatteryCapacity().hasChargeMicroAmpereHour()).isTrue();
- if (hasBattery()) {
- assertThat(atom.getRemainingBatteryCapacity().getChargeMicroAmpereHour())
- .isGreaterThan(0);
- }
- }
-
- @RestrictedBuildTest
- public void testFullBatteryCapacity() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
-
- assertThat(data).isNotEmpty();
- Atom atom = data.get(0);
- assertThat(atom.getFullBatteryCapacity().hasCapacityMicroAmpereHour()).isTrue();
- if (hasBattery()) {
- assertThat(atom.getFullBatteryCapacity().getCapacityMicroAmpereHour()).isGreaterThan(0);
- }
- }
-
- public void testBatteryVoltage() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.BATTERY_VOLTAGE_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
-
- assertThat(data).isNotEmpty();
- Atom atom = data.get(0);
- assertThat(atom.getBatteryVoltage().hasVoltageMillivolt()).isTrue();
- if (hasBattery()) {
- assertThat(atom.getBatteryVoltage().getVoltageMillivolt()).isGreaterThan(0);
- }
- }
-
- // This test is for the pulled battery level atom.
- public void testBatteryLevel() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.BATTERY_LEVEL_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
-
- assertThat(data).isNotEmpty();
- Atom atom = data.get(0);
- assertThat(atom.getBatteryLevel().hasBatteryLevel()).isTrue();
- if (hasBattery()) {
- assertThat(atom.getBatteryLevel().getBatteryLevel()).isIn(Range.openClosed(0, 100));
- }
- }
-
- // This test is for the pulled battery charge count atom.
- public void testBatteryCycleCount() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.BATTERY_CYCLE_COUNT_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
-
- assertThat(data).isNotEmpty();
- Atom atom = data.get(0);
- assertThat(atom.getBatteryCycleCount().hasCycleCount()).isTrue();
- if (hasBattery()) {
- assertThat(atom.getBatteryCycleCount().getCycleCount()).isAtLeast(0);
- }
- }
-
- public void testKernelWakelock() throws Exception {
- if (!kernelWakelockStatsExist()) {
- return;
- }
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.KERNEL_WAKELOCK_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
-
- assertThat(data).isNotEmpty();
- for (Atom atom : data) {
- assertThat(atom.getKernelWakelock().hasName()).isTrue();
- assertThat(atom.getKernelWakelock().hasCount()).isTrue();
- assertThat(atom.getKernelWakelock().hasVersion()).isTrue();
- assertThat(atom.getKernelWakelock().getVersion()).isGreaterThan(0);
- assertThat(atom.getKernelWakelock().hasTimeMicros()).isTrue();
- }
- }
-
- // Returns true iff either |WAKE_LOCK_FILE| or |WAKE_SOURCES_FILE| exists.
- private boolean kernelWakelockStatsExist() {
- try {
- return doesFileExist(WAKE_LOCK_FILE) || doesFileExist(WAKE_SOURCES_FILE);
- } catch(Exception e) {
- return false;
- }
- }
-
- public void testWifiActivityInfo() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
- if (!hasFeature(FEATURE_WATCH, false)) return;
- if (!checkDeviceFor("checkWifiEnhancedPowerReportingSupported")) return;
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.WIFI_ACTIVITY_INFO_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> dataList = getGaugeMetricDataList();
-
- for (Atom atom: dataList) {
- assertThat(atom.getWifiActivityInfo().getTimestampMillis()).isGreaterThan(0L);
- assertThat(atom.getWifiActivityInfo().getStackState()).isAtLeast(0);
- assertThat(atom.getWifiActivityInfo().getControllerIdleTimeMillis()).isGreaterThan(0L);
- assertThat(atom.getWifiActivityInfo().getControllerTxTimeMillis()).isAtLeast(0L);
- assertThat(atom.getWifiActivityInfo().getControllerRxTimeMillis()).isAtLeast(0L);
- assertThat(atom.getWifiActivityInfo().getControllerEnergyUsed()).isAtLeast(0L);
- }
- }
-
- public void testBuildInformation() throws Exception {
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.BUILD_INFORMATION_FIELD_NUMBER, null);
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
- assertThat(data).isNotEmpty();
- BuildInformation atom = data.get(0).getBuildInformation();
- assertThat(getProperty("ro.product.brand")).isEqualTo(atom.getBrand());
- assertThat(getProperty("ro.product.name")).isEqualTo(atom.getProduct());
- assertThat(getProperty("ro.product.device")).isEqualTo(atom.getDevice());
- assertThat(getProperty("ro.build.version.release_or_codename")).isEqualTo(atom.getVersionRelease());
- assertThat(getProperty("ro.build.id")).isEqualTo(atom.getId());
- assertThat(getProperty("ro.build.version.incremental"))
- .isEqualTo(atom.getVersionIncremental());
- assertThat(getProperty("ro.build.type")).isEqualTo(atom.getType());
- assertThat(getProperty("ro.build.tags")).isEqualTo(atom.getTags());
- }
-
- public void testOnDevicePowerMeasurement() throws Exception {
- if (!OPTIONAL_TESTS_ENABLED) return;
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.ON_DEVICE_POWER_MEASUREMENT_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> dataList = getGaugeMetricDataList();
-
- for (Atom atom: dataList) {
- assertThat(atom.getOnDevicePowerMeasurement().getMeasurementTimestampMillis())
- .isAtLeast(0L);
- assertThat(atom.getOnDevicePowerMeasurement().getEnergyMicrowattSecs()).isAtLeast(0L);
- }
- }
-
- // Explicitly tests if the adb command to log a breadcrumb is working.
- public void testBreadcrumbAdb() throws Exception {
- final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER;
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<EventMetricData> data = getEventMetricDataList();
- AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
- assertThat(atom.getLabel()).isEqualTo(1);
- assertThat(atom.getState().getNumber()).isEqualTo(AppBreadcrumbReported.State.START_VALUE);
- }
-
- // Test dumpsys stats --proto.
- public void testDumpsysStats() throws Exception {
- final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER;
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Get the stats incident section.
- List<ConfigMetricsReportList> listList = getReportsFromStatsDataDumpProto();
- assertThat(listList).isNotEmpty();
-
- // Extract the relevent report from the incident section.
- ConfigMetricsReportList ourList = null;
- int hostUid = getHostUid();
- for (ConfigMetricsReportList list : listList) {
- ConfigMetricsReportList.ConfigKey configKey = list.getConfigKey();
- if (configKey.getUid() == hostUid && configKey.getId() == CONFIG_ID) {
- ourList = list;
- break;
- }
- }
- assertWithMessage(String.format("Could not find list for uid=%d id=%d", hostUid, CONFIG_ID))
- .that(ourList).isNotNull();
-
- // Make sure that the report is correct.
- List<EventMetricData> data = getEventMetricDataList(ourList);
- AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
- assertThat(atom.getLabel()).isEqualTo(1);
- assertThat(atom.getState().getNumber()).isEqualTo(AppBreadcrumbReported.State.START_VALUE);
- }
-
- public void testConnectivityStateChange() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
- if (!hasFeature(FEATURE_WATCH, false)) return;
- if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-
- final int atomTag = Atom.CONNECTIVITY_STATE_CHANGED_FIELD_NUMBER;
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
-
- turnOnAirplaneMode();
- // wait long enough for airplane mode events to propagate.
- Thread.sleep(1_200);
- turnOffAirplaneMode();
- // wait long enough for the device to restore connection
- Thread.sleep(13_000);
-
- List<EventMetricData> data = getEventMetricDataList();
- // at least 1 disconnect and 1 connect
- assertThat(data.size()).isAtLeast(2);
- boolean foundDisconnectEvent = false;
- boolean foundConnectEvent = false;
- for (EventMetricData d : data) {
- ConnectivityStateChanged atom = d.getAtom().getConnectivityStateChanged();
- if(atom.getState().getNumber()
- == ConnectivityStateChanged.State.DISCONNECTED_VALUE) {
- foundDisconnectEvent = true;
- }
- if(atom.getState().getNumber()
- == ConnectivityStateChanged.State.CONNECTED_VALUE) {
- foundConnectEvent = true;
- }
- }
- assertThat(foundConnectEvent).isTrue();
- assertThat(foundDisconnectEvent).isTrue();
- }
-
- public void testSimSlotState() throws Exception {
- if (!hasFeature(FEATURE_TELEPHONY, true)) {
- return;
- }
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.SIM_SLOT_STATE_FIELD_NUMBER, null);
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
- assertThat(data).isNotEmpty();
- SimSlotState atom = data.get(0).getSimSlotState();
- // NOTE: it is possible for devices with telephony support to have no SIM at all
- assertThat(atom.getActiveSlotCount()).isEqualTo(getActiveSimSlotCount());
- assertThat(atom.getSimCount()).isAtMost(getActiveSimCountUpperBound());
- assertThat(atom.getEsimCount()).isAtMost(getActiveEsimCountUpperBound());
- // Above assertions do no necessarily enforce the following, since some are upper bounds
- assertThat(atom.getActiveSlotCount()).isAtLeast(atom.getSimCount());
- assertThat(atom.getSimCount()).isAtLeast(atom.getEsimCount());
- assertThat(atom.getEsimCount()).isAtLeast(0);
- // For GSM phones, at least one slot should be active even if there is no card
- if (hasGsmPhone()) {
- assertThat(atom.getActiveSlotCount()).isAtLeast(1);
- }
- }
-
- public void testSupportedRadioAccessFamily() throws Exception {
- if (!hasFeature(FEATURE_TELEPHONY, true)) {
- return;
- }
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.SUPPORTED_RADIO_ACCESS_FAMILY_FIELD_NUMBER, null);
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> data = getGaugeMetricDataList();
- assertThat(data).isNotEmpty();
- SupportedRadioAccessFamily atom = data.get(0).getSupportedRadioAccessFamily();
- if (hasGsmPhone()) {
- assertThat(atom.getNetworkTypeBitmask() & NETWORK_TYPE_BITMASK_GSM_ALL)
- .isNotEqualTo(0L);
- }
- if (hasCdmaPhone()) {
- assertThat(atom.getNetworkTypeBitmask() & NETWORK_TYPE_BITMASK_CDMA_ALL)
- .isNotEqualTo(0L);
- }
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
deleted file mode 100644
index 230a516..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
+++ /dev/null
@@ -1,247 +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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.app.ProcessStateEnum; // From enums.proto for atoms.proto's UidProcessStateChanged.
-
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Statsd atom tests that are done via app, for atoms that report a uid.
- */
-public class ProcStateAtomTests extends ProcStateTestCase {
-
- private static final String TAG = "Statsd.ProcStateAtomTests";
-
- private static final int WAIT_TIME_FOR_CONFIG_UPDATE_MS = 200;
- // ActivityManager can take a while to register screen state changes, mandating an extra delay.
- private static final int WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS = 1_000;
- private static final int EXTRA_WAIT_TIME_MS = 5_000; // as buffer when proc state changing.
- private static final int STATSD_REPORT_WAIT_TIME_MS = 500; // make sure statsd finishes log.
-
- private static final String FEATURE_WATCH = "android.hardware.type.watch";
-
- // The tests here are using the BatteryStats definition of 'background'.
- private static final Set<Integer> BG_STATES = new HashSet<>(
- Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_IMPORTANT_BACKGROUND_VALUE,
- ProcessStateEnum.PROCESS_STATE_TRANSIENT_BACKGROUND_VALUE,
- ProcessStateEnum.PROCESS_STATE_BACKUP_VALUE,
- ProcessStateEnum.PROCESS_STATE_SERVICE_VALUE,
- ProcessStateEnum.PROCESS_STATE_RECEIVER_VALUE,
- ProcessStateEnum.PROCESS_STATE_HEAVY_WEIGHT_VALUE
- ));
-
- // Using the BatteryStats definition of 'cached', which is why HOME (etc) are considered cached.
- private static final Set<Integer> CACHED_STATES = new HashSet<>(
- Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_HOME_VALUE,
- ProcessStateEnum.PROCESS_STATE_LAST_ACTIVITY_VALUE,
- ProcessStateEnum.PROCESS_STATE_CACHED_ACTIVITY_VALUE,
- ProcessStateEnum.PROCESS_STATE_CACHED_ACTIVITY_CLIENT_VALUE,
- ProcessStateEnum.PROCESS_STATE_CACHED_RECENT_VALUE,
- ProcessStateEnum.PROCESS_STATE_CACHED_EMPTY_VALUE
- ));
-
- private static final Set<Integer> MISC_STATES = new HashSet<>(
- Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_PERSISTENT_VALUE, // TODO: untested
- ProcessStateEnum.PROCESS_STATE_PERSISTENT_UI_VALUE, // TODO: untested
- ProcessStateEnum.PROCESS_STATE_TOP_VALUE,
- ProcessStateEnum.PROCESS_STATE_BOUND_TOP_VALUE, // TODO: untested
- ProcessStateEnum.PROCESS_STATE_BOUND_FOREGROUND_SERVICE_VALUE, // TODO: untested
- ProcessStateEnum.PROCESS_STATE_FOREGROUND_SERVICE_VALUE,
- ProcessStateEnum.PROCESS_STATE_IMPORTANT_FOREGROUND_VALUE,
- ProcessStateEnum.PROCESS_STATE_TOP_SLEEPING_VALUE,
-
- ProcessStateEnum.PROCESS_STATE_UNKNOWN_VALUE,
- ProcessStateEnum.PROCESS_STATE_NONEXISTENT_VALUE
- ));
-
- private static final Set<Integer> ALL_STATES = Stream.of(MISC_STATES, CACHED_STATES, BG_STATES)
- .flatMap(s -> s.stream()).collect(Collectors.toSet());
-
- private static final Function<Atom, Integer> PROC_STATE_FUNCTION =
- atom -> atom.getUidProcessStateChanged().getState().getNumber();
-
- private static final int PROC_STATE_ATOM_TAG = Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- public void testForegroundService() throws Exception {
- Set<Integer> onStates = new HashSet<>(Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_FOREGROUND_SERVICE_VALUE));
- Set<Integer> offStates = complement(onStates);
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(PROC_STATE_ATOM_TAG, false); // False: does not use attribution.
- Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
- executeForegroundService();
- final int waitTime = SLEEP_OF_FOREGROUND_SERVICE;
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS + EXTRA_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
- assertStatesOccurred(stateSet, data, waitTime, PROC_STATE_FUNCTION);
- }
-
- public void testForeground() throws Exception {
- Set<Integer> onStates = new HashSet<>(Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_IMPORTANT_FOREGROUND_VALUE));
- // There are no offStates, since the app remains in foreground until killed.
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates); // state sets, in order
- createAndUploadConfig(PROC_STATE_ATOM_TAG, false); // False: does not use attribution.
-
- Thread.sleep(WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS);
-
- executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
- final int waitTime = EXTRA_WAIT_TIME_MS + 5_000; // Overlay may need to sit there a while.
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
- assertStatesOccurred(stateSet, data, 0, PROC_STATE_FUNCTION);
- }
-
- public void testBackground() throws Exception {
- Set<Integer> onStates = BG_STATES;
- Set<Integer> offStates = complement(onStates);
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(PROC_STATE_ATOM_TAG, false); // False: does not use attribution.
- Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
- executeBackgroundService(ACTION_BACKGROUND_SLEEP);
- final int waitTime = SLEEP_OF_ACTION_BACKGROUND_SLEEP;
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS + EXTRA_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
- assertStatesOccurred(stateSet, data, waitTime, PROC_STATE_FUNCTION);
- }
-
- public void testTop() throws Exception {
- Set<Integer> onStates = new HashSet<>(Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_TOP_VALUE));
- Set<Integer> offStates = complement(onStates);
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(PROC_STATE_ATOM_TAG, false); // False: does not use attribution.
-
- Thread.sleep(WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS);
-
- executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
- final int waitTime = SLEEP_OF_ACTION_SLEEP_WHILE_TOP;
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS + EXTRA_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
- assertStatesOccurred(stateSet, data, waitTime, PROC_STATE_FUNCTION);
- }
-
- public void testTopSleeping() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- Set<Integer> onStates = new HashSet<>(Arrays.asList(
- ProcessStateEnum.PROCESS_STATE_TOP_SLEEPING_VALUE));
- Set<Integer> offStates = complement(onStates);
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(PROC_STATE_ATOM_TAG, false); //False: does not use attribution.
-
- turnScreenOn();
- Thread.sleep(WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS);
-
- executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
- // ASAP, turn off the screen to make proc state -> top_sleeping.
- turnScreenOff();
- final int waitTime = SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS;
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- popUntilFind(data, new HashSet<>(Arrays.asList(ProcessStateEnum.PROCESS_STATE_TOP_VALUE)),
- PROC_STATE_FUNCTION); // clear out anything prior to it entering TOP.
- popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out TOP itself.
- // reset screen back on
- turnScreenOn();
- // Don't check the wait time, since it's up to the system how long top sleeping persists.
- assertStatesOccurred(stateSet, data, 0, PROC_STATE_FUNCTION);
- }
-
- public void testCached() throws Exception {
- Set<Integer> onStates = CACHED_STATES;
- Set<Integer> offStates = complement(onStates);
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(PROC_STATE_ATOM_TAG, false); // False: des not use attribution.
- Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
- // The schedule is as follows
- // #1. The system may do anything it wants, such as moving the app into a cache state.
- // #2. We move the app into the background.
- // #3. The background process ends, so the app definitely moves to a cache state
- // (this is the ultimate goal of the test).
- // #4. We start a foreground activity, moving the app out of cache.
-
- // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
- executeBackgroundService(ACTION_END_IMMEDIATELY);
- final int cacheTime = 2_000; // process should be in cached state for up to this long
- Thread.sleep(cacheTime);
- // Now forcibly bring the app out of cache (#4 above).
- executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
- // Now check the data *before* the app enters cache again (to avoid another cache event).
-
- List<EventMetricData> data = getEventMetricDataList();
- // First, clear out any incidental cached states of step #1, prior to step #2.
- popUntilFind(data, BG_STATES, PROC_STATE_FUNCTION);
- // Now clear out the bg state from step #2 (since we are interested in the cache after it).
- popUntilFind(data, onStates, PROC_STATE_FUNCTION);
- // The result is that data should start at step #3, definitively in a cached state.
- assertStatesOccurred(stateSet, data, 1_000, PROC_STATE_FUNCTION);
- }
-
- public void testValidityOfStates() throws Exception {
- assertWithMessage("UNKNOWN_TO_PROTO should not be a valid state")
- .that(ALL_STATES).doesNotContain(ProcessStateEnum.PROCESS_STATE_UNKNOWN_TO_PROTO_VALUE);
- }
-
- /** Returns the a set containing elements of a that are not elements of b. */
- private Set<Integer> difference(Set<Integer> a, Set<Integer> b) {
- Set<Integer> result = new HashSet<Integer>(a);
- result.removeAll(b);
- return result;
- }
-
- /** Returns the set of all states that are not in set. */
- private Set<Integer> complement(Set<Integer> set) {
- return difference(ALL_STATES, set);
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateTestCase.java
deleted file mode 100644
index 2fa4233..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateTestCase.java
+++ /dev/null
@@ -1,76 +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 android.cts.statsd.atom;
-
-import android.app.ProcessStateEnum; // From enums.proto for atoms.proto's UidProcessStateChanged.
-
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Base class for manipulating process states
- */
-public class ProcStateTestCase extends DeviceAtomTestCase {
-
- private static final String TAG = "Statsd.ProcStateTestCase";
-
- private static final String DEVICE_SIDE_FG_ACTIVITY_COMPONENT
- = "com.android.server.cts.device.statsd/.StatsdCtsForegroundActivity";
- private static final String DEVICE_SIDE_FG_SERVICE_COMPONENT
- = "com.android.server.cts.device.statsd/.StatsdCtsForegroundService";
-
- // Constants from the device-side tests (not directly accessible here).
- public static final String ACTION_END_IMMEDIATELY = "action.end_immediately";
- public static final String ACTION_BACKGROUND_SLEEP = "action.background_sleep";
- public static final String ACTION_SLEEP_WHILE_TOP = "action.sleep_top";
- public static final String ACTION_LONG_SLEEP_WHILE_TOP = "action.long_sleep_top";
- public static final String ACTION_SHOW_APPLICATION_OVERLAY = "action.show_application_overlay";
-
- // Sleep times (ms) that actions invoke device-side.
- public static final int SLEEP_OF_ACTION_SLEEP_WHILE_TOP = 2_000;
- public static final int SLEEP_OF_ACTION_LONG_SLEEP_WHILE_TOP = 60_000;
- public static final int SLEEP_OF_ACTION_BACKGROUND_SLEEP = 2_000;
- public static final int SLEEP_OF_FOREGROUND_SERVICE = 2_000;
-
-
- /**
- * Runs an activity (in the foreground) to perform the given action.
- * @param actionValue the action code constants indicating the desired action to perform.
- */
- protected void executeForegroundActivity(String actionValue) throws Exception {
- getDevice().executeShellCommand(String.format(
- "am start -n '%s' -e %s %s",
- DEVICE_SIDE_FG_ACTIVITY_COMPONENT,
- KEY_ACTION, actionValue));
- }
-
- /**
- * Runs a simple foreground service.
- */
- protected void executeForegroundService() throws Exception {
- executeForegroundActivity(ACTION_END_IMMEDIATELY);
- getDevice().executeShellCommand(String.format(
- "am startservice -n '%s'", DEVICE_SIDE_FG_SERVICE_COMPONENT));
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
deleted file mode 100644
index f41bd86..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ /dev/null
@@ -1,2254 +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.cts.statsd.atom;
-
-import static com.android.os.AtomsProto.IntegrityCheckResultReported.Response.ALLOWED;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.app.AppOpEnum;
-import android.net.wifi.WifiModeEnum;
-import android.os.WakeLockLevelEnum;
-import android.server.ErrorSource;
-import android.telephony.NetworkTypeEnum;
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.compatibility.common.util.PropertyUtil;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto;
-import com.android.os.AtomsProto.ANROccurred;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.AppCrashOccurred;
-import com.android.os.AtomsProto.AppOps;
-import com.android.os.AtomsProto.AppStartOccurred;
-import com.android.os.AtomsProto.AppUsageEventOccurred;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.AttributedAppOps;
-import com.android.os.AtomsProto.AttributionNode;
-import com.android.os.AtomsProto.AudioStateChanged;
-import com.android.os.AtomsProto.BinderCalls;
-import com.android.os.AtomsProto.BleScanResultReceived;
-import com.android.os.AtomsProto.BleScanStateChanged;
-import com.android.os.AtomsProto.BlobCommitted;
-import com.android.os.AtomsProto.BlobLeased;
-import com.android.os.AtomsProto.BlobOpened;
-import com.android.os.AtomsProto.CameraStateChanged;
-import com.android.os.AtomsProto.DangerousPermissionState;
-import com.android.os.AtomsProto.DangerousPermissionStateSampled;
-import com.android.os.AtomsProto.DeviceCalculatedPowerBlameUid;
-import com.android.os.AtomsProto.FlashlightStateChanged;
-import com.android.os.AtomsProto.ForegroundServiceAppOpSessionEnded;
-import com.android.os.AtomsProto.ForegroundServiceStateChanged;
-import com.android.os.AtomsProto.GpsScanStateChanged;
-import com.android.os.AtomsProto.HiddenApiUsed;
-import com.android.os.AtomsProto.IntegrityCheckResultReported;
-import com.android.os.AtomsProto.IonHeapSize;
-import com.android.os.AtomsProto.LmkKillOccurred;
-import com.android.os.AtomsProto.LooperStats;
-import com.android.os.AtomsProto.MediaCodecStateChanged;
-import com.android.os.AtomsProto.NotificationReported;
-import com.android.os.AtomsProto.OverlayStateChanged;
-import com.android.os.AtomsProto.PackageNotificationChannelGroupPreferences;
-import com.android.os.AtomsProto.PackageNotificationChannelPreferences;
-import com.android.os.AtomsProto.PackageNotificationPreferences;
-import com.android.os.AtomsProto.PictureInPictureStateChanged;
-import com.android.os.AtomsProto.ProcessMemoryHighWaterMark;
-import com.android.os.AtomsProto.ProcessMemorySnapshot;
-import com.android.os.AtomsProto.ProcessMemoryState;
-import com.android.os.AtomsProto.ScheduledJobStateChanged;
-import com.android.os.AtomsProto.SettingSnapshot;
-import com.android.os.AtomsProto.SyncStateChanged;
-import com.android.os.AtomsProto.TestAtomReported;
-import com.android.os.AtomsProto.UiEventReported;
-import com.android.os.AtomsProto.VibratorStateChanged;
-import com.android.os.AtomsProto.WakelockStateChanged;
-import com.android.os.AtomsProto.WakeupAlarmOccurred;
-import com.android.os.AtomsProto.WifiLockStateChanged;
-import com.android.os.AtomsProto.WifiMulticastLockStateChanged;
-import com.android.os.AtomsProto.WifiScanStateChanged;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.server.notification.SmallHash;
-import com.android.tradefed.log.LogUtil;
-import com.google.common.collect.Range;
-import com.google.protobuf.Descriptors;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * Statsd atom tests that are done via app, for atoms that report a uid.
- */
-public class UidAtomTests extends DeviceAtomTestCase {
-
- private static final String TAG = "Statsd.UidAtomTests";
-
- private static final String TEST_PACKAGE_NAME = "com.android.server.cts.device.statsd";
-
- private static final boolean DAVEY_ENABLED = false;
-
- private static final int NUM_APP_OPS = AttributedAppOps.getDefaultInstance().getOp().
- getDescriptorForType().getValues().size() - 1;
-
- private static final String TEST_INSTALL_APK = "CtsStatsdEmptyApp.apk";
- private static final String TEST_INSTALL_APK_BASE = "CtsStatsdEmptySplitApp.apk";
- private static final String TEST_INSTALL_APK_SPLIT = "CtsStatsdEmptySplitApp_pl.apk";
- private static final String TEST_INSTALL_PACKAGE =
- "com.android.cts.device.statsd.emptyapp";
- private static final String TEST_REMOTE_DIR = "/data/local/tmp/statsd";
- private static final String ACTION_SHOW_APPLICATION_OVERLAY = "action.show_application_overlay";
- private static final String ACTION_LONG_SLEEP_WHILE_TOP = "action.long_sleep_top";
-
- private static final int WAIT_TIME_FOR_CONFIG_UPDATE_MS = 200;
- private static final int EXTRA_WAIT_TIME_MS = 5_000; // as buffer when app starting/stopping.
- private static final int STATSD_REPORT_WAIT_TIME_MS = 500; // make sure statsd finishes log.
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- resetBatteryStatus();
- super.tearDown();
- }
-
- public void testLmkKillOccurred() throws Exception {
- if (!"true".equals(getProperty("ro.lmk.log_stats"))) {
- return;
- }
-
- final int atomTag = Atom.LMK_KILL_OCCURRED_FIELD_NUMBER;
- createAndUploadConfig(atomTag, false);
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- executeBackgroundService(ACTION_LMK);
- Thread.sleep(15_000);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- assertThat(data).hasSize(1);
- assertThat(data.get(0).getAtom().hasLmkKillOccurred()).isTrue();
- LmkKillOccurred atom = data.get(0).getAtom().getLmkKillOccurred();
- assertThat(atom.getUid()).isEqualTo(getUid());
- assertThat(atom.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(atom.getOomAdjScore()).isAtLeast(500);
- }
-
- public void testAppCrashOccurred() throws Exception {
- final int atomTag = Atom.APP_CRASH_OCCURRED_FIELD_NUMBER;
- createAndUploadConfig(atomTag, false);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runActivity("StatsdCtsForegroundActivity", "action", "action.crash");
-
- Thread.sleep(WAIT_TIME_SHORT);
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- AppCrashOccurred atom = data.get(0).getAtom().getAppCrashOccurred();
- assertThat(atom.getEventType()).isEqualTo("crash");
- assertThat(atom.getIsInstantApp().getNumber())
- .isEqualTo(AppCrashOccurred.InstantApp.FALSE_VALUE);
- assertThat(atom.getForegroundState().getNumber())
- .isEqualTo(AppCrashOccurred.ForegroundState.FOREGROUND_VALUE);
- assertThat(atom.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- }
-
- public void testAppStartOccurred() throws Exception {
- final int atomTag = Atom.APP_START_OCCURRED_FIELD_NUMBER;
-
- createAndUploadConfig(atomTag, false);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runActivity("StatsdCtsForegroundActivity", "action", "action.sleep_top", 3_500);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- assertThat(data).hasSize(1);
- AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred();
- assertThat(atom.getPkgName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(atom.getActivityName())
- .isEqualTo("com.android.server.cts.device.statsd.StatsdCtsForegroundActivity");
- assertThat(atom.getIsInstantApp()).isFalse();
- assertThat(atom.getActivityStartMillis()).isGreaterThan(0L);
- assertThat(atom.getTransitionDelayMillis()).isGreaterThan(0);
- }
-
- public void testAudioState() throws Exception {
- if (!hasFeature(FEATURE_AUDIO_OUTPUT, true)) return;
-
- final int atomTag = Atom.AUDIO_STATE_CHANGED_FIELD_NUMBER;
- final String name = "testAudioState";
-
- Set<Integer> onState = new HashSet<>(
- Arrays.asList(AudioStateChanged.State.ON_VALUE));
- Set<Integer> offState = new HashSet<>(
- Arrays.asList(AudioStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(onState, offState);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
- Thread.sleep(WAIT_TIME_SHORT);
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Because the timestamp is truncated, we skip checking time differences between state
- // changes.
- assertStatesOccurred(stateSet, data, 0,
- atom -> atom.getAudioStateChanged().getState().getNumber());
-
- // Check that timestamp is truncated
- for (EventMetricData metric : data) {
- long elapsedTimestampNs = metric.getElapsedTimestampNanos();
- assertTimestampIsTruncated(elapsedTimestampNs);
- }
- }
-
- public void testBleScan() throws Exception {
- if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-
- final int atom = Atom.BLE_SCAN_STATE_CHANGED_FIELD_NUMBER;
- final int field = BleScanStateChanged.STATE_FIELD_NUMBER;
- final int stateOn = BleScanStateChanged.State.ON_VALUE;
- final int stateOff = BleScanStateChanged.State.OFF_VALUE;
- final int minTimeDiffMillis = 1_500;
- final int maxTimeDiffMillis = 3_000;
-
- List<EventMetricData> data = doDeviceMethodOnOff("testBleScanUnoptimized", atom, field,
- stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
- BleScanStateChanged a0 = data.get(0).getAtom().getBleScanStateChanged();
- BleScanStateChanged a1 = data.get(1).getAtom().getBleScanStateChanged();
- assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
- assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
- }
-
- public void testBleUnoptimizedScan() throws Exception {
- if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-
- final int atom = Atom.BLE_SCAN_STATE_CHANGED_FIELD_NUMBER;
- final int field = BleScanStateChanged.STATE_FIELD_NUMBER;
- final int stateOn = BleScanStateChanged.State.ON_VALUE;
- final int stateOff = BleScanStateChanged.State.OFF_VALUE;
- final int minTimeDiffMillis = 1_500;
- final int maxTimeDiffMillis = 3_000;
-
- List<EventMetricData> data = doDeviceMethodOnOff("testBleScanUnoptimized", atom, field,
- stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
- BleScanStateChanged a0 = data.get(0).getAtom().getBleScanStateChanged();
- assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
- assertThat(a0.getIsFiltered()).isFalse();
- assertThat(a0.getIsFirstMatch()).isFalse();
- assertThat(a0.getIsOpportunistic()).isFalse();
- BleScanStateChanged a1 = data.get(1).getAtom().getBleScanStateChanged();
- assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
- assertThat(a1.getIsFiltered()).isFalse();
- assertThat(a1.getIsFirstMatch()).isFalse();
- assertThat(a1.getIsOpportunistic()).isFalse();
-
-
- // Now repeat the test for opportunistic scanning and make sure it is reported correctly.
- data = doDeviceMethodOnOff("testBleScanOpportunistic", atom, field,
- stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
- a0 = data.get(0).getAtom().getBleScanStateChanged();
- assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
- assertThat(a0.getIsFiltered()).isFalse();
- assertThat(a0.getIsFirstMatch()).isFalse();
- assertThat(a0.getIsOpportunistic()).isTrue(); // This scan is opportunistic.
- a1 = data.get(1).getAtom().getBleScanStateChanged();
- assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
- assertThat(a1.getIsFiltered()).isFalse();
- assertThat(a1.getIsFirstMatch()).isFalse();
- assertThat(a1.getIsOpportunistic()).isTrue();
- }
-
- public void testBleScanResult() throws Exception {
- if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-
- final int atom = Atom.BLE_SCAN_RESULT_RECEIVED_FIELD_NUMBER;
- final int field = BleScanResultReceived.NUM_RESULTS_FIELD_NUMBER;
-
- StatsdConfig.Builder conf = createConfigBuilder();
- addAtomEvent(conf, atom, createFvm(field).setGteInt(0));
- List<EventMetricData> data = doDeviceMethod("testBleScanResult", conf);
-
- assertThat(data.size()).isAtLeast(1);
- BleScanResultReceived a0 = data.get(0).getAtom().getBleScanResultReceived();
- assertThat(a0.getNumResults()).isAtLeast(1);
- }
-
- public void testHiddenApiUsed() throws Exception {
- String oldRate = getDevice().executeShellCommand(
- "device_config get app_compat hidden_api_access_statslog_sampling_rate").trim();
-
- getDevice().executeShellCommand(
- "device_config put app_compat hidden_api_access_statslog_sampling_rate 65536");
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- try {
- final int atomTag = Atom.HIDDEN_API_USED_FIELD_NUMBER;
-
- createAndUploadConfig(atomTag, false);
-
- runActivity("HiddenApiUsedActivity", null, null, 2_500);
-
- List<EventMetricData> data = getEventMetricDataList();
- assertThat(data).hasSize(1);
-
- HiddenApiUsed atom = data.get(0).getAtom().getHiddenApiUsed();
-
- int uid = getUid();
- assertThat(atom.getUid()).isEqualTo(uid);
- assertThat(atom.getAccessDenied()).isFalse();
- assertThat(atom.getSignature())
- .isEqualTo("Landroid/app/Activity;->mWindow:Landroid/view/Window;");
- } finally {
- if (!oldRate.equals("null")) {
- getDevice().executeShellCommand(
- "device_config put app_compat hidden_api_access_statslog_sampling_rate "
- + oldRate);
- } else {
- getDevice().executeShellCommand(
- "device_config delete hidden_api_access_statslog_sampling_rate");
- }
- }
- }
-
- public void testCameraState() throws Exception {
- if (!hasFeature(FEATURE_CAMERA, true) && !hasFeature(FEATURE_CAMERA_FRONT, true)) return;
-
- final int atomTag = Atom.CAMERA_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> cameraOn = new HashSet<>(Arrays.asList(CameraStateChanged.State.ON_VALUE));
- Set<Integer> cameraOff = new HashSet<>(Arrays.asList(CameraStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(cameraOn, cameraOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testCameraState");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
- atom -> atom.getCameraStateChanged().getState().getNumber());
- }
-
- public void testCpuTimePerUid() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.CPU_TIME_PER_UID_FIELD_NUMBER, null);
-
- uploadConfig(config);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
-
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> atomList = getGaugeMetricDataList();
-
- // TODO: We don't have atom matching on gauge yet. Let's refactor this after that feature is
- // implemented.
- boolean found = false;
- int uid = getUid();
- for (Atom atom : atomList) {
- if (atom.getCpuTimePerUid().getUid() == uid) {
- found = true;
- assertThat(atom.getCpuTimePerUid().getUserTimeMicros()).isGreaterThan(0L);
- assertThat(atom.getCpuTimePerUid().getSysTimeMicros()).isGreaterThan(0L);
- }
- }
- assertWithMessage(String.format("did not find uid %d", uid)).that(found).isTrue();
- }
-
- public void testDeviceCalculatedPowerUse() throws Exception {
- if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.DEVICE_CALCULATED_POWER_USE_FIELD_NUMBER, null);
- uploadConfig(config);
- unplugDevice();
-
- Thread.sleep(WAIT_TIME_LONG);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- Atom atom = getGaugeMetricDataList().get(0);
- assertThat(atom.getDeviceCalculatedPowerUse().getComputedPowerNanoAmpSecs())
- .isGreaterThan(0L);
- }
-
-
- public void testDeviceCalculatedPowerBlameUid() throws Exception {
- if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
- if (!hasBattery()) {
- return;
- }
-
- String kernelVersion = getDevice().executeShellCommand("uname -r");
- if (kernelVersion.contains("3.18")) {
- LogUtil.CLog.d("Skipping calculated power blame uid test.");
- return;
- }
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config,
- Atom.DEVICE_CALCULATED_POWER_BLAME_UID_FIELD_NUMBER, null);
- uploadConfig(config);
- unplugDevice();
-
- Thread.sleep(WAIT_TIME_LONG);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- List<Atom> atomList = getGaugeMetricDataList();
- boolean uidFound = false;
- int uid = getUid();
- long uidPower = 0;
- for (Atom atom : atomList) {
- DeviceCalculatedPowerBlameUid item = atom.getDeviceCalculatedPowerBlameUid();
- if (item.getUid() == uid) {
- assertWithMessage(String.format("Found multiple power values for uid %d", uid))
- .that(uidFound).isFalse();
- uidFound = true;
- uidPower = item.getPowerNanoAmpSecs();
- }
- }
- assertWithMessage(String.format("No power value for uid %d", uid)).that(uidFound).isTrue();
- assertWithMessage(String.format("Non-positive power value for uid %d", uid))
- .that(uidPower).isGreaterThan(0L);
- }
-
- public void testDavey() throws Exception {
- if (!DAVEY_ENABLED ) return;
- long MAX_DURATION = 2000;
- long MIN_DURATION = 750;
- final int atomTag = Atom.DAVEY_OCCURRED_FIELD_NUMBER;
- createAndUploadConfig(atomTag, false); // UID is logged without attribution node
-
- runActivity("DaveyActivity", null, null);
-
- List<EventMetricData> data = getEventMetricDataList();
- assertThat(data).hasSize(1);
- long duration = data.get(0).getAtom().getDaveyOccurred().getJankDurationMillis();
- assertWithMessage("Incorrect jank duration")
- .that(duration).isIn(Range.closed(MIN_DURATION, MAX_DURATION));
- }
-
- public void testFlashlightState() throws Exception {
- if (!hasFeature(FEATURE_CAMERA_FLASH, true)) return;
-
- final int atomTag = Atom.FLASHLIGHT_STATE_CHANGED_FIELD_NUMBER;
- final String name = "testFlashlight";
-
- Set<Integer> flashlightOn = new HashSet<>(
- Arrays.asList(FlashlightStateChanged.State.ON_VALUE));
- Set<Integer> flashlightOff = new HashSet<>(
- Arrays.asList(FlashlightStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(flashlightOn, flashlightOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getFlashlightStateChanged().getState().getNumber());
- }
-
- public void testForegroundServiceState() throws Exception {
- final int atomTag = Atom.FOREGROUND_SERVICE_STATE_CHANGED_FIELD_NUMBER;
- final String name = "testForegroundService";
-
- Set<Integer> enterForeground = new HashSet<>(
- Arrays.asList(ForegroundServiceStateChanged.State.ENTER_VALUE));
- Set<Integer> exitForeground = new HashSet<>(
- Arrays.asList(ForegroundServiceStateChanged.State.EXIT_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(enterForeground, exitForeground);
-
- createAndUploadConfig(atomTag, false);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getForegroundServiceStateChanged().getState().getNumber());
- }
-
-
- public void testForegroundServiceAccessAppOp() throws Exception {
- final int atomTag = Atom.FOREGROUND_SERVICE_APP_OP_SESSION_ENDED_FIELD_NUMBER;
- final String name = "testForegroundServiceAccessAppOp";
-
- createAndUploadConfig(atomTag, false);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- assertWithMessage("Wrong atom size").that(data.size()).isEqualTo(3);
- for (int i = 0; i < data.size(); i++) {
- ForegroundServiceAppOpSessionEnded atom
- = data.get(i).getAtom().getForegroundServiceAppOpSessionEnded();
- final int opName = atom.getAppOpName().getNumber();
- final int acceptances = atom.getCountOpsAccepted();
- final int rejections = atom.getCountOpsRejected();
- final int count = acceptances + rejections;
- int expectedCount = 0;
- switch (opName) {
- case AppOpEnum.APP_OP_CAMERA_VALUE:
- expectedCount = 3;
- break;
- case AppOpEnum.APP_OP_FINE_LOCATION_VALUE:
- expectedCount = 1;
- break;
- case AppOpEnum.APP_OP_RECORD_AUDIO_VALUE:
- expectedCount = 2;
- break;
- case AppOpEnum.APP_OP_COARSE_LOCATION_VALUE:
- // fall-through
- default:
- fail("Unexpected opName " + opName);
- }
- assertWithMessage("Wrong count for " + opName).that(count).isEqualTo(expectedCount);
- }
- }
-
- public void testGpsScan() throws Exception {
- if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
- // Whitelist this app against background location request throttling
- String origWhitelist = getDevice().executeShellCommand(
- "settings get global location_background_throttle_package_whitelist").trim();
- getDevice().executeShellCommand(String.format(
- "settings put global location_background_throttle_package_whitelist %s",
- DEVICE_SIDE_TEST_PACKAGE));
-
- try {
- final int atom = Atom.GPS_SCAN_STATE_CHANGED_FIELD_NUMBER;
- final int key = GpsScanStateChanged.STATE_FIELD_NUMBER;
- final int stateOn = GpsScanStateChanged.State.ON_VALUE;
- final int stateOff = GpsScanStateChanged.State.OFF_VALUE;
- final int minTimeDiffMillis = 500;
- final int maxTimeDiffMillis = 60_000;
-
- List<EventMetricData> data = doDeviceMethodOnOff("testGpsScan", atom, key,
- stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
- GpsScanStateChanged a0 = data.get(0).getAtom().getGpsScanStateChanged();
- GpsScanStateChanged a1 = data.get(1).getAtom().getGpsScanStateChanged();
- assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
- assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
- } finally {
- if ("null".equals(origWhitelist) || "".equals(origWhitelist)) {
- getDevice().executeShellCommand(
- "settings delete global location_background_throttle_package_whitelist");
- } else {
- getDevice().executeShellCommand(String.format(
- "settings put global location_background_throttle_package_whitelist %s",
- origWhitelist));
- }
- }
- }
-
- public void testGnssStats() throws Exception {
- // Get GnssMetrics as a simple gauge metric.
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.GNSS_STATS_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
- // Whitelist this app against background location request throttling
- String origWhitelist = getDevice().executeShellCommand(
- "settings get global location_background_throttle_package_whitelist").trim();
- getDevice().executeShellCommand(String.format(
- "settings put global location_background_throttle_package_whitelist %s",
- DEVICE_SIDE_TEST_PACKAGE));
-
- try {
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testGpsStatus");
-
- Thread.sleep(WAIT_TIME_LONG);
- // Trigger a pull and wait for new pull before killing the process.
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
-
- // Assert about GnssMetrics for the test app.
- List<Atom> atoms = getGaugeMetricDataList();
-
- boolean found = false;
- for (Atom atom : atoms) {
- AtomsProto.GnssStats state = atom.getGnssStats();
- found = true;
- if ((state.getSvStatusReports() > 0 || state.getL5SvStatusReports() > 0)
- && state.getLocationReports() == 0) {
- // Device is detected to be indoors and not able to acquire location.
- // flaky test device
- break;
- }
- assertThat(state.getLocationReports()).isGreaterThan((long) 0);
- assertThat(state.getLocationFailureReports()).isAtLeast((long) 0);
- assertThat(state.getTimeToFirstFixReports()).isGreaterThan((long) 0);
- assertThat(state.getTimeToFirstFixMillis()).isGreaterThan((long) 0);
- assertThat(state.getPositionAccuracyReports()).isGreaterThan((long) 0);
- assertThat(state.getPositionAccuracyMeters()).isGreaterThan((long) 0);
- assertThat(state.getTopFourAverageCn0Reports()).isGreaterThan((long) 0);
- assertThat(state.getTopFourAverageCn0DbMhz()).isGreaterThan((long) 0);
- assertThat(state.getL5TopFourAverageCn0Reports()).isAtLeast((long) 0);
- assertThat(state.getL5TopFourAverageCn0DbMhz()).isAtLeast((long) 0);
- assertThat(state.getSvStatusReports()).isAtLeast((long) 0);
- assertThat(state.getSvStatusReportsUsedInFix()).isAtLeast((long) 0);
- assertThat(state.getL5SvStatusReports()).isAtLeast((long) 0);
- assertThat(state.getL5SvStatusReportsUsedInFix()).isAtLeast((long) 0);
- }
- assertWithMessage(String.format("Did not find a matching atom"))
- .that(found).isTrue();
- } finally {
- if ("null".equals(origWhitelist) || "".equals(origWhitelist)) {
- getDevice().executeShellCommand(
- "settings delete global location_background_throttle_package_whitelist");
- } else {
- getDevice().executeShellCommand(String.format(
- "settings put global location_background_throttle_package_whitelist %s",
- origWhitelist));
- }
- }
- }
-
- public void testMediaCodecActivity() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- final int atomTag = Atom.MEDIA_CODEC_STATE_CHANGED_FIELD_NUMBER;
-
- // 5 seconds. Starting video tends to be much slower than most other
- // tests on slow devices. This is unfortunate, because it leaves a
- // really big slop in assertStatesOccurred. It would be better if
- // assertStatesOccurred had a tighter range on large timeouts.
- final int waitTime = 5000;
-
- // From {@link VideoPlayerActivity#DELAY_MILLIS}
- final int videoDuration = 2000;
-
- Set<Integer> onState = new HashSet<>(
- Arrays.asList(MediaCodecStateChanged.State.ON_VALUE));
- Set<Integer> offState = new HashSet<>(
- Arrays.asList(MediaCodecStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(onState, offState);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- Thread.sleep(WAIT_TIME_SHORT);
-
- runActivity("VideoPlayerActivity", "action", "action.play_video",
- waitTime);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, videoDuration,
- atom -> atom.getMediaCodecStateChanged().getState().getNumber());
- }
-
- public void testOverlayState() throws Exception {
- if (!hasFeature(FEATURE_WATCH, false)) return;
- final int atomTag = Atom.OVERLAY_STATE_CHANGED_FIELD_NUMBER;
-
- Set<Integer> entered = new HashSet<>(
- Arrays.asList(OverlayStateChanged.State.ENTERED_VALUE));
- Set<Integer> exited = new HashSet<>(
- Arrays.asList(OverlayStateChanged.State.EXITED_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(entered, exited);
-
- createAndUploadConfig(atomTag, false);
-
- runActivity("StatsdCtsForegroundActivity", "action", "action.show_application_overlay",
- 5_000);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- // The overlay box should appear about 2sec after the app start
- assertStatesOccurred(stateSet, data, 0,
- atom -> atom.getOverlayStateChanged().getState().getNumber());
- }
-
- public void testPictureInPictureState() throws Exception {
- String supported = getDevice().executeShellCommand("am supports-multiwindow");
- if (!hasFeature(FEATURE_WATCH, false) ||
- !hasFeature(FEATURE_PICTURE_IN_PICTURE, true) ||
- !supported.contains("true")) {
- LogUtil.CLog.d("Skipping picture in picture atom test.");
- return;
- }
-
- StatsdConfig.Builder conf = createConfigBuilder();
- // PictureInPictureStateChanged atom is used prior to rvc-qpr
- addAtomEvent(conf, Atom.PICTURE_IN_PICTURE_STATE_CHANGED_FIELD_NUMBER,
- /*useAttribution=*/false);
- // Picture-in-picture logs' been migrated to UiEvent since rvc-qpr
- FieldValueMatcher.Builder pkgMatcher = createFvm(UiEventReported.PACKAGE_NAME_FIELD_NUMBER)
- .setEqString(DEVICE_SIDE_TEST_PACKAGE);
- addAtomEvent(conf, Atom.UI_EVENT_REPORTED_FIELD_NUMBER, Arrays.asList(pkgMatcher));
- uploadConfig(conf);
-
- LogUtil.CLog.d("Playing video in Picture-in-Picture mode");
- runActivity("VideoPlayerActivity", "action", "action.play_video_picture_in_picture_mode");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Filter out the PictureInPictureStateChanged and UiEventReported atom
- List<EventMetricData> pictureInPictureStateChangedData = data.stream()
- .filter(e -> e.getAtom().hasPictureInPictureStateChanged())
- .collect(Collectors.toList());
- List<EventMetricData> uiEventReportedData = data.stream()
- .filter(e -> e.getAtom().hasUiEventReported())
- .collect(Collectors.toList());
-
- if (!pictureInPictureStateChangedData.isEmpty()) {
- LogUtil.CLog.d("Assert using PictureInPictureStateChanged");
- Set<Integer> entered = new HashSet<>(
- Arrays.asList(PictureInPictureStateChanged.State.ENTERED_VALUE));
- List<Set<Integer>> stateSet = Arrays.asList(entered);
- assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
- atom -> atom.getPictureInPictureStateChanged().getState().getNumber());
- } else if (!uiEventReportedData.isEmpty()) {
- LogUtil.CLog.d("Assert using UiEventReported");
- // See PipUiEventEnum for definitions
- final int enterPipEventId = 603;
- // Assert that log for entering PiP happens exactly once, we do not use
- // assertStateOccurred here since PiP may log something else when activity finishes.
- List<EventMetricData> entered = uiEventReportedData.stream()
- .filter(e -> e.getAtom().getUiEventReported().getEventId() == enterPipEventId)
- .collect(Collectors.toList());
- assertThat(entered).hasSize(1);
- } else {
- fail("No logging event from PictureInPictureStateChanged nor UiEventReported");
- }
- }
-
- public void testScheduledJobState() throws Exception {
- String expectedName = "com.android.server.cts.device.statsd/.StatsdJobService";
- final int atomTag = Atom.SCHEDULED_JOB_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> jobSchedule = new HashSet<>(
- Arrays.asList(ScheduledJobStateChanged.State.SCHEDULED_VALUE));
- Set<Integer> jobOn = new HashSet<>(
- Arrays.asList(ScheduledJobStateChanged.State.STARTED_VALUE));
- Set<Integer> jobOff = new HashSet<>(
- Arrays.asList(ScheduledJobStateChanged.State.FINISHED_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(jobSchedule, jobOn, jobOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- allowImmediateSyncs();
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testScheduledJob");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- assertStatesOccurred(stateSet, data, 0,
- atom -> atom.getScheduledJobStateChanged().getState().getNumber());
-
- for (EventMetricData e : data) {
- assertThat(e.getAtom().getScheduledJobStateChanged().getJobName())
- .isEqualTo(expectedName);
- }
- }
-
- //Note: this test does not have uid, but must run on the device
- public void testScreenBrightness() throws Exception {
- int initialBrightness = getScreenBrightness();
- boolean isInitialManual = isScreenBrightnessModeManual();
- setScreenBrightnessMode(true);
- setScreenBrightness(200);
- Thread.sleep(WAIT_TIME_LONG);
-
- final int atomTag = Atom.SCREEN_BRIGHTNESS_CHANGED_FIELD_NUMBER;
-
- Set<Integer> screenMin = new HashSet<>(Arrays.asList(47));
- Set<Integer> screen100 = new HashSet<>(Arrays.asList(100));
- Set<Integer> screen200 = new HashSet<>(Arrays.asList(198));
- // Set<Integer> screenMax = new HashSet<>(Arrays.asList(255));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(screenMin, screen100, screen200);
-
- createAndUploadConfig(atomTag);
- Thread.sleep(WAIT_TIME_SHORT);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testScreenBrightness");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Restore initial screen brightness
- setScreenBrightness(initialBrightness);
- setScreenBrightnessMode(isInitialManual);
-
- popUntilFind(data, screenMin, atom->atom.getScreenBrightnessChanged().getLevel());
- popUntilFindFromEnd(data, screen200, atom->atom.getScreenBrightnessChanged().getLevel());
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getScreenBrightnessChanged().getLevel());
- }
- public void testSyncState() throws Exception {
- final int atomTag = Atom.SYNC_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> syncOn = new HashSet<>(Arrays.asList(SyncStateChanged.State.ON_VALUE));
- Set<Integer> syncOff = new HashSet<>(Arrays.asList(SyncStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(syncOn, syncOff, syncOn, syncOff);
-
- createAndUploadConfig(atomTag, true);
- allowImmediateSyncs();
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSyncState");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data,
- /* wait = */ 0 /* don't verify time differences between state changes */,
- atom -> atom.getSyncStateChanged().getState().getNumber());
- }
-
- public void testVibratorState() throws Exception {
- if (!checkDeviceFor("checkVibratorSupported")) return;
-
- final int atomTag = Atom.VIBRATOR_STATE_CHANGED_FIELD_NUMBER;
- final String name = "testVibratorState";
-
- Set<Integer> onState = new HashSet<>(
- Arrays.asList(VibratorStateChanged.State.ON_VALUE));
- Set<Integer> offState = new HashSet<>(
- Arrays.asList(VibratorStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(onState, offState);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
- Thread.sleep(WAIT_TIME_LONG);
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- assertStatesOccurred(stateSet, data, 300,
- atom -> atom.getVibratorStateChanged().getState().getNumber());
- }
-
- public void testWakelockState() throws Exception {
- final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> wakelockOn = new HashSet<>(Arrays.asList(
- WakelockStateChanged.State.ACQUIRE_VALUE,
- WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE));
- Set<Integer> wakelockOff = new HashSet<>(Arrays.asList(
- WakelockStateChanged.State.RELEASE_VALUE,
- WakelockStateChanged.State.CHANGE_RELEASE_VALUE));
-
- final String EXPECTED_TAG = "StatsdPartialWakelock";
- final WakeLockLevelEnum EXPECTED_LEVEL = WakeLockLevelEnum.PARTIAL_WAKE_LOCK;
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(wakelockOn, wakelockOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getWakelockStateChanged().getState().getNumber());
-
- for (EventMetricData event: data) {
- String tag = event.getAtom().getWakelockStateChanged().getTag();
- WakeLockLevelEnum type = event.getAtom().getWakelockStateChanged().getType();
- assertThat(tag).isEqualTo(EXPECTED_TAG);
- assertThat(type).isEqualTo(EXPECTED_LEVEL);
- }
- }
-
- public void testWakeupAlarm() throws Exception {
- // For automotive, all wakeup alarm becomes normal alarm. So this
- // test does not work.
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- final int atomTag = Atom.WAKEUP_ALARM_OCCURRED_FIELD_NUMBER;
-
- StatsdConfig.Builder config = createConfigBuilder();
- addAtomEvent(config, atomTag, true); // True: uses attribution.
-
- List<EventMetricData> data = doDeviceMethod("testWakeupAlarm", config);
- assertThat(data.size()).isAtLeast(1);
- for (int i = 0; i < data.size(); i++) {
- WakeupAlarmOccurred wao = data.get(i).getAtom().getWakeupAlarmOccurred();
- assertThat(wao.getTag()).isEqualTo("*walarm*:android.cts.statsd.testWakeupAlarm");
- assertThat(wao.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- }
- }
-
- public void testWifiLockHighPerf() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
- if (!hasFeature(FEATURE_PC, false)) return;
-
- final int atomTag = Atom.WIFI_LOCK_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> lockOn = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.ON_VALUE));
- Set<Integer> lockOff = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(lockOn, lockOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWifiLockHighPerf");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getWifiLockStateChanged().getState().getNumber());
-
- for (EventMetricData event : data) {
- assertThat(event.getAtom().getWifiLockStateChanged().getMode())
- .isEqualTo(WifiModeEnum.WIFI_MODE_FULL_HIGH_PERF);
- }
- }
-
- public void testWifiLockLowLatency() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
- if (!hasFeature(FEATURE_PC, false)) return;
-
- final int atomTag = Atom.WIFI_LOCK_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> lockOn = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.ON_VALUE));
- Set<Integer> lockOff = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.OFF_VALUE));
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(lockOn, lockOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWifiLockLowLatency");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getWifiLockStateChanged().getState().getNumber());
-
- for (EventMetricData event : data) {
- assertThat(event.getAtom().getWifiLockStateChanged().getMode())
- .isEqualTo(WifiModeEnum.WIFI_MODE_FULL_LOW_LATENCY);
- }
- }
-
- public void testWifiMulticastLock() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
- if (!hasFeature(FEATURE_PC, false)) return;
-
- final int atomTag = Atom.WIFI_MULTICAST_LOCK_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> lockOn = new HashSet<>(
- Arrays.asList(WifiMulticastLockStateChanged.State.ON_VALUE));
- Set<Integer> lockOff = new HashSet<>(
- Arrays.asList(WifiMulticastLockStateChanged.State.OFF_VALUE));
-
- final String EXPECTED_TAG = "StatsdCTSMulticastLock";
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(lockOn, lockOff);
-
- createAndUploadConfig(atomTag, true);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWifiMulticastLock");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getWifiMulticastLockStateChanged().getState().getNumber());
-
- for (EventMetricData event: data) {
- String tag = event.getAtom().getWifiMulticastLockStateChanged().getTag();
- assertThat(tag).isEqualTo(EXPECTED_TAG);
- }
- }
-
- public void testWifiScan() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
-
- final int atom = Atom.WIFI_SCAN_STATE_CHANGED_FIELD_NUMBER;
- final int key = WifiScanStateChanged.STATE_FIELD_NUMBER;
- final int stateOn = WifiScanStateChanged.State.ON_VALUE;
- final int stateOff = WifiScanStateChanged.State.OFF_VALUE;
- final int minTimeDiffMillis = 250;
- final int maxTimeDiffMillis = 60_000;
- final boolean demandExactlyTwo = false; // Two scans are performed, so up to 4 atoms logged.
-
- List<EventMetricData> data = doDeviceMethodOnOff("testWifiScan", atom, key,
- stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, demandExactlyTwo);
-
- assertThat(data.size()).isIn(Range.closed(2, 4));
- WifiScanStateChanged a0 = data.get(0).getAtom().getWifiScanStateChanged();
- WifiScanStateChanged a1 = data.get(1).getAtom().getWifiScanStateChanged();
- assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
- assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
- }
-
- public void testBinderStats() throws Exception {
- try {
- unplugDevice();
- Thread.sleep(WAIT_TIME_SHORT);
- enableBinderStats();
- binderStatsNoSampling();
- resetBinderStats();
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.BINDER_CALLS_FIELD_NUMBER, null);
-
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification",3_000);
-
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- boolean found = false;
- int uid = getUid();
- List<Atom> atomList = getGaugeMetricDataList();
- for (Atom atom : atomList) {
- BinderCalls calls = atom.getBinderCalls();
- boolean classMatches = calls.getServiceClassName().contains(
- "com.android.server.notification.NotificationManagerService");
- boolean methodMatches = calls.getServiceMethodName()
- .equals("createNotificationChannels");
-
- if (calls.getUid() == uid && classMatches && methodMatches) {
- found = true;
- assertThat(calls.getRecordedCallCount()).isGreaterThan(0L);
- assertThat(calls.getCallCount()).isGreaterThan(0L);
- assertThat(calls.getRecordedTotalLatencyMicros())
- .isIn(Range.open(0L, 1000000L));
- assertThat(calls.getRecordedTotalCpuMicros()).isIn(Range.open(0L, 1000000L));
- }
- }
-
- assertWithMessage(String.format("Did not find a matching atom for uid %d", uid))
- .that(found).isTrue();
-
- } finally {
- disableBinderStats();
- plugInAc();
- }
- }
-
- public void testLooperStats() throws Exception {
- try {
- unplugDevice();
- setUpLooperStats();
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.LOOPER_STATS_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification", 3_000);
-
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<Atom> atomList = getGaugeMetricDataList();
-
- boolean found = false;
- int uid = getUid();
- for (Atom atom : atomList) {
- LooperStats stats = atom.getLooperStats();
- String notificationServiceFullName =
- "com.android.server.notification.NotificationManagerService";
- boolean handlerMatches =
- stats.getHandlerClassName().equals(
- notificationServiceFullName + "$WorkerHandler");
- boolean messageMatches =
- stats.getMessageName().equals(
- notificationServiceFullName + "$EnqueueNotificationRunnable");
- if (atom.getLooperStats().getUid() == uid && handlerMatches && messageMatches) {
- found = true;
- assertThat(stats.getMessageCount()).isGreaterThan(0L);
- assertThat(stats.getRecordedMessageCount()).isGreaterThan(0L);
- assertThat(stats.getRecordedTotalLatencyMicros())
- .isIn(Range.open(0L, 1000000L));
- assertThat(stats.getRecordedTotalCpuMicros()).isIn(Range.open(0L, 1000000L));
- assertThat(stats.getRecordedMaxLatencyMicros()).isIn(Range.open(0L, 1000000L));
- assertThat(stats.getRecordedMaxCpuMicros()).isIn(Range.open(0L, 1000000L));
- assertThat(stats.getRecordedDelayMessageCount()).isGreaterThan(0L);
- assertThat(stats.getRecordedTotalDelayMillis())
- .isIn(Range.closedOpen(0L, 5000L));
- assertThat(stats.getRecordedMaxDelayMillis()).isIn(Range.closedOpen(0L, 5000L));
- }
- }
- assertWithMessage(String.format("Did not find a matching atom for uid %d", uid))
- .that(found).isTrue();
- } finally {
- cleanUpLooperStats();
- plugInAc();
- }
- }
-
- public void testProcessMemoryState() throws Exception {
- // Get ProcessMemoryState as a simple gauge metric.
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.PROCESS_MEMORY_STATE_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Start test app.
- try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
- "action.show_notification")) {
- Thread.sleep(WAIT_TIME_LONG);
- // Trigger a pull and wait for new pull before killing the process.
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
- }
-
- // Assert about ProcessMemoryState for the test app.
- List<Atom> atoms = getGaugeMetricDataList();
- int uid = getUid();
- boolean found = false;
- for (Atom atom : atoms) {
- ProcessMemoryState state = atom.getProcessMemoryState();
- if (state.getUid() != uid) {
- continue;
- }
- found = true;
- assertThat(state.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(state.getOomAdjScore()).isAtLeast(0);
- assertThat(state.getPageFault()).isAtLeast(0L);
- assertThat(state.getPageMajorFault()).isAtLeast(0L);
- assertThat(state.getRssInBytes()).isGreaterThan(0L);
- assertThat(state.getCacheInBytes()).isAtLeast(0L);
- assertThat(state.getSwapInBytes()).isAtLeast(0L);
- }
- assertWithMessage(String.format("Did not find a matching atom for uid %d", uid))
- .that(found).isTrue();
- }
-
- public void testProcessMemoryHighWaterMark() throws Exception {
- // Get ProcessMemoryHighWaterMark as a simple gauge metric.
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.PROCESS_MEMORY_HIGH_WATER_MARK_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Start test app and trigger a pull while it is running.
- try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
- "action.show_notification")) {
- Thread.sleep(WAIT_TIME_SHORT);
- // Trigger a pull and wait for new pull before killing the process.
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
- }
-
- // Assert about ProcessMemoryHighWaterMark for the test app, statsd and system server.
- List<Atom> atoms = getGaugeMetricDataList();
- int uid = getUid();
- boolean foundTestApp = false;
- boolean foundStatsd = false;
- boolean foundSystemServer = false;
- for (Atom atom : atoms) {
- ProcessMemoryHighWaterMark state = atom.getProcessMemoryHighWaterMark();
- if (state.getUid() == uid) {
- foundTestApp = true;
- assertThat(state.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(state.getRssHighWaterMarkInBytes()).isGreaterThan(0L);
- } else if (state.getProcessName().contains("/statsd")) {
- foundStatsd = true;
- assertThat(state.getRssHighWaterMarkInBytes()).isGreaterThan(0L);
- } else if (state.getProcessName().equals("system")) {
- foundSystemServer = true;
- assertThat(state.getRssHighWaterMarkInBytes()).isGreaterThan(0L);
- }
- }
- assertWithMessage(String.format("Did not find a matching atom for test app uid=%d",uid))
- .that(foundTestApp).isTrue();
- assertWithMessage("Did not find a matching atom for statsd").that(foundStatsd).isTrue();
- assertWithMessage("Did not find a matching atom for system server")
- .that(foundSystemServer).isTrue();
- }
-
- public void testProcessMemorySnapshot() throws Exception {
- // Get ProcessMemorySnapshot as a simple gauge metric.
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Start test app and trigger a pull while it is running.
- try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
- "action.show_notification")) {
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- }
-
- // Assert about ProcessMemorySnapshot for the test app, statsd and system server.
- List<Atom> atoms = getGaugeMetricDataList();
- int uid = getUid();
- boolean foundTestApp = false;
- boolean foundStatsd = false;
- boolean foundSystemServer = false;
- for (Atom atom : atoms) {
- ProcessMemorySnapshot snapshot = atom.getProcessMemorySnapshot();
- if (snapshot.getUid() == uid) {
- foundTestApp = true;
- assertThat(snapshot.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- } else if (snapshot.getProcessName().contains("/statsd")) {
- foundStatsd = true;
- } else if (snapshot.getProcessName().equals("system")) {
- foundSystemServer = true;
- }
-
- assertThat(snapshot.getPid()).isGreaterThan(0);
- assertThat(snapshot.getAnonRssAndSwapInKilobytes()).isAtLeast(0);
- assertThat(snapshot.getAnonRssAndSwapInKilobytes()).isEqualTo(
- snapshot.getAnonRssInKilobytes() + snapshot.getSwapInKilobytes());
- assertThat(snapshot.getRssInKilobytes()).isAtLeast(0);
- assertThat(snapshot.getAnonRssInKilobytes()).isAtLeast(0);
- assertThat(snapshot.getSwapInKilobytes()).isAtLeast(0);
- }
- assertWithMessage(String.format("Did not find a matching atom for test app uid=%d",uid))
- .that(foundTestApp).isTrue();
- assertWithMessage("Did not find a matching atom for statsd").that(foundStatsd).isTrue();
- assertWithMessage("Did not find a matching atom for system server")
- .that(foundSystemServer).isTrue();
- }
-
- public void testIonHeapSize_optional() throws Exception {
- if (isIonHeapSizeMandatory()) {
- return;
- }
-
- List<Atom> atoms = pullIonHeapSizeAsGaugeMetric();
- if (atoms.isEmpty()) {
- // No support.
- return;
- }
- assertIonHeapSize(atoms);
- }
-
- public void testIonHeapSize_mandatory() throws Exception {
- if (!isIonHeapSizeMandatory()) {
- return;
- }
-
- List<Atom> atoms = pullIonHeapSizeAsGaugeMetric();
- assertIonHeapSize(atoms);
- }
-
- /** Returns whether IonHeapSize atom is supported. */
- private boolean isIonHeapSizeMandatory() throws Exception {
- // Support is guaranteed by libmeminfo VTS.
- return PropertyUtil.getFirstApiLevel(getDevice()) >= 30;
- }
-
- /** Returns IonHeapSize atoms pulled as a simple gauge metric while test app is running. */
- private List<Atom> pullIonHeapSizeAsGaugeMetric() throws Exception {
- // Get IonHeapSize as a simple gauge metric.
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.ION_HEAP_SIZE_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Start test app and trigger a pull while it is running.
- try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
- "action.show_notification")) {
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
- }
-
- return getGaugeMetricDataList();
- }
-
- private static void assertIonHeapSize(List<Atom> atoms) {
- assertThat(atoms).hasSize(1);
- IonHeapSize ionHeapSize = atoms.get(0).getIonHeapSize();
- assertThat(ionHeapSize.getTotalSizeKb()).isAtLeast(0);
- }
-
- /**
- * The the app id from a uid.
- *
- * @param uid The uid of the app
- *
- * @return The app id of the app
- *
- * @see android.os.UserHandle#getAppId
- */
- private static int getAppId(int uid) {
- return uid % 100000;
- }
-
- public void testRoleHolder() throws Exception {
- // Make device side test package a role holder
- String callScreenAppRole = "android.app.role.CALL_SCREENING";
- getDevice().executeShellCommand(
- "cmd role add-role-holder " + callScreenAppRole + " " + DEVICE_SIDE_TEST_PACKAGE);
-
- // Set up what to collect
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.ROLE_HOLDER_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- boolean verifiedKnowRoleState = false;
-
- // Pull a report
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- int testAppId = getAppId(getUid());
-
- for (Atom atom : getGaugeMetricDataList()) {
- AtomsProto.RoleHolder roleHolder = atom.getRoleHolder();
-
- assertThat(roleHolder.getPackageName()).isNotNull();
- assertThat(roleHolder.getUid()).isAtLeast(0);
- assertThat(roleHolder.getRole()).isNotNull();
-
- if (roleHolder.getPackageName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
- assertThat(getAppId(roleHolder.getUid())).isEqualTo(testAppId);
- assertThat(roleHolder.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(roleHolder.getRole()).isEqualTo(callScreenAppRole);
-
- verifiedKnowRoleState = true;
- }
- }
-
- assertThat(verifiedKnowRoleState).isTrue();
- }
-
- public void testDangerousPermissionState() throws Exception {
- final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED = 1 << 8;
- final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED = 1 << 9;
-
- // Set up what to collect
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.DANGEROUS_PERMISSION_STATE_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- boolean verifiedKnowPermissionState = false;
-
- // Pull a report
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- int testAppId = getAppId(getUid());
-
- for (Atom atom : getGaugeMetricDataList()) {
- DangerousPermissionState permissionState = atom.getDangerousPermissionState();
-
- assertThat(permissionState.getPermissionName()).isNotNull();
- assertThat(permissionState.getUid()).isAtLeast(0);
- assertThat(permissionState.getPackageName()).isNotNull();
-
- if (getAppId(permissionState.getUid()) == testAppId) {
-
- if (permissionState.getPermissionName().contains(
- "ACCESS_FINE_LOCATION")) {
- assertThat(permissionState.getIsGranted()).isTrue();
- assertThat(permissionState.getPermissionFlags() & ~(
- FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED
- | FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED))
- .isEqualTo(0);
-
- verifiedKnowPermissionState = true;
- }
- }
- }
-
- assertThat(verifiedKnowPermissionState).isTrue();
- }
-
- public void testDangerousPermissionStateSampled() throws Exception {
- // get full atom for reference
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.DANGEROUS_PERMISSION_STATE_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<DangerousPermissionState> fullDangerousPermissionState = new ArrayList<>();
- for (Atom atom : getGaugeMetricDataList()) {
- fullDangerousPermissionState.add(atom.getDangerousPermissionState());
- }
-
- removeConfig(CONFIG_ID);
- getReportList(); // Clears data.
- List<Atom> gaugeMetricDataList = null;
-
- // retries in case sampling returns full list or empty list - which should be extremely rare
- for (int attempt = 0; attempt < 10; attempt++) {
- // Set up what to collect
- config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.DANGEROUS_PERMISSION_STATE_SAMPLED_FIELD_NUMBER,
- null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Pull a report
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- gaugeMetricDataList = getGaugeMetricDataList();
- if (gaugeMetricDataList.size() > 0
- && gaugeMetricDataList.size() < fullDangerousPermissionState.size()) {
- break;
- }
- removeConfig(CONFIG_ID);
- getReportList(); // Clears data.
- }
- assertThat(gaugeMetricDataList.size()).isGreaterThan(0);
- assertThat(gaugeMetricDataList.size()).isLessThan(fullDangerousPermissionState.size());
-
- long lastUid = -1;
- int fullIndex = 0;
-
- for (Atom atom : getGaugeMetricDataList()) {
- DangerousPermissionStateSampled permissionState =
- atom.getDangerousPermissionStateSampled();
-
- DangerousPermissionState referenceState = fullDangerousPermissionState.get(fullIndex);
-
- if (referenceState.getUid() != permissionState.getUid()) {
- // atoms are sampled on uid basis if uid is present, all related permissions must
- // be logged.
- assertThat(permissionState.getUid()).isNotEqualTo(lastUid);
- continue;
- }
-
- lastUid = permissionState.getUid();
-
- assertThat(permissionState.getPermissionFlags()).isEqualTo(
- referenceState.getPermissionFlags());
- assertThat(permissionState.getIsGranted()).isEqualTo(referenceState.getIsGranted());
- assertThat(permissionState.getPermissionName()).isEqualTo(
- referenceState.getPermissionName());
-
- fullIndex++;
- }
- }
-
- public void testAppOps() throws Exception {
- // Set up what to collect
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.APP_OPS_FIELD_NUMBER, null);
- uploadConfig(config);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testAppOps");
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Pull a report
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- ArrayList<Integer> expectedOps = new ArrayList<>();
- for (int i = 0; i < NUM_APP_OPS; i++) {
- expectedOps.add(i);
- }
-
- for (Descriptors.EnumValueDescriptor valueDescriptor :
- AttributedAppOps.getDefaultInstance().getOp().getDescriptorForType().getValues()) {
- if (valueDescriptor.getOptions().hasDeprecated()) {
- // Deprecated app op, remove from list of expected ones.
- expectedOps.remove(expectedOps.indexOf(valueDescriptor.getNumber()));
- }
- }
- for (Atom atom : getGaugeMetricDataList()) {
-
- AppOps appOps = atom.getAppOps();
- if (appOps.getPackageName().equals(TEST_PACKAGE_NAME)) {
- if (appOps.getOpId().getNumber() == -1) {
- continue;
- }
- long totalNoted = appOps.getTrustedForegroundGrantedCount()
- + appOps.getTrustedBackgroundGrantedCount()
- + appOps.getTrustedForegroundRejectedCount()
- + appOps.getTrustedBackgroundRejectedCount();
- assertWithMessage("Operation in APP_OPS_ENUM_MAP: " + appOps.getOpId().getNumber())
- .that(totalNoted - 1).isEqualTo(appOps.getOpId().getNumber());
- assertWithMessage("Unexpected Op reported").that(expectedOps).contains(
- appOps.getOpId().getNumber());
- expectedOps.remove(expectedOps.indexOf(appOps.getOpId().getNumber()));
- }
- }
- assertWithMessage("Logging app op ids are missing in report.").that(expectedOps).isEmpty();
- }
-
- public void testANROccurred() throws Exception {
- final int atomTag = Atom.ANR_OCCURRED_FIELD_NUMBER;
- createAndUploadConfig(atomTag, false);
- Thread.sleep(WAIT_TIME_SHORT);
-
- try (AutoCloseable a = withActivity("ANRActivity", null, null)) {
- Thread.sleep(WAIT_TIME_SHORT);
- getDevice().executeShellCommand(
- "am broadcast -a action_anr -p " + DEVICE_SIDE_TEST_PACKAGE);
- Thread.sleep(20_000);
- }
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- assertThat(data).hasSize(1);
- assertThat(data.get(0).getAtom().hasAnrOccurred()).isTrue();
- ANROccurred atom = data.get(0).getAtom().getAnrOccurred();
- assertThat(atom.getIsInstantApp().getNumber())
- .isEqualTo(ANROccurred.InstantApp.FALSE_VALUE);
- assertThat(atom.getForegroundState().getNumber())
- .isEqualTo(ANROccurred.ForegroundState.FOREGROUND_VALUE);
- assertThat(atom.getErrorSource()).isEqualTo(ErrorSource.DATA_APP);
- assertThat(atom.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- }
-
- public void testWriteRawTestAtom() throws Exception {
- final int atomTag = Atom.TEST_ATOM_REPORTED_FIELD_NUMBER;
- createAndUploadConfig(atomTag, true);
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWriteRawTestAtom");
-
- Thread.sleep(WAIT_TIME_SHORT);
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
- assertThat(data).hasSize(4);
-
- TestAtomReported atom = data.get(0).getAtom().getTestAtomReported();
- List<AttributionNode> attrChain = atom.getAttributionNodeList();
- assertThat(attrChain).hasSize(2);
- assertThat(attrChain.get(0).getUid()).isEqualTo(1234);
- assertThat(attrChain.get(0).getTag()).isEqualTo("tag1");
- assertThat(attrChain.get(1).getUid()).isEqualTo(getUid());
- assertThat(attrChain.get(1).getTag()).isEqualTo("tag2");
-
- assertThat(atom.getIntField()).isEqualTo(42);
- assertThat(atom.getLongField()).isEqualTo(Long.MAX_VALUE);
- assertThat(atom.getFloatField()).isEqualTo(3.14f);
- assertThat(atom.getStringField()).isEqualTo("This is a basic test!");
- assertThat(atom.getBooleanField()).isFalse();
- assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.ON_VALUE);
- assertThat(atom.getBytesField().getExperimentIdList())
- .containsExactly(1L, 2L, 3L).inOrder();
-
-
- atom = data.get(1).getAtom().getTestAtomReported();
- attrChain = atom.getAttributionNodeList();
- assertThat(attrChain).hasSize(2);
- assertThat(attrChain.get(0).getUid()).isEqualTo(9999);
- assertThat(attrChain.get(0).getTag()).isEqualTo("tag9999");
- assertThat(attrChain.get(1).getUid()).isEqualTo(getUid());
- assertThat(attrChain.get(1).getTag()).isEmpty();
-
- assertThat(atom.getIntField()).isEqualTo(100);
- assertThat(atom.getLongField()).isEqualTo(Long.MIN_VALUE);
- assertThat(atom.getFloatField()).isEqualTo(-2.5f);
- assertThat(atom.getStringField()).isEqualTo("Test null uid");
- assertThat(atom.getBooleanField()).isTrue();
- assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.UNKNOWN_VALUE);
- assertThat(atom.getBytesField().getExperimentIdList())
- .containsExactly(1L, 2L, 3L).inOrder();
-
- atom = data.get(2).getAtom().getTestAtomReported();
- attrChain = atom.getAttributionNodeList();
- assertThat(attrChain).hasSize(1);
- assertThat(attrChain.get(0).getUid()).isEqualTo(getUid());
- assertThat(attrChain.get(0).getTag()).isEqualTo("tag1");
-
- assertThat(atom.getIntField()).isEqualTo(-256);
- assertThat(atom.getLongField()).isEqualTo(-1234567890L);
- assertThat(atom.getFloatField()).isEqualTo(42.01f);
- assertThat(atom.getStringField()).isEqualTo("Test non chained");
- assertThat(atom.getBooleanField()).isTrue();
- assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.OFF_VALUE);
- assertThat(atom.getBytesField().getExperimentIdList())
- .containsExactly(1L, 2L, 3L).inOrder();
-
- atom = data.get(3).getAtom().getTestAtomReported();
- attrChain = atom.getAttributionNodeList();
- assertThat(attrChain).hasSize(1);
- assertThat(attrChain.get(0).getUid()).isEqualTo(getUid());
- assertThat(attrChain.get(0).getTag()).isEmpty();
-
- assertThat(atom.getIntField()).isEqualTo(0);
- assertThat(atom.getLongField()).isEqualTo(0L);
- assertThat(atom.getFloatField()).isEqualTo(0f);
- assertThat(atom.getStringField()).isEmpty();
- assertThat(atom.getBooleanField()).isTrue();
- assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.OFF_VALUE);
- assertThat(atom.getBytesField().getExperimentIdList()).isEmpty();
- }
-
- public void testNotificationPackagePreferenceExtraction() throws Exception {
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config,
- Atom.PACKAGE_NOTIFICATION_PREFERENCES_FIELD_NUMBER,
- null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
- runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification");
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<PackageNotificationPreferences> allPreferences = new ArrayList<>();
- for (Atom atom : getGaugeMetricDataList()){
- if(atom.hasPackageNotificationPreferences()) {
- allPreferences.add(atom.getPackageNotificationPreferences());
- }
- }
- assertThat(allPreferences.size()).isGreaterThan(0);
-
- boolean foundTestPackagePreferences = false;
- int uid = getUid();
- for (PackageNotificationPreferences pref : allPreferences) {
- assertThat(pref.getUid()).isGreaterThan(0);
- assertTrue(pref.hasImportance());
- assertTrue(pref.hasVisibility());
- assertTrue(pref.hasUserLockedFields());
- if(pref.getUid() == uid){
- assertThat(pref.getImportance()).isEqualTo(-1000); //UNSPECIFIED_IMPORTANCE
- assertThat(pref.getVisibility()).isEqualTo(-1000); //UNSPECIFIED_VISIBILITY
- foundTestPackagePreferences = true;
- }
- }
- assertTrue(foundTestPackagePreferences);
- }
-
- public void testNotificationChannelPreferencesExtraction() throws Exception {
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config,
- Atom.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES_FIELD_NUMBER,
- null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
- runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification");
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<PackageNotificationChannelPreferences> allChannelPreferences = new ArrayList<>();
- for(Atom atom : getGaugeMetricDataList()) {
- if (atom.hasPackageNotificationChannelPreferences()) {
- allChannelPreferences.add(atom.getPackageNotificationChannelPreferences());
- }
- }
- assertThat(allChannelPreferences.size()).isGreaterThan(0);
-
- boolean foundTestPackagePreferences = false;
- int uid = getUid();
- for (PackageNotificationChannelPreferences pref : allChannelPreferences) {
- assertThat(pref.getUid()).isGreaterThan(0);
- assertTrue(pref.hasChannelId());
- assertTrue(pref.hasChannelName());
- assertTrue(pref.hasDescription());
- assertTrue(pref.hasImportance());
- assertTrue(pref.hasUserLockedFields());
- assertTrue(pref.hasIsDeleted());
- if(uid == pref.getUid() && pref.getChannelId().equals("StatsdCtsChannel")) {
- assertThat(pref.getChannelName()).isEqualTo("Statsd Cts");
- assertThat(pref.getDescription()).isEqualTo("Statsd Cts Channel");
- assertThat(pref.getImportance()).isEqualTo(3); // IMPORTANCE_DEFAULT
- foundTestPackagePreferences = true;
- }
- }
- assertTrue(foundTestPackagePreferences);
- }
-
- public void testNotificationChannelGroupPreferencesExtraction() throws Exception {
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config,
- Atom.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES_FIELD_NUMBER,
- null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
- runActivity("StatsdCtsForegroundActivity", "action", "action.create_channel_group");
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<PackageNotificationChannelGroupPreferences> allGroupPreferences = new ArrayList<>();
- for(Atom atom : getGaugeMetricDataList()) {
- if (atom.hasPackageNotificationChannelGroupPreferences()) {
- allGroupPreferences.add(atom.getPackageNotificationChannelGroupPreferences());
- }
- }
- assertThat(allGroupPreferences.size()).isGreaterThan(0);
-
- boolean foundTestPackagePreferences = false;
- int uid = getUid();
- for(PackageNotificationChannelGroupPreferences pref : allGroupPreferences) {
- assertThat(pref.getUid()).isGreaterThan(0);
- assertTrue(pref.hasGroupId());
- assertTrue(pref.hasGroupName());
- assertTrue(pref.hasDescription());
- assertTrue(pref.hasIsBlocked());
- assertTrue(pref.hasUserLockedFields());
- if(uid == pref.getUid() && pref.getGroupId().equals("StatsdCtsGroup")) {
- assertThat(pref.getGroupName()).isEqualTo("Statsd Cts Group");
- assertThat(pref.getDescription()).isEqualTo("StatsdCtsGroup Description");
- assertThat(pref.getIsBlocked()).isFalse();
- foundTestPackagePreferences = true;
- }
- }
- assertTrue(foundTestPackagePreferences);
- }
-
- public void testNotificationReported() throws Exception {
- StatsdConfig.Builder config = getPulledConfig();
- addAtomEvent(config, Atom.NOTIFICATION_REPORTED_FIELD_NUMBER,
- Arrays.asList(createFvm(NotificationReported.PACKAGE_NAME_FIELD_NUMBER)
- .setEqString(DEVICE_SIDE_TEST_PACKAGE)));
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
- runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification");
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
- assertThat(data).hasSize(1);
- assertThat(data.get(0).getAtom().hasNotificationReported()).isTrue();
- AtomsProto.NotificationReported n = data.get(0).getAtom().getNotificationReported();
- assertThat(n.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(n.getUid()).isEqualTo(getUid());
- assertThat(n.getNotificationIdHash()).isEqualTo(1); // smallHash(0x7f080001)
- assertThat(n.getChannelIdHash()).isEqualTo(SmallHash.hash("StatsdCtsChannel"));
- assertThat(n.getGroupIdHash()).isEqualTo(0);
- assertFalse(n.getIsGroupSummary());
- assertThat(n.getCategory()).isEmpty();
- assertThat(n.getStyle()).isEqualTo(0);
- assertThat(n.getNumPeople()).isEqualTo(0);
- }
-
- public void testSettingsStatsReported() throws Exception {
- // Base64 encoded proto com.android.service.nano.StringListParamProto,
- // which contains five strings 'low_power_trigger_level', 'preferred_network_mode1',
- // 'preferred_network_mode1_int', 'wfc_ims_mode','zen_mode'
- final String encoded =
- "Chdsb3dfcG93ZXJfdHJpZ2dlcl9sZXZlbAoQd2ZjX2ltc19tb2RlID0gMgoXcHJlZmVycmVkX25ldHdvcmtfbW9kZTEKG3ByZWZlcnJlZF9uZXR3b3JrX21vZGUxX2ludAoIemVuX21vZGU";
- final String network_mode1 = "preferred_network_mode1";
-
- int originalNetworkMode;
- try {
- originalNetworkMode = Integer.parseInt(
- getDevice().executeShellCommand("settings get global " + network_mode1));
- } catch (NumberFormatException e) {
- // The default value, zen mode is not enabled
- originalNetworkMode = 0;
- }
-
- // Clear settings_stats device config.
- Thread.sleep(WAIT_TIME_SHORT);
- getDevice().executeShellCommand(
- "device_config reset untrusted_clear settings_stats");
- // Set whitelist through device config.
- Thread.sleep(WAIT_TIME_SHORT);
- getDevice().executeShellCommand(
- "device_config put settings_stats GlobalFeature__integer_whitelist " + encoded);
- Thread.sleep(WAIT_TIME_SHORT);
- // Set network_mode1 value
- getDevice().executeShellCommand("settings put global " + network_mode1 + " 15");
-
- // Get SettingSnapshot as a simple gauge metric.
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.SETTING_SNAPSHOT_FIELD_NUMBER, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Start test app and trigger a pull while it is running.
- try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
- "action.show_notification")) {
- Thread.sleep(WAIT_TIME_SHORT);
- // Trigger a pull and wait for new pull before killing the process.
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_LONG);
- }
-
- // Test the size of atoms. It should contain 5 atoms
- List<Atom> atoms = getGaugeMetricDataList();
- assertThat(atoms.size()).isEqualTo(5);
- SettingSnapshot snapshot = null;
- for (Atom atom : atoms) {
- SettingSnapshot settingSnapshot = atom.getSettingSnapshot();
- if (network_mode1.equals(settingSnapshot.getName())) {
- snapshot = settingSnapshot;
- break;
- }
- }
-
- Thread.sleep(WAIT_TIME_SHORT);
- // Test the data of atom.
- assertNotNull(snapshot);
- // Get setting value and test value type.
- final int newNetworkMode = Integer.parseInt(
- getDevice().executeShellCommand("settings get global " + network_mode1).trim());
- assertThat(snapshot.getType()).isEqualTo(
- SettingSnapshot.SettingsValueType.ASSIGNED_INT_TYPE);
- assertThat(snapshot.getBoolValue()).isEqualTo(false);
- assertThat(snapshot.getIntValue()).isEqualTo(newNetworkMode);
- assertThat(snapshot.getFloatValue()).isEqualTo(0f);
- assertThat(snapshot.getStrValue()).isEqualTo("");
- assertThat(snapshot.getUserId()).isEqualTo(0);
-
- // Restore the setting value.
- getDevice().executeShellCommand(
- "settings put global " + network_mode1 + " " + originalNetworkMode);
- }
-
- public void testIntegrityCheckAtomReportedDuringInstall() throws Exception {
- createAndUploadConfig(AtomsProto.Atom.INTEGRITY_CHECK_RESULT_REPORTED_FIELD_NUMBER);
-
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
- installTestApp();
-
- List<EventMetricData> data = getEventMetricDataList();
-
- assertThat(data.size()).isEqualTo(1);
- assertThat(data.get(0).getAtom().hasIntegrityCheckResultReported()).isTrue();
- IntegrityCheckResultReported result = data.get(0)
- .getAtom().getIntegrityCheckResultReported();
- assertThat(result.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- // we do not assert on certificates since it seem to differ by device.
- assertThat(result.getInstallerPackageName()).isEqualTo("adb");
- assertThat(result.getVersionCode()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE_VERSION);
- assertThat(result.getResponse()).isEqualTo(ALLOWED);
- assertThat(result.getCausedByAppCertRule()).isFalse();
- assertThat(result.getCausedByInstallerRule()).isFalse();
- }
-
- public void testMobileBytesTransfer() throws Throwable {
- final int appUid = getUid();
-
- // Verify MobileBytesTransfer, passing a ThrowingPredicate that verifies contents of
- // corresponding atom type to prevent code duplication. The passed predicate returns
- // true if the atom of appUid is found, false otherwise, and throws an exception if
- // contents are not expected.
- doTestMobileBytesTransferThat(Atom.MOBILE_BYTES_TRANSFER_FIELD_NUMBER, (atom) -> {
- final AtomsProto.MobileBytesTransfer data = ((Atom) atom).getMobileBytesTransfer();
- if (data.getUid() == appUid) {
- assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
- data.getRxPackets(), data.getTxPackets());
- return true; // found
- }
- return false;
- });
- }
-
- public void testMobileBytesTransferByFgBg() throws Throwable {
- final int appUid = getUid();
-
- doTestMobileBytesTransferThat(Atom.MOBILE_BYTES_TRANSFER_BY_FG_BG_FIELD_NUMBER, (atom) -> {
- final AtomsProto.MobileBytesTransferByFgBg data =
- ((Atom) atom).getMobileBytesTransferByFgBg();
- if (data.getUid() == appUid && data.getIsForeground()) {
- assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
- data.getRxPackets(), data.getTxPackets());
- return true; // found
- }
- return false;
- });
- }
-
- public void testDataUsageBytesTransfer() throws Throwable {
- final boolean subtypeCombined = getNetworkStatsCombinedSubTypeEnabled();
-
- doTestMobileBytesTransferThat(Atom.DATA_USAGE_BYTES_TRANSFER_FIELD_NUMBER, (atom) -> {
- final AtomsProto.DataUsageBytesTransfer data =
- ((Atom) atom).getDataUsageBytesTransfer();
- if (data.getState() == 1 /*NetworkStats.SET_FOREGROUND*/) {
- assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
- data.getRxPackets(), data.getTxPackets());
- // TODO: verify the RAT type field with the value gotten from device.
- if (subtypeCombined) {
- assertThat(data.getRatType()).isEqualTo(
- NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
- } else {
- assertThat(data.getRatType()).isGreaterThan(
- NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
- }
-
- // Assert that subscription info is valid.
- assertThat(data.getSimMcc()).matches("^\\d{3}$");
- assertThat(data.getSimMnc()).matches("^\\d{2,3}$");
- assertThat(data.getCarrierId()).isNotEqualTo(
- -1); // TelephonyManager#UNKNOWN_CARRIER_ID
-
- return true; // found
- }
- return false;
- });
- }
-
- // TODO(b/157651730): Determine how to test tag and metered state within atom.
- public void testBytesTransferByTagAndMetered() throws Throwable {
- final int appUid = getUid();
- final int atomId = Atom.BYTES_TRANSFER_BY_TAG_AND_METERED_FIELD_NUMBER;
-
- doTestMobileBytesTransferThat(atomId, (atom) -> {
- final AtomsProto.BytesTransferByTagAndMetered data =
- ((Atom) atom).getBytesTransferByTagAndMetered();
- if (data.getUid() == appUid && data.getTag() == 0 /*app traffic generated on tag 0*/) {
- assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
- data.getRxPackets(), data.getTxPackets());
- return true; // found
- }
- return false;
- });
- }
-
- public void testIsolatedToHostUidMapping() throws Exception {
- createAndUploadConfig(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, /*useAttribution=*/false);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Create an isolated service from which An AppBreadcrumbReported atom is written.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testIsolatedProcessService");
-
- List<EventMetricData> data = getEventMetricDataList();
- assertThat(data).hasSize(1);
- AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
- assertThat(atom.getUid()).isEqualTo(getUid());
- assertThat(atom.getLabel()).isEqualTo(0);
- assertThat(atom.getState()).isEqualTo(AppBreadcrumbReported.State.START);
- }
-
- public void testPushedBlobStoreStats() throws Exception {
- StatsdConfig.Builder conf = createConfigBuilder();
- addAtomEvent(conf, Atom.BLOB_COMMITTED_FIELD_NUMBER, false);
- addAtomEvent(conf, Atom.BLOB_LEASED_FIELD_NUMBER, false);
- addAtomEvent(conf, Atom.BLOB_OPENED_FIELD_NUMBER, false);
- uploadConfig(conf);
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testBlobStore");
-
- List<EventMetricData> data = getEventMetricDataList();
- assertThat(data).hasSize(3);
-
- BlobCommitted blobCommitted = data.get(0).getAtom().getBlobCommitted();
- final long blobId = blobCommitted.getBlobId();
- final long blobSize = blobCommitted.getSize();
- assertThat(blobCommitted.getUid()).isEqualTo(getUid());
- assertThat(blobId).isNotEqualTo(0);
- assertThat(blobSize).isNotEqualTo(0);
- assertThat(blobCommitted.getResult()).isEqualTo(BlobCommitted.Result.SUCCESS);
-
- BlobLeased blobLeased = data.get(1).getAtom().getBlobLeased();
- assertThat(blobLeased.getUid()).isEqualTo(getUid());
- assertThat(blobLeased.getBlobId()).isEqualTo(blobId);
- assertThat(blobLeased.getSize()).isEqualTo(blobSize);
- assertThat(blobLeased.getResult()).isEqualTo(BlobLeased.Result.SUCCESS);
-
- BlobOpened blobOpened = data.get(2).getAtom().getBlobOpened();
- assertThat(blobOpened.getUid()).isEqualTo(getUid());
- assertThat(blobOpened.getBlobId()).isEqualTo(blobId);
- assertThat(blobOpened.getSize()).isEqualTo(blobSize);
- assertThat(blobOpened.getResult()).isEqualTo(BlobOpened.Result.SUCCESS);
- }
-
- // Constants that match the constants for AtomTests#testBlobStore
- private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5;
- private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000;
- private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L;
- private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000;
-
- public void testPulledBlobStoreStats() throws Exception {
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config,
- Atom.BLOB_INFO_FIELD_NUMBER,
- null);
- uploadConfig(config);
-
- final long testStartTimeMs = System.currentTimeMillis();
- Thread.sleep(WAIT_TIME_SHORT);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testBlobStore");
- Thread.sleep(WAIT_TIME_LONG);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Add commit callback time to test end time to account for async execution
- final long testEndTimeMs =
- System.currentTimeMillis() + BLOB_COMMIT_CALLBACK_TIMEOUT_SEC * 1000;
-
- // Find the BlobInfo for the blob created in the test run
- AtomsProto.BlobInfo blobInfo = null;
- for (Atom atom : getGaugeMetricDataList()) {
- if (atom.hasBlobInfo()) {
- final AtomsProto.BlobInfo temp = atom.getBlobInfo();
- if (temp.getCommitters().getCommitter(0).getUid() == getUid()) {
- blobInfo = temp;
- break;
- }
- }
- }
- assertThat(blobInfo).isNotNull();
-
- assertThat(blobInfo.getSize()).isEqualTo(BLOB_FILE_SIZE_BYTES);
-
- // Check that expiry time is reasonable
- assertThat(blobInfo.getExpiryTimestampMillis()).isGreaterThan(
- testStartTimeMs + BLOB_EXPIRY_DURATION_MS);
- assertThat(blobInfo.getExpiryTimestampMillis()).isLessThan(
- testEndTimeMs + BLOB_EXPIRY_DURATION_MS);
-
- // Check that commit time is reasonable
- final long commitTimeMs = blobInfo.getCommitters().getCommitter(
- 0).getCommitTimestampMillis();
- assertThat(commitTimeMs).isGreaterThan(testStartTimeMs);
- assertThat(commitTimeMs).isLessThan(testEndTimeMs);
-
- // Check that WHITELIST and PRIVATE access mode flags are set
- assertThat(blobInfo.getCommitters().getCommitter(0).getAccessMode()).isEqualTo(0b1001);
- assertThat(blobInfo.getCommitters().getCommitter(0).getNumWhitelistedPackage()).isEqualTo(
- 1);
-
- assertThat(blobInfo.getLeasees().getLeaseeCount()).isGreaterThan(0);
- assertThat(blobInfo.getLeasees().getLeasee(0).getUid()).isEqualTo(getUid());
-
- // Check that lease expiry time is reasonable
- final long leaseExpiryMs = blobInfo.getLeasees().getLeasee(
- 0).getLeaseExpiryTimestampMillis();
- assertThat(leaseExpiryMs).isGreaterThan(testStartTimeMs + BLOB_LEASE_EXPIRY_DURATION_MS);
- assertThat(leaseExpiryMs).isLessThan(testEndTimeMs + BLOB_LEASE_EXPIRY_DURATION_MS);
- }
-
- private void assertDataUsageAtomDataExpected(long rxb, long txb, long rxp, long txp) {
- assertThat(rxb).isGreaterThan(0L);
- assertThat(txb).isGreaterThan(0L);
- assertThat(rxp).isGreaterThan(0L);
- assertThat(txp).isGreaterThan(0L);
- }
-
- private void doTestMobileBytesTransferThat(int atomTag, ThrowingPredicate p)
- throws Throwable {
- if (!hasFeature(FEATURE_TELEPHONY, true)) return;
-
- // Get MobileBytesTransfer as a simple gauge metric.
- final StatsdConfig.Builder config = getPulledConfig();
- addGaugeAtomWithDimensions(config, atomTag, null);
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Generate some traffic on mobile network.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testGenerateMobileTraffic");
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Force polling NetworkStatsService to get most updated network stats from lower layer.
- runActivity("StatsdCtsForegroundActivity", "action", "action.poll_network_stats");
- Thread.sleep(WAIT_TIME_SHORT);
-
- // Pull a report
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final List<Atom> atoms = getGaugeMetricDataList(/*checkTimestampTruncated=*/true);
- assertThat(atoms.size()).isAtLeast(1);
-
- boolean foundAppStats = false;
- for (final Atom atom : atoms) {
- if (p.accept(atom)) {
- foundAppStats = true;
- }
- }
- assertWithMessage("uid " + getUid() + " is not found in " + atoms.size() + " atoms")
- .that(foundAppStats).isTrue();
- }
-
- @FunctionalInterface
- private interface ThrowingPredicate<S, T extends Throwable> {
- boolean accept(S s) throws T;
- }
-
- public void testPackageInstallerV2MetricsReported() throws Throwable {
- if (!hasFeature(FEATURE_INCREMENTAL_DELIVERY, true)) return;
- final AtomsProto.PackageInstallerV2Reported report = installPackageUsingV2AndGetReport(
- new String[]{TEST_INSTALL_APK});
- assertTrue(report.getIsIncremental());
- // tests are ran using SHELL_UID and installation will be treated as adb install
- assertEquals("", report.getPackageName());
- assertEquals(1, report.getReturnCode());
- assertTrue(report.getDurationMillis() > 0);
- assertEquals(getTestFileSize(TEST_INSTALL_APK), report.getApksSizeBytes());
-
- getDevice().uninstallPackage(TEST_INSTALL_PACKAGE);
- }
-
- public void testPackageInstallerV2MetricsReportedForSplits() throws Throwable {
- if (!hasFeature(FEATURE_INCREMENTAL_DELIVERY, true)) return;
-
- final AtomsProto.PackageInstallerV2Reported report = installPackageUsingV2AndGetReport(
- new String[]{TEST_INSTALL_APK_BASE, TEST_INSTALL_APK_SPLIT});
- assertTrue(report.getIsIncremental());
- // tests are ran using SHELL_UID and installation will be treated as adb install
- assertEquals("", report.getPackageName());
- assertEquals(1, report.getReturnCode());
- assertTrue(report.getDurationMillis() > 0);
- assertEquals(
- getTestFileSize(TEST_INSTALL_APK_BASE) + getTestFileSize(TEST_INSTALL_APK_SPLIT),
- report.getApksSizeBytes());
-
- getDevice().uninstallPackage(TEST_INSTALL_PACKAGE);
- }
-
- public void testAppForegroundBackground() throws Exception {
- Set<Integer> onStates = new HashSet<>(Arrays.asList(
- AppUsageEventOccurred.EventType.MOVE_TO_FOREGROUND_VALUE));
- Set<Integer> offStates = new HashSet<>(Arrays.asList(
- AppUsageEventOccurred.EventType.MOVE_TO_BACKGROUND_VALUE));
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(Atom.APP_USAGE_EVENT_OCCURRED_FIELD_NUMBER, false);
- Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
- getDevice().executeShellCommand(String.format(
- "am start -n '%s' -e %s %s",
- "com.android.server.cts.device.statsd/.StatsdCtsForegroundActivity",
- "action", ACTION_SHOW_APPLICATION_OVERLAY));
- final int waitTime = EXTRA_WAIT_TIME_MS + 5_000; // Overlay may need to sit there a while.
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- Function<Atom, Integer> appUsageStateFunction =
- atom -> atom.getAppUsageEventOccurred().getEventType().getNumber();
- popUntilFind(data, onStates, appUsageStateFunction); // clear out initial appusage states.s
- assertStatesOccurred(stateSet, data, 0, appUsageStateFunction);
- }
-
- public void testAppForceStopUsageEvent() throws Exception {
- Set<Integer> onStates = new HashSet<>(Arrays.asList(
- AppUsageEventOccurred.EventType.MOVE_TO_FOREGROUND_VALUE));
- Set<Integer> offStates = new HashSet<>(Arrays.asList(
- AppUsageEventOccurred.EventType.MOVE_TO_BACKGROUND_VALUE));
-
- List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
- createAndUploadConfig(Atom.APP_USAGE_EVENT_OCCURRED_FIELD_NUMBER, false);
- Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
- getDevice().executeShellCommand(String.format(
- "am start -n '%s' -e %s %s",
- "com.android.server.cts.device.statsd/.StatsdCtsForegroundActivity",
- "action", ACTION_LONG_SLEEP_WHILE_TOP));
- final int waitTime = EXTRA_WAIT_TIME_MS + 5_000;
- Thread.sleep(waitTime);
-
- getDevice().executeShellCommand(String.format(
- "am force-stop %s",
- "com.android.server.cts.device.statsd/.StatsdCtsForegroundActivity"));
- Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
- List<EventMetricData> data = getEventMetricDataList();
- Function<Atom, Integer> appUsageStateFunction =
- atom -> atom.getAppUsageEventOccurred().getEventType().getNumber();
- popUntilFind(data, onStates, appUsageStateFunction); // clear out initial appusage states.
- assertStatesOccurred(stateSet, data, 0, appUsageStateFunction);
- }
-
- private AtomsProto.PackageInstallerV2Reported installPackageUsingV2AndGetReport(
- String[] apkNames) throws Exception {
- createAndUploadConfig(Atom.PACKAGE_INSTALLER_V2_REPORTED_FIELD_NUMBER);
- Thread.sleep(WAIT_TIME_SHORT);
- installPackageUsingIncremental(apkNames, TEST_REMOTE_DIR);
- assertTrue(getDevice().isPackageInstalled(TEST_INSTALL_PACKAGE));
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<AtomsProto.PackageInstallerV2Reported> reports = new ArrayList<>();
- for(EventMetricData data : getEventMetricDataList()) {
- if (data.getAtom().hasPackageInstallerV2Reported()) {
- reports.add(data.getAtom().getPackageInstallerV2Reported());
- }
- }
- assertEquals(1, reports.size());
- return reports.get(0);
- }
-
- private void installPackageUsingIncremental(String[] apkNames, String remoteDirPath)
- throws Exception {
- getDevice().executeShellCommand("mkdir " + remoteDirPath);
- String[] remoteApkPaths = new String[apkNames.length];
- for (int i = 0; i < remoteApkPaths.length; i++) {
- remoteApkPaths[i] = pushApkToRemote(apkNames[i], remoteDirPath);
- }
- getDevice().executeShellCommand(
- "pm install-incremental -t -g " + String.join(" ", remoteApkPaths));
- }
-
- private String pushApkToRemote(String apkName, String remoteDirPath)
- throws Exception {
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final File apk = buildHelper.getTestFile(apkName);
- final String remoteApkPath = remoteDirPath + "/" + apk.getName();
- assertTrue(getDevice().pushFile(apk, remoteApkPath));
- assertNotNull(apk);
- return remoteApkPath;
- }
-
- private long getTestFileSize(String fileName) throws Exception {
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final File file = buildHelper.getTestFile(fileName);
- return file.length();
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
deleted file mode 100644
index 0ccb13c..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
+++ /dev/null
@@ -1,45 +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 android.cts.statsd.metadata;
-
-import android.cts.statsd.atom.AtomTestCase;
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.tradefed.log.LogUtil;
-
-public class MetadataTestCase extends AtomTestCase {
- public static final String DUMP_METADATA_CMD = "cmd stats print-stats";
-
- protected StatsdStatsReport getStatsdStatsReport() throws Exception {
- try {
- StatsdStatsReport report = getDump(StatsdStatsReport.parser(),
- String.join(" ", DUMP_METADATA_CMD, "--proto"));
- return report;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- LogUtil.CLog.e("Failed to fetch and parse the statsdstats output report.");
- throw (e);
- }
- }
-
- protected final StatsdConfig.Builder getBaseConfig() throws Exception {
- StatsdConfig.Builder builder = createConfigBuilder();
- addAtomEvent(builder, Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
- return builder;
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
deleted file mode 100644
index 7022732..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
+++ /dev/null
@@ -1,110 +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 android.cts.statsd.metadata;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.AtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.Subscription;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-import com.android.os.AtomsProto.AnomalyDetected;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.os.StatsLog.StatsdStatsReport.ConfigStats;
-import com.android.tradefed.log.LogUtil;
-
-
-import java.util.List;
-
-/**
- * Statsd Metadata tests.
- */
-public class MetadataTests extends MetadataTestCase {
-
- private static final String TAG = "Statsd.MetadataTests";
-
- // Tests that the statsd config is reset after the specified ttl.
- public void testConfigTtl() throws Exception {
- final int TTL_TIME_SEC = 8;
- StatsdConfig.Builder config = getBaseConfig();
- config.setTtlInSeconds(TTL_TIME_SEC); // should reset in this many seconds.
-
- uploadConfig(config);
- long startTime = System.currentTimeMillis();
- Thread.sleep(WAIT_TIME_SHORT);
- doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, within < TTL_TIME_SEC secs.
- Thread.sleep(WAIT_TIME_SHORT);
- StatsdStatsReport report = getStatsdStatsReport(); // Has only been 1 second
- LogUtil.CLog.d("got following statsdstats report: " + report.toString());
- boolean foundActiveConfig = false;
- int creationTime = 0;
- for (ConfigStats stats: report.getConfigStatsList()) {
- if (stats.getId() == CONFIG_ID && stats.getUid() == getHostUid()) {
- if(!stats.hasDeletionTimeSec()) {
- assertWithMessage("Found multiple active CTS configs!")
- .that(foundActiveConfig).isFalse();
- foundActiveConfig = true;
- creationTime = stats.getCreationTimeSec();
- }
- }
- }
- assertWithMessage("Did not find an active CTS config").that(foundActiveConfig).isTrue();
-
- while(System.currentTimeMillis() - startTime < 8_000) {
- Thread.sleep(10);
- }
- doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, after TTL_TIME_SEC secs.
- Thread.sleep(WAIT_TIME_SHORT);
- report = getStatsdStatsReport();
- LogUtil.CLog.d("got following statsdstats report: " + report.toString());
- foundActiveConfig = false;
- int expectedTime = creationTime + TTL_TIME_SEC;
- for (ConfigStats stats: report.getConfigStatsList()) {
- if (stats.getId() == CONFIG_ID && stats.getUid() == getHostUid()) {
- // Original config should be TTL'd
- if (stats.getCreationTimeSec() == creationTime) {
- assertWithMessage("Config should have TTL'd but is still active")
- .that(stats.hasDeletionTimeSec()).isTrue();
- assertWithMessage(
- "Config deletion time should be about %s after creation", TTL_TIME_SEC
- ).that(Math.abs(stats.getDeletionTimeSec() - expectedTime)).isAtMost(2);
- }
- // There should still be one active config, that is marked as reset.
- if(!stats.hasDeletionTimeSec()) {
- assertWithMessage("Found multiple active CTS configs!")
- .that(foundActiveConfig).isFalse();
- foundActiveConfig = true;
- creationTime = stats.getCreationTimeSec();
- assertWithMessage("Active config after TTL should be marked as reset")
- .that(stats.hasResetTimeSec()).isTrue();
- assertWithMessage("Reset and creation time should be equal for TTl'd configs")
- .that(stats.getResetTimeSec()).isEqualTo(stats.getCreationTimeSec());
- assertWithMessage(
- "Reset config should be created when the original config TTL'd"
- ).that(Math.abs(stats.getCreationTimeSec() - expectedTime)).isAtMost(2);
- }
- }
- }
- assertWithMessage("Did not find an active CTS config after the TTL")
- .that(foundActiveConfig).isTrue();
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
deleted file mode 100644
index a63e01e..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
+++ /dev/null
@@ -1,433 +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 android.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.AttributionNode;
-import com.android.os.AtomsProto.BleScanStateChanged;
-import com.android.os.AtomsProto.WakelockStateChanged;
-import com.android.os.StatsLog;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.CountBucketInfo;
-import com.android.os.StatsLog.CountMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-public class CountMetricsTests extends DeviceAtomTestCase {
-
- public void testSimpleEventCountMetric() throws Exception {
- int matcherId = 1;
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
- builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
- .setId(MetricsUtils.COUNT_METRIC_ID)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setWhat(matcherId))
- .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId));
- uploadConfig(builder);
-
- doAppBreadcrumbReportedStart(0);
- doAppBreadcrumbReportedStop(0);
- Thread.sleep(2000); // Wait for the metrics to propagate to statsd.
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
- assertThat(metricReport.hasCountMetrics()).isTrue();
-
- StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics();
-
- assertThat(countData.getDataCount()).isGreaterThan(0);
- assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(2);
- }
- public void testEventCountWithCondition() throws Exception {
- int startMatcherId = 1;
- int endMatcherId = 2;
- int whatMatcherId = 3;
- int conditionId = 4;
-
- StatsdConfigProto.AtomMatcher whatMatcher =
- MetricsUtils.unspecifiedAtomMatcher(whatMatcherId);
-
- StatsdConfigProto.AtomMatcher predicateStartMatcher =
- MetricsUtils.startAtomMatcher(startMatcherId);
-
- StatsdConfigProto.AtomMatcher predicateEndMatcher =
- MetricsUtils.stopAtomMatcher(endMatcherId);
-
- StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder()
- .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
- .setStart(startMatcherId)
- .setStop(endMatcherId)
- .setCountNesting(false))
- .setId(conditionId)
- .build();
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
- .addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
- .setId(MetricsUtils.COUNT_METRIC_ID)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setWhat(whatMatcherId)
- .setCondition(conditionId))
- .addAtomMatcher(whatMatcher)
- .addAtomMatcher(predicateStartMatcher)
- .addAtomMatcher(predicateEndMatcher)
- .addPredicate(p);
-
- uploadConfig(builder);
-
- doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
- Thread.sleep(10);
- doAppBreadcrumbReportedStart(0);
- Thread.sleep(10);
- doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
- Thread.sleep(10);
- doAppBreadcrumbReportedStop(0);
- Thread.sleep(10);
- doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
- Thread.sleep(2000); // Wait for the metrics to propagate to statsd.
-
- StatsLogReport metricReport = getStatsLogReport();
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
- assertThat(metricReport.hasCountMetrics()).isTrue();
-
- StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics();
-
- assertThat(countData.getDataCount()).isGreaterThan(0);
- assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(1);
- }
-
- public void testEventCountWithConditionAndActivation() throws Exception {
- int startMatcherId = 1;
- int startMatcherLabel = 1;
- int endMatcherId = 2;
- int endMatcherLabel = 2;
- int whatMatcherId = 3;
- int whatMatcherLabel = 3;
- int conditionId = 4;
- int activationMatcherId = 5;
- int activationMatcherLabel = 5;
- int ttlSec = 5;
-
- StatsdConfigProto.AtomMatcher whatMatcher =
- MetricsUtils.appBreadcrumbMatcherWithLabel(whatMatcherId, whatMatcherLabel);
-
- StatsdConfigProto.AtomMatcher predicateStartMatcher =
- MetricsUtils.startAtomMatcherWithLabel(startMatcherId, startMatcherLabel);
-
- StatsdConfigProto.AtomMatcher predicateEndMatcher =
- MetricsUtils.stopAtomMatcherWithLabel(endMatcherId, endMatcherLabel);
-
- StatsdConfigProto.AtomMatcher activationMatcher =
- MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId,
- activationMatcherLabel);
-
- StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder()
- .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
- .setStart(startMatcherId)
- .setStop(endMatcherId)
- .setCountNesting(false))
- .setId(conditionId)
- .build();
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
- .addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
- .setId(MetricsUtils.COUNT_METRIC_ID)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setWhat(whatMatcherId)
- .setCondition(conditionId)
- )
- .addAtomMatcher(whatMatcher)
- .addAtomMatcher(predicateStartMatcher)
- .addAtomMatcher(predicateEndMatcher)
- .addAtomMatcher(activationMatcher)
- .addPredicate(p)
- .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.COUNT_METRIC_ID)
- .setActivationType(StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY)
- .addEventActivation(StatsdConfigProto.EventActivation.newBuilder()
- .setAtomMatcherId(activationMatcherId)
- .setTtlSeconds(ttlSec)));
-
- uploadConfig(builder);
-
- // Activate the metric.
- doAppBreadcrumbReported(activationMatcherLabel);
- Thread.sleep(10);
-
- // Set the condition to true.
- doAppBreadcrumbReportedStart(startMatcherLabel);
- Thread.sleep(10);
-
- // Log an event that should be counted. Bucket 1 Count 1.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Log an event that should be counted. Bucket 1 Count 2.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Set the condition to false.
- doAppBreadcrumbReportedStop(endMatcherLabel);
- Thread.sleep(10);
-
- // Log an event that should not be counted because condition is false.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Log an event that should not be counted.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Condition to true again.
- doAppBreadcrumbReportedStart(startMatcherLabel);
- Thread.sleep(10);
-
- // Event should not be counted, metric is still not active.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Activate the metric.
- doAppBreadcrumbReported(activationMatcherLabel);
- Thread.sleep(10);
-
- // Log an event that should be counted.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Log an event that should not be counted.
- doAppBreadcrumbReported(whatMatcherLabel);
- Thread.sleep(10);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.hasCountMetrics()).isTrue();
- assertThat(metricReport.getIsActive()).isFalse();
-
- StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics();
- assertThat(countData.getDataCount()).isEqualTo(1);
- assertThat(countData.getData(0).getBucketInfoCount()).isEqualTo(2);
- assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(2);
- assertThat(countData.getData(0).getBucketInfo(1).getCount()).isEqualTo(1);
- }
-
- public void testPartialBucketCountMetric() throws Exception {
- int matcherId = 1;
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
- builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
- .setId(MetricsUtils.COUNT_METRIC_ID)
- .setBucket(StatsdConfigProto.TimeUnit.ONE_DAY) // Should ensure partial bucket.
- .setWhat(matcherId))
- .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId));
- uploadConfig(builder);
-
- doAppBreadcrumbReportedStart(0);
-
- builder.getCountMetricBuilder(0).setBucket(StatsdConfigProto.TimeUnit.CTS);
- uploadConfig(builder); // The count metric had a partial bucket.
- doAppBreadcrumbReportedStart(0);
- Thread.sleep(10);
- doAppBreadcrumbReportedStart(0);
- Thread.sleep(WAIT_TIME_LONG); // Finish the current bucket.
-
- ConfigMetricsReportList reports = getReportList();
- LogUtil.CLog.d("Got following report list: " + reports.toString());
-
- assertThat(reports.getReportsCount()).isEqualTo(2);
- boolean inOrder = reports.getReports(0).getCurrentReportWallClockNanos() <
- reports.getReports(1).getCurrentReportWallClockNanos();
-
- // Only 1 metric, so there should only be 1 StatsLogReport.
- for (ConfigMetricsReport report : reports.getReportsList()) {
- assertThat(report.getMetricsCount()).isEqualTo(1);
- assertThat(report.getMetrics(0).getCountMetrics().getDataCount()).isEqualTo(1);
- }
- CountMetricData data1 =
- reports.getReports(inOrder? 0 : 1).getMetrics(0).getCountMetrics().getData(0);
- CountMetricData data2 =
- reports.getReports(inOrder? 1 : 0).getMetrics(0).getCountMetrics().getData(0);
- // Data1 should have only 1 bucket, and it should be a partial bucket.
- // The count should be 1.
- assertThat(data1.getBucketInfoCount()).isEqualTo(1);
- CountBucketInfo bucketInfo = data1.getBucketInfo(0);
- assertThat(bucketInfo.getCount()).isEqualTo(1);
- assertWithMessage("First report's bucket should be less than 1 day")
- .that(bucketInfo.getEndBucketElapsedNanos())
- .isLessThan(bucketInfo.getStartBucketElapsedNanos() +
- 1_000_000_000L * 60L * 60L * 24L);
-
- //Second report should have a count of 2.
- assertThat(data2.getBucketInfoCount()).isAtMost(2);
- int totalCount = 0;
- for (CountBucketInfo bucket : data2.getBucketInfoList()) {
- totalCount += bucket.getCount();
- }
- assertThat(totalCount).isEqualTo(2);
- }
-
- public void testSlicedStateCountMetricNoReset() throws Exception {
- int whatMatcherId = 3;
- int stateId = 4;
- int onStateGroupId = 5;
- int offStateGroupId = 6;
-
- // Atom 9998 {
- // repeated AttributionNode attribution_node = 1;
- // optional WakeLockLevelEnum type = 2;
- // optional string tag = 3;
- // }
- int whatAtomId = 9_998;
-
- StatsdConfigProto.AtomMatcher whatMatcher =
- MetricsUtils.getAtomMatcher(whatAtomId)
- .setId(whatMatcherId)
- .build();
-
- StatsdConfigProto.State state = StatsdConfigProto.State.newBuilder()
- .setId(stateId)
- .setAtomId(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER)
- .setMap(StatsdConfigProto.StateMap.newBuilder()
- .addGroup(StatsdConfigProto.StateMap.StateGroup.newBuilder()
- .setGroupId(onStateGroupId)
- .addValue(WakelockStateChanged.State.ACQUIRE_VALUE)
- .addValue(WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE)
- )
- .addGroup(StatsdConfigProto.StateMap.StateGroup.newBuilder()
- .setGroupId(offStateGroupId)
- .addValue(WakelockStateChanged.State.RELEASE_VALUE)
- .addValue(WakelockStateChanged.State.CHANGE_RELEASE_VALUE)
- )
- )
- .build();
-
- StatsdConfigProto.MetricStateLink stateLink = StatsdConfigProto.MetricStateLink.newBuilder()
- .setStateAtomId(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER)
- .setFieldsInWhat(FieldMatcher.newBuilder()
- .setField(whatAtomId)
- .addChild(FieldMatcher.newBuilder()
- .setField(1)
- .setPosition(Position.FIRST)
- .addChild(FieldMatcher.newBuilder()
- .setField(AttributionNode.UID_FIELD_NUMBER)
- )
- )
- .addChild(FieldMatcher.newBuilder()
- .setField(2)
- )
- .addChild(FieldMatcher.newBuilder()
- .setField(3)
- )
- )
- .setFieldsInState(FieldMatcher.newBuilder()
- .setField(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder()
- .setField(WakelockStateChanged.ATTRIBUTION_NODE_FIELD_NUMBER)
- .setPosition(Position.FIRST)
- .addChild(FieldMatcher.newBuilder()
- .setField(AttributionNode.UID_FIELD_NUMBER)
- )
- )
- .addChild(FieldMatcher.newBuilder()
- .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
- )
- .addChild(FieldMatcher.newBuilder()
- .setField(WakelockStateChanged.TAG_FIELD_NUMBER)
- )
- )
- .build();
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
- .addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
- .setId(MetricsUtils.COUNT_METRIC_ID)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setWhat(whatMatcherId)
- .addSliceByState(stateId)
- .addStateLink(stateLink)
- )
- .addAtomMatcher(whatMatcher)
- .addState(state);
- uploadConfig(builder);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSliceByWakelockState");
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
- assertThat(metricReport.hasCountMetrics()).isTrue();
-
- StatsLogReport.CountMetricDataWrapper dataWrapper = metricReport.getCountMetrics();
- assertThat(dataWrapper.getDataCount()).isEqualTo(2);
-
-
- List<CountMetricData> sortedDataList = IntStream.range(0, dataWrapper.getDataCount())
- .mapToObj(i -> {
- CountMetricData data = dataWrapper.getData(i);
- assertWithMessage("Unexpected SliceByState count for data[%s]", "" + i)
- .that(data.getSliceByStateCount()).isEqualTo(1);
- return data;
- })
- .sorted((data1, data2) ->
- Long.compare(data1.getSliceByState(0).getGroupId(),
- data2.getSliceByState(0).getGroupId())
- )
- .collect(Collectors.toList());
-
- CountMetricData data = sortedDataList.get(0);
- assertThat(data.getSliceByState(0).getAtomId())
- .isEqualTo(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER);
- assertThat(data.getSliceByState(0).getGroupId())
- .isEqualTo(onStateGroupId);
- long totalCount = data.getBucketInfoList().stream()
- .mapToLong(CountBucketInfo::getCount)
- .sum();
- assertThat(totalCount).isEqualTo(6);
-
- data = sortedDataList.get(1);
- assertThat(data.getSliceByState(0).getAtomId())
- .isEqualTo(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER);
- assertThat(data.getSliceByState(0).getGroupId())
- .isEqualTo(offStateGroupId);
- totalCount = data.getBucketInfoList().stream()
- .mapToLong(CountBucketInfo::getCount)
- .sum();
- assertThat(totalCount).isEqualTo(3);
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/DurationMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/DurationMetricsTests.java
deleted file mode 100644
index 65cef95..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/DurationMetricsTests.java
+++ /dev/null
@@ -1,569 +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 android.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-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.DurationBucketInfo;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
-
-import com.google.common.collect.Range;
-
-import java.util.List;
-
-public class DurationMetricsTests extends DeviceAtomTestCase {
-
- private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
- private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1;
- private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2;
- private static final int APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID = 3;
-
- public void testDurationMetric() throws Exception {
- final int label = 1;
- // Add AtomMatchers.
- AtomMatcher startAtomMatcher =
- MetricsUtils.startAtomMatcherWithLabel(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, label);
- AtomMatcher stopAtomMatcher =
- MetricsUtils.stopAtomMatcherWithLabel(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, label);
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(startAtomMatcher);
- builder.addAtomMatcher(stopAtomMatcher);
-
- // Add Predicates.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
- builder.addPredicate(predicate);
-
- // Add DurationMetric.
- builder.addDurationMetric(
- StatsdConfigProto.DurationMetric.newBuilder()
- .setId(MetricsUtils.DURATION_METRIC_ID)
- .setWhat(predicate.getId())
- .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
- .setBucket(StatsdConfigProto.TimeUnit.CTS));
-
- // Upload config.
- uploadConfig(builder);
-
- // Create AppBreadcrumbReported Start/Stop events.
- doAppBreadcrumbReportedStart(label);
- Thread.sleep(2000);
- doAppBreadcrumbReportedStop(label);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.hasDurationMetrics()).isTrue();
- StatsLogReport.DurationMetricDataWrapper durationData
- = metricReport.getDurationMetrics();
- assertThat(durationData.getDataCount()).isEqualTo(1);
- assertThat(durationData.getData(0).getBucketInfo(0).getDurationNanos())
- .isIn(Range.open(0L, (long)1e9));
- }
-
- public void testDurationMetricWithCondition() throws Exception {
- final int durationLabel = 1;
- final int conditionLabel = 2;
-
- // Add AtomMatchers.
- AtomMatcher startAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, durationLabel);
- AtomMatcher stopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, durationLabel);
- AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_B_MATCH_START_ID, conditionLabel);
- AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID, conditionLabel);
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
- .addAtomMatcher(startAtomMatcher)
- .addAtomMatcher(stopAtomMatcher)
- .addAtomMatcher(conditionStartAtomMatcher)
- .addAtomMatcher(conditionStopAtomMatcher);
-
- // Add Predicates.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
-
- SimplePredicate conditionSimplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID)
- .build();
- Predicate conditionPredicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("ConditionPredicate"))
- .setSimplePredicate(conditionSimplePredicate)
- .build();
-
- builder
- .addPredicate(predicate)
- .addPredicate(conditionPredicate);
-
- // Add DurationMetric.
- builder
- .addDurationMetric(StatsdConfigProto.DurationMetric.newBuilder()
- .setId(MetricsUtils.DURATION_METRIC_ID)
- .setWhat(predicate.getId())
- .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setCondition(conditionPredicate.getId())
- );
-
- // Upload config.
- uploadConfig(builder);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Set the condition to true.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // Start counted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop counted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Set the condition to false.
- doAppBreadcrumbReportedStop(conditionLabel);
- Thread.sleep(10);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
- StatsLogReport metricReport = getStatsLogReport();
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.hasDurationMetrics()).isTrue();
- StatsLogReport.DurationMetricDataWrapper durationData
- = metricReport.getDurationMetrics();
- assertThat(durationData.getDataCount()).isEqualTo(1);
- long totalDuration = durationData.getData(0).getBucketInfoList().stream()
- .mapToLong(bucketInfo -> bucketInfo.getDurationNanos())
- .peek(durationNs -> assertThat(durationNs).isIn(Range.openClosed(0L, (long)1e9)))
- .sum();
- assertThat(totalDuration).isIn(Range.open((long)2e9, (long)3e9));
- }
-
- public void testDurationMetricWithActivation() throws Exception {
- final int activationMatcherId = 5;
- final int activationMatcherLabel = 5;
- final int ttlSec = 5;
- final int durationLabel = 1;
-
- // Add AtomMatchers.
- AtomMatcher startAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, durationLabel);
- AtomMatcher stopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, durationLabel);
- StatsdConfigProto.AtomMatcher activationMatcher =
- MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId,
- activationMatcherLabel);
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
- .addAtomMatcher(startAtomMatcher)
- .addAtomMatcher(stopAtomMatcher)
- .addAtomMatcher(activationMatcher);
-
- // Add Predicates.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
- builder.addPredicate(predicate);
-
- // Add DurationMetric.
- builder
- .addDurationMetric(StatsdConfigProto.DurationMetric.newBuilder()
- .setId(MetricsUtils.DURATION_METRIC_ID)
- .setWhat(predicate.getId())
- .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- )
- .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.DURATION_METRIC_ID)
- .addEventActivation(StatsdConfigProto.EventActivation.newBuilder()
- .setAtomMatcherId(activationMatcherId)
- .setActivationType(
- StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY)
- .setTtlSeconds(ttlSec)));
-
- // Upload config.
- uploadConfig(builder);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Activate the metric.
- doAppBreadcrumbReported(activationMatcherLabel);
- Thread.sleep(10);
-
- // Start counted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop counted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
- StatsLogReport metricReport = getStatsLogReport();
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.hasDurationMetrics()).isTrue();
- StatsLogReport.DurationMetricDataWrapper durationData
- = metricReport.getDurationMetrics();
- assertThat(durationData.getDataCount()).isEqualTo(1);
- long totalDuration = durationData.getData(0).getBucketInfoList().stream()
- .mapToLong(bucketInfo -> bucketInfo.getDurationNanos())
- .peek(durationNs -> assertThat(durationNs).isIn(Range.openClosed(0L, (long)1e9)))
- .sum();
- assertThat(totalDuration).isIn(Range.open((long)2e9, (long)3e9));
- }
-
- public void testDurationMetricWithConditionAndActivation() throws Exception {
- final int durationLabel = 1;
- final int conditionLabel = 2;
- final int activationMatcherId = 5;
- final int activationMatcherLabel = 5;
- final int ttlSec = 5;
-
- // Add AtomMatchers.
- AtomMatcher startAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, durationLabel);
- AtomMatcher stopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, durationLabel);
- AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_B_MATCH_START_ID, conditionLabel);
- AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID, conditionLabel);
- StatsdConfigProto.AtomMatcher activationMatcher =
- MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId,
- activationMatcherLabel);
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
- .addAtomMatcher(startAtomMatcher)
- .addAtomMatcher(stopAtomMatcher)
- .addAtomMatcher(conditionStartAtomMatcher)
- .addAtomMatcher(conditionStopAtomMatcher)
- .addAtomMatcher(activationMatcher);
-
- // Add Predicates.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
- builder.addPredicate(predicate);
-
- SimplePredicate conditionSimplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID)
- .build();
- Predicate conditionPredicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("ConditionPredicate"))
- .setSimplePredicate(conditionSimplePredicate)
- .build();
- builder.addPredicate(conditionPredicate);
-
- // Add DurationMetric.
- builder
- .addDurationMetric(StatsdConfigProto.DurationMetric.newBuilder()
- .setId(MetricsUtils.DURATION_METRIC_ID)
- .setWhat(predicate.getId())
- .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setCondition(conditionPredicate.getId())
- )
- .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.DURATION_METRIC_ID)
- .addEventActivation(StatsdConfigProto.EventActivation.newBuilder()
- .setAtomMatcherId(activationMatcherId)
- .setActivationType(
- StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY)
- .setTtlSeconds(ttlSec)));
-
- // Upload config.
- uploadConfig(builder);
-
- // Activate the metric.
- doAppBreadcrumbReported(activationMatcherLabel);
- Thread.sleep(10);
-
- // Set the condition to true.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // Start counted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop counted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Set the condition to false.
- doAppBreadcrumbReportedStop(conditionLabel);
- Thread.sleep(10);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
- //doAppBreadcrumbReported(99); // TODO: maybe remove?
- //Thread.sleep(10);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Set condition to true again.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Activate the metric.
- doAppBreadcrumbReported(activationMatcherLabel);
- Thread.sleep(10);
-
- // Start counted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop counted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Start uncounted duration.
- doAppBreadcrumbReportedStart(durationLabel);
- Thread.sleep(10);
-
- Thread.sleep(2_000);
-
- // Stop uncounted duration.
- doAppBreadcrumbReportedStop(durationLabel);
- Thread.sleep(10);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
- assertThat(metricReport.hasDurationMetrics()).isTrue();
- StatsLogReport.DurationMetricDataWrapper durationData
- = metricReport.getDurationMetrics();
- assertThat(durationData.getDataCount()).isEqualTo(1);
- long totalDuration = durationData.getData(0).getBucketInfoList().stream()
- .mapToLong(bucketInfo -> bucketInfo.getDurationNanos())
- .peek(durationNs -> assertThat(durationNs).isIn(Range.openClosed(0L, (long)1e9)))
- .sum();
- assertThat(totalDuration).isIn(Range.open((long)4e9, (long)5e9));
- }
-
- public void testDurationMetricWithDimension() throws Exception {
- // Add AtomMatchers.
- AtomMatcher startAtomMatcherA =
- MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID);
- AtomMatcher stopAtomMatcherA =
- MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID);
- AtomMatcher startAtomMatcherB =
- MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID);
- AtomMatcher stopAtomMatcherB =
- MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID);
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(startAtomMatcherA);
- builder.addAtomMatcher(stopAtomMatcherA);
- builder.addAtomMatcher(startAtomMatcherB);
- builder.addAtomMatcher(stopAtomMatcherB);
-
- // Add Predicates.
- SimplePredicate simplePredicateA = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicateA = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate_A"))
- .setSimplePredicate(simplePredicateA)
- .build();
- builder.addPredicate(predicateA);
-
- FieldMatcher.Builder dimensionsBuilder = FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
- dimensionsBuilder
- .addChild(FieldMatcher.newBuilder().setField(
- AppBreadcrumbReported.LABEL_FIELD_NUMBER));
- Predicate predicateB =
- Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate_B"))
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID)
- .setDimensions(dimensionsBuilder.build())
- .build())
- .build();
- builder.addPredicate(predicateB);
-
- // Add DurationMetric.
- builder.addDurationMetric(
- StatsdConfigProto.DurationMetric.newBuilder()
- .setId(MetricsUtils.DURATION_METRIC_ID)
- .setWhat(predicateB.getId())
- .setCondition(predicateA.getId())
- .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .setDimensionsInWhat(
- FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder().setField(
- AppBreadcrumbReported.LABEL_FIELD_NUMBER))));
-
- // Upload config.
- uploadConfig(builder);
-
- // Trigger events.
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(2000);
- doAppBreadcrumbReportedStart(2);
- Thread.sleep(2000);
- doAppBreadcrumbReportedStop(1);
- Thread.sleep(2000);
- doAppBreadcrumbReportedStop(2);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
- assertThat(metricReport.hasDurationMetrics()).isTrue();
- StatsLogReport.DurationMetricDataWrapper durationData
- = metricReport.getDurationMetrics();
- assertThat(durationData.getDataCount()).isEqualTo(2);
- assertThat(durationData.getData(0).getBucketInfoCount()).isGreaterThan(3);
- assertThat(durationData.getData(1).getBucketInfoCount()).isGreaterThan(3);
- long totalDuration = 0;
- for (DurationBucketInfo bucketInfo : durationData.getData(0).getBucketInfoList()) {
- assertThat(bucketInfo.getDurationNanos()).isIn(Range.openClosed(0L, (long) 1e9));
- totalDuration += bucketInfo.getDurationNanos();
- }
- // Duration for both labels is expected to be 4s.
- assertThat(totalDuration).isIn(Range.open((long) 3e9, (long) 8e9));
- totalDuration = 0;
- for (DurationBucketInfo bucketInfo : durationData.getData(1).getBucketInfoList()) {
- assertThat(bucketInfo.getDurationNanos()).isIn(Range.openClosed(0L, (long) 1e9));
- totalDuration += bucketInfo.getDurationNanos();
- }
- assertThat(totalDuration).isIn(Range.open((long) 3e9, (long) 8e9));
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
deleted file mode 100644
index 2280e13..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
+++ /dev/null
@@ -1,336 +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 android.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.ActivationType;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.MetricActivation;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.log.LogUtil;
-
-public class GaugeMetricsTests extends DeviceAtomTestCase {
-
- private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
- private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1;
- private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2;
-
- public void testGaugeMetric() throws Exception {
- // Add AtomMatcher's.
- AtomMatcher startAtomMatcher =
- MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID);
- AtomMatcher stopAtomMatcher =
- MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID);
- AtomMatcher atomMatcher =
- MetricsUtils.simpleAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID);
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(startAtomMatcher);
- builder.addAtomMatcher(stopAtomMatcher);
- builder.addAtomMatcher(atomMatcher);
-
- // Add Predicate's.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
- builder.addPredicate(predicate);
-
- // Add GaugeMetric.
- FieldMatcher fieldMatcher =
- FieldMatcher.newBuilder().setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID).build();
- builder.addGaugeMetric(
- StatsdConfigProto.GaugeMetric.newBuilder()
- .setId(MetricsUtils.GAUGE_METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .setCondition(predicate.getId())
- .setGaugeFieldsFilter(
- FieldFilter.newBuilder().setIncludeAll(false).setFields(fieldMatcher).build())
- .setDimensionsInWhat(
- FieldMatcher.newBuilder()
- .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .addChild(FieldMatcher.newBuilder()
- .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .build())
- .build())
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .build());
-
- // Upload config.
- uploadConfig(builder);
-
- // Create AppBreadcrumbReported Start/Stop events.
- doAppBreadcrumbReportedStart(0);
- Thread.sleep(10);
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(10);
- doAppBreadcrumbReportedStart(2);
- Thread.sleep(2000);
- doAppBreadcrumbReportedStop(2);
- Thread.sleep(10);
- doAppBreadcrumbReportedStop(0);
- Thread.sleep(10);
- doAppBreadcrumbReportedStop(1);
- doAppBreadcrumbReportedStart(2);
- Thread.sleep(10);
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(2000);
- doAppBreadcrumbReportedStop(2);
- Thread.sleep(10);
- doAppBreadcrumbReportedStop(1);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID);
- assertThat(metricReport.hasGaugeMetrics()).isTrue();
- StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics();
- assertThat(gaugeData.getDataCount()).isEqualTo(1);
-
- int bucketCount = gaugeData.getData(0).getBucketInfoCount();
- GaugeMetricData data = gaugeData.getData(0);
- assertThat(bucketCount).isGreaterThan(2);
- MetricsUtils.assertBucketTimePresent(data.getBucketInfo(0));
- assertThat(data.getBucketInfo(0).getAtomCount()).isEqualTo(1);
- assertThat(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getLabel())
- .isEqualTo(0);
- assertThat(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getState())
- .isEqualTo(AppBreadcrumbReported.State.START);
-
- MetricsUtils.assertBucketTimePresent(data.getBucketInfo(1));
- assertThat(data.getBucketInfo(1).getAtomCount()).isEqualTo(1);
-
- MetricsUtils.assertBucketTimePresent(data.getBucketInfo(bucketCount-1));
- assertThat(data.getBucketInfo(bucketCount-1).getAtomCount()).isEqualTo(1);
- assertThat(data.getBucketInfo(bucketCount-1).getAtom(0).getAppBreadcrumbReported().getLabel())
- .isEqualTo(2);
- assertThat(data.getBucketInfo(bucketCount-1).getAtom(0).getAppBreadcrumbReported().getState())
- .isEqualTo(AppBreadcrumbReported.State.STOP);
- }
-
- public void testPulledGaugeMetricWithActivation() throws Exception {
- // Add AtomMatcher's.
- int activationAtomMatcherId = 1;
- int activationAtomMatcherLabel = 1;
-
- int systemUptimeMatcherId = 2;
- AtomMatcher activationAtomMatcher =
- MetricsUtils.appBreadcrumbMatcherWithLabel(
- activationAtomMatcherId, activationAtomMatcherLabel);
- AtomMatcher systemUptimeMatcher =
- AtomMatcher.newBuilder()
- .setId(systemUptimeMatcherId)
- .setSimpleAtomMatcher(
- SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_UPTIME_FIELD_NUMBER))
- .build();
-
- StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(activationAtomMatcher);
- builder.addAtomMatcher(systemUptimeMatcher);
-
- // Add GaugeMetric.
- builder.addGaugeMetric(
- StatsdConfigProto.GaugeMetric.newBuilder()
- .setId(MetricsUtils.GAUGE_METRIC_ID)
- .setWhat(systemUptimeMatcherId)
- .setGaugeFieldsFilter(
- FieldFilter.newBuilder().setIncludeAll(true).build())
- .setBucket(StatsdConfigProto.TimeUnit.CTS)
- .build());
-
- // Add activation.
- builder.addMetricActivation(MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.GAUGE_METRIC_ID)
- .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
- .addEventActivation(EventActivation.newBuilder()
- .setAtomMatcherId(activationAtomMatcherId)
- .setTtlSeconds(5)));
-
- // Upload config.
- uploadConfig(builder);
-
- // Plenty of time to pull, but we should not keep the data since we are not active.
- Thread.sleep(20_000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID);
- assertThat(metricReport.hasGaugeMetrics()).isFalse();
- }
-
- public void testPulledGaugeMetricWithConditionAndActivation() throws Exception {
- final int conditionLabel = 2;
- final int activationMatcherId = 5;
- final int activationMatcherLabel = 5;
- final int whatMatcherId = 8;
- final int ttlSec = 5;
-
- // Add AtomMatchers.
- AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, conditionLabel);
- AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, conditionLabel);
- AtomMatcher activationMatcher =
- MetricsUtils.startAtomMatcherWithLabel(
- activationMatcherId, activationMatcherLabel);
- AtomMatcher whatMatcher =
- MetricsUtils.unspecifiedAtomMatcher(whatMatcherId);
-
- StatsdConfig.Builder builder = createConfigBuilder()
- .addAtomMatcher(conditionStartAtomMatcher)
- .addAtomMatcher(conditionStopAtomMatcher)
- .addAtomMatcher(whatMatcher)
- .addAtomMatcher(activationMatcher);
-
- // Add Predicates.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
- builder.addPredicate(predicate);
-
- // Add GaugeMetric.
- builder
- .addGaugeMetric(GaugeMetric.newBuilder()
- .setId(MetricsUtils.GAUGE_METRIC_ID)
- .setWhat(whatMatcher.getId())
- .setBucket(TimeUnit.CTS)
- .setCondition(predicate.getId())
- .setGaugeFieldsFilter(
- FieldFilter.newBuilder().setIncludeAll(false).setFields(
- FieldMatcher.newBuilder()
- .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- )
- )
- .setDimensionsInWhat(FieldMatcher.newBuilder().setField(whatMatcherId))
- )
- .addMetricActivation(MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.GAUGE_METRIC_ID)
- .addEventActivation(EventActivation.newBuilder()
- .setAtomMatcherId(activationMatcherId)
- .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
- .setTtlSeconds(ttlSec)
- )
- );
-
- uploadConfig(builder);
-
- // Activate the metric.
- doAppBreadcrumbReportedStart(activationMatcherLabel);
- Thread.sleep(10);
-
- // Set the condition to true.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // This value is collected.
- doAppBreadcrumbReported(10);
- Thread.sleep(10);
-
- // Ignored; value already collected.
- doAppBreadcrumbReported(20);
- Thread.sleep(10);
-
- // Set the condition to false.
- doAppBreadcrumbReportedStop(conditionLabel);
- Thread.sleep(10);
-
- // Value not updated because condition is false.
- doAppBreadcrumbReported(30);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Value not collected.
- doAppBreadcrumbReported(40);
- Thread.sleep(10);
-
- // Condition to true again.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // Value not collected.
- doAppBreadcrumbReported(50);
- Thread.sleep(10);
-
- // Activate the metric.
- doAppBreadcrumbReportedStart(activationMatcherLabel);
- Thread.sleep(10);
-
- // Value collected.
- doAppBreadcrumbReported(60);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Value not collected.
- doAppBreadcrumbReported(70);
- Thread.sleep(10);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID);
- assertThat(metricReport.hasGaugeMetrics()).isTrue();
- assertThat(metricReport.getIsActive()).isFalse();
-
- StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics();
- assertThat(gaugeData.getDataCount()).isEqualTo(1);
- assertThat(gaugeData.getData(0).getBucketInfoCount()).isEqualTo(2);
-
- GaugeBucketInfo bucketInfo = gaugeData.getData(0).getBucketInfo(0);
- MetricsUtils.assertBucketTimePresent(bucketInfo);
- assertThat(bucketInfo.getAtomCount()).isEqualTo(1);
- assertThat(bucketInfo.getAtom(0).getAppBreadcrumbReported().getLabel()).isEqualTo(10);
-
- bucketInfo = gaugeData.getData(0).getBucketInfo(1);
- MetricsUtils.assertBucketTimePresent(bucketInfo);
- assertThat(bucketInfo.getAtomCount()).isEqualTo(1);
- assertThat(bucketInfo.getAtom(0).getAppBreadcrumbReported().getLabel()).isEqualTo(60);
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricActivationTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/MetricActivationTests.java
deleted file mode 100644
index 339970a..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricActivationTests.java
+++ /dev/null
@@ -1,566 +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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.ActivationType;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.MetricActivation;
-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.StatsLogReport;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.List;
-
-/**
- * Test Statsd Metric activations and deactivations
- */
-public class MetricActivationTests extends DeviceAtomTestCase {
- private final long metric1Id = 1L;
- private final int metric1MatcherId = 1;
-
- private final long metric2Id = 2L;
- private final int metric2MatcherId = 2;
-
- private final long metric3Id = 3L;
- private final int metric3MatcherId = 3;
-
- private final int act1MatcherId = 10;
- private final int act1CancelMatcherId = -10;
-
- private final int act2MatcherId = 20;
- private final int act2CancelMatcherId = -20;
-
-
- private StatsdConfig.Builder createConfig(final int act1TtlSecs, final int act2TtlSecs) {
- AtomMatcher metric1Matcher =
- MetricsUtils.simpleAtomMatcher(metric1MatcherId, metric1MatcherId);
- AtomMatcher metric2Matcher =
- MetricsUtils.simpleAtomMatcher(metric2MatcherId, metric2MatcherId);
- AtomMatcher metric3Matcher =
- MetricsUtils.simpleAtomMatcher(metric3MatcherId, metric3MatcherId);
- AtomMatcher act1Matcher =
- MetricsUtils.simpleAtomMatcher(act1MatcherId, act1MatcherId);
- AtomMatcher act1CancelMatcher =
- MetricsUtils.simpleAtomMatcher(act1CancelMatcherId, act1CancelMatcherId);
- AtomMatcher act2Matcher =
- MetricsUtils.simpleAtomMatcher(act2MatcherId, act2MatcherId);
- AtomMatcher act2CancelMatcher =
- MetricsUtils.simpleAtomMatcher(act2CancelMatcherId, act2CancelMatcherId);
-
- EventMetric metric1 = EventMetric.newBuilder()
- .setId(metric1Id)
- .setWhat(metric1MatcherId)
- .build();
-
- EventMetric metric2 = EventMetric.newBuilder()
- .setId(metric2Id)
- .setWhat(metric2MatcherId)
- .build();
-
- EventMetric metric3 = EventMetric.newBuilder()
- .setId(metric3Id)
- .setWhat(metric3MatcherId)
- .build();
-
- EventActivation metric1Act1 =
- MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
- .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
- .build();
-
- EventActivation metric1Act2 =
- MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
- .setActivationType(ActivationType.ACTIVATE_ON_BOOT)
- .build();
-
- EventActivation metric2Act1 =
- MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
- .setActivationType(ActivationType.ACTIVATE_ON_BOOT)
- .build();
-
- EventActivation metric2Act2 =
- MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
- .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
- .build();
-
- MetricActivation metric1Activation = MetricActivation.newBuilder()
- .setMetricId(metric1Id)
- .addEventActivation(metric1Act1)
- .addEventActivation(metric1Act2)
- .build();
-
- MetricActivation metric2Activation = MetricActivation.newBuilder()
- .setMetricId(metric2Id)
- .addEventActivation(metric2Act1)
- .addEventActivation(metric2Act2)
- .build();
-
- return createConfigBuilder()
- .addAtomMatcher(metric1Matcher)
- .addAtomMatcher(metric2Matcher)
- .addAtomMatcher(metric3Matcher)
- .addAtomMatcher(act1Matcher)
- .addAtomMatcher(act1CancelMatcher)
- .addAtomMatcher(act2Matcher)
- .addAtomMatcher(act2CancelMatcher)
- .addEventMetric(metric1)
- .addEventMetric(metric2)
- .addEventMetric(metric3)
- .addMetricActivation(metric1Activation)
- .addMetricActivation(metric2Activation);
- }
-
- /**
- * Metric 1:
- * Activation 1:
- * - Ttl: 5 seconds
- * - Type: IMMEDIATE
- * Activation 2:
- * - Ttl: 8 seconds
- * - Type: ON_BOOT
- *
- * Metric 2:
- * Activation 1:
- * - Ttl: 5 seconds
- * - Type: ON_BOOT
- * Activation 2:
- * - Ttl: 8 seconds
- * - Type: IMMEDIATE
- *
- * Metric 3: No activations; always active
- **/
- public void testCancellation() throws Exception {
- final int act1TtlSecs = 5;
- final int act2TtlSecs = 8;
- uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
-
- // Ignored, metric not active.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Trigger cancel for already inactive event activation 1.
- doAppBreadcrumbReported(act1CancelMatcherId);
- Thread.sleep(10L);
-
- // Trigger event activation 1.
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // First logged event.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Second logged event.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Cancel event activation 1.
- doAppBreadcrumbReported(act1CancelMatcherId);
- Thread.sleep(10L);
-
- // Ignored, metric not active.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Trigger event activation 1.
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // Trigger event activation 2.
- doAppBreadcrumbReported(act2MatcherId);
- Thread.sleep(10L);
-
- // Third logged event.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Cancel event activation 2.
- doAppBreadcrumbReported(act2CancelMatcherId);
- Thread.sleep(10L);
-
- // Fourth logged event.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Expire event activation 1
- Thread.sleep(act1TtlSecs * 1000);
-
- // Ignored, metric 1 not active. Activation 1 expired and Activation 2 was cancelled.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // Trigger event activation 2.
- doAppBreadcrumbReported(act2MatcherId);
- Thread.sleep(10L);
-
- // Metric 1 log ignored, Activation 1 expired and Activation 2 needs reboot to activate.
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- // First logged event for Metric 3.
- doAppBreadcrumbReported(metric3MatcherId);
- Thread.sleep(10L);
-
- ConfigMetricsReportList reportList = getReportList();
- List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
- ConfigMetricsReport report = reports.get(0);
- verifyMetrics(report, 4, 0, 1);
- }
-
- /**
- * Metric 1:
- * Activation 1:
- * - Ttl: 100 seconds
- * - Type: IMMEDIATE
- * Activation 2:
- * - Ttl: 200 seconds
- * - Type: ON_BOOT
- *
- * Metric 2:
- * Activation 1:
- * - Ttl: 100 seconds
- * - Type: ON_BOOT
- * Activation 2:
- * - Ttl: 200 seconds
- * - Type: IMMEDIATE
- *
- * Metric 3: No activations; always active
- **/
- public void testRestart() throws Exception {
- final int act1TtlSecs = 200;
- final int act2TtlSecs = 400;
- uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
-
- // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds (will activate after boot)
- // Metric 2 Activation 2: 0 seconds
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // First logged event for Metric 1.
- // Metric 2 event ignored, will activate after boot.
- // First logged event for Metric 3.
- logAllMetrics();
-
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 200 seconds
- // Metric 2 Activation 2: 0 seconds
- rebootDeviceAndWaitUntilReady();
-
- // Second logged event for Metric 1.
- // First logged event for Metric 2.
- // Second logged event for Metric 3.
- logAllMetrics();
-
- // Time remaining:
- // Metric 1 Activation 1: 0 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds
- // Metric 2 Activation 2: 0 seconds
- Thread.sleep(act1TtlSecs * 1000L);
-
- // Metric 1 event ignored, Activation 1 expired.
- // Metric 2 event ignored, Activation 1 expired.
- // Third logged event for Metric 3.
- logAllMetrics();
-
- // Trigger Metric 1 Activation 2 and Metric 2 Activation 2.
- // Time remaining:
- // Metric 1 Activation 1: 0 seconds
- // Metric 1 Activation 2: 0 seconds (will activate after boot)
- // Metric 2 Activation 1: 0 seconds
- // Metric 2 Activation 2: 400 seconds
- doAppBreadcrumbReported(act2MatcherId);
- Thread.sleep(10L);
-
- // Metric 1 event ignored, will activate after boot.
- // Second logged event for Metric 2.
- // Fourth logged event for Metric 3.
- logAllMetrics();
-
- // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds (will activate after boot)
- // Metric 2 Activation 1: 0 seconds (will activate after boot)
- // Metric 2 Activation 2: 400 seconds
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // Third logged event for Metric 1.
- // Third logged event for Metric 2.
- // Fifth logged event for Metric 3.
- logAllMetrics();
-
- // Time remaining:
- // Metric 1 Activation 1: 100 seconds
- // Metric 1 Activation 2: 0 seconds (will activate after boot)
- // Metric 2 Activation 1: 0 seconds (will activate after boot)
- // Metric 2 Activation 2: 300 seconds
- Thread.sleep(act1TtlSecs * 1000L / 2);
-
- // Time remaining:
- // Metric 1 Activation 1: 100 seconds
- // Metric 1 Activation 2: 400 seconds
- // Metric 2 Activation 1: 200 seconds
- // Metric 2 Activation 2: 300 seconds
- rebootDeviceAndWaitUntilReady();
-
- // Fourth logged event for Metric 1.
- // Fourth logged event for Metric 2.
- // Sixth logged event for Metric 3.
- logAllMetrics();
-
- // Expire Metric 1 Activation 1.
- // Time remaining:
- // Metric 1 Activation 1: 0 seconds
- // Metric 1 Activation 2: 300 seconds
- // Metric 2 Activation 1: 100 seconds
- // Metric 2 Activation 2: 200 seconds
- Thread.sleep(act1TtlSecs * 1000L / 2);
-
- // Fifth logged event for Metric 1.
- // Fifth logged event for Metric 2.
- // Seventh logged event for Metric 3.
- logAllMetrics();
-
- // Expire all activations.
- // Time remaining:
- // Metric 1 Activation 1: 0 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds
- // Metric 2 Activation 2: 0 seconds
- Thread.sleep(act2TtlSecs * 1000L);
-
- // Metric 1 event ignored.
- // Metric 2 event ignored.
- // Eighth logged event for Metric 3.
- logAllMetrics();
-
- ConfigMetricsReportList reportList = getReportList();
- List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
- assertThat(reports).hasSize(3);
-
- // Report before restart.
- ConfigMetricsReport report = reports.get(0);
- verifyMetrics(report, 1, 0, 1);
-
- // Report after first restart.
- report = reports.get(1);
- verifyMetrics(report, 2, 3, 4);
-
- // Report after second restart.
- report = reports.get(2);
- verifyMetrics(report, 2, 2, 3);
- }
-
- /**
- * Metric 1:
- * Activation 1:
- * - Ttl: 100 seconds
- * - Type: IMMEDIATE
- * Activation 2:
- * - Ttl: 200 seconds
- * - Type: ON_BOOT
- *
- * Metric 2:
- * Activation 1:
- * - Ttl: 100 seconds
- * - Type: ON_BOOT
- * Activation 2:
- * - Ttl: 200 seconds
- * - Type: IMMEDIATE
- *
- * Metric 3: No activations; always active
- **/
- public void testMultipleActivations() throws Exception {
- final int act1TtlSecs = 200;
- final int act2TtlSecs = 400;
- uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
-
- // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds (will activate after boot)
- // Metric 2 Activation 2: 0 seconds
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // First logged event for Metric 1.
- // Metric 2 event ignored, will activate after boot.
- // First logged event for Metric 3.
- logAllMetrics();
-
- // Time remaining:
- // Metric 1 Activation 1: 100 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds (will activate after boot)
- // Metric 2 Activation 2: 0 seconds
- Thread.sleep(act1TtlSecs * 1000L / 2);
-
- // Second logged event for Metric 1.
- // Metric 2 event ignored, will activate after boot.
- // Second logged event for Metric 3.
- logAllMetrics();
-
- // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds (will activate after boot)
- // Metric 2 Activation 2: 0 seconds
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // Third logged event for Metric 1.
- // Metric 2 event ignored, will activate after boot.
- // Third logged event for Metric 3.
- logAllMetrics();
-
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 200 seconds
- // Metric 2 Activation 2: 0 seconds
- rebootDeviceAndWaitUntilReady();
-
- // Fourth logged event for Metric 1.
- // First logged event for Metric 2.
- // Fourth logged event for Metric 3.
- logAllMetrics();
-
- // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
- // Time remaining:
- // Metric 1 Activation 1: 200 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 200 seconds
- // Metric 2 Activation 2: 0 seconds
- doAppBreadcrumbReported(act1MatcherId);
- Thread.sleep(10L);
-
- // Fifth logged event for Metric 1.
- // Second logged event for Metric 2.
- // Fifth logged event for Metric 3.
- logAllMetrics();
-
- // Expire all activations.
- // Time remaining:
- // Metric 1 Activation 1: 0 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds
- // Metric 2 Activation 2: 0 seconds
- Thread.sleep(act1TtlSecs * 1000L);
-
- // Metric 1 event ignored.
- // Metric 2 event ignored.
- // Sixth logged event for Metric 3.
- logAllMetrics();
-
- // Time remaining:
- // Metric 1 Activation 1: 0 seconds
- // Metric 1 Activation 2: 0 seconds
- // Metric 2 Activation 1: 0 seconds
- // Metric 2 Activation 2: 0 seconds
- rebootDeviceAndWaitUntilReady();
-
- // Metric 1 event ignored.
- // Metric 2 event ignored.
- // Seventh logged event for Metric 3.
- logAllMetrics();
-
- ConfigMetricsReportList reportList = getReportList();
- List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
- assertThat(reports).hasSize(3);
-
- // Report before restart.
- ConfigMetricsReport report = reports.get(0);
- verifyMetrics(report, 3, 0, 3);
-
- // Report after first restart.
- report = reports.get(1);
- verifyMetrics(report, 2, 2, 3);
-
- // Report after second restart.
- report = reports.get(2);
- verifyMetrics(report, 0, 0, 1);
- }
-
- private void logAllMetrics() throws Exception {
- doAppBreadcrumbReported(metric1MatcherId);
- Thread.sleep(10L);
-
- doAppBreadcrumbReported(metric2MatcherId);
- Thread.sleep(10L);
-
- doAppBreadcrumbReported(metric3MatcherId);
- Thread.sleep(10L);
- }
-
- private void verifyMetrics(ConfigMetricsReport report, int metric1Count, int metric2Count,
- int metric3Count) throws Exception {
- assertThat(report.getMetricsCount()).isEqualTo(3);
-
- verifyMetric(
- report.getMetrics(0), // StatsLogReport
- 1, // Metric Id
- 1, // Metric what atom matcher label
- metric1Count // Data count
- );
- verifyMetric(
- report.getMetrics(1), // StatsLogReport
- 2, // Metric Id
- 2, // Metric what atom matcher label
- metric2Count // Data count
- );
- verifyMetric(
- report.getMetrics(2), // StatsLogReport
- 3, // Metric Id
- 3, // Metric what atom matcher label
- metric3Count // Data count
- );
- }
-
- private void verifyMetric(StatsLogReport metricReport, long metricId, int metricMatcherLabel,
- int dataCount) {
- LogUtil.CLog.d("Got the following event metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(metricId);
- assertThat(metricReport.hasEventMetrics()).isEqualTo(dataCount > 0);
-
- StatsLogReport.EventMetricDataWrapper eventData = metricReport.getEventMetrics();
- assertThat(eventData.getDataCount()).isEqualTo(dataCount);
- for (int i = 0; i < eventData.getDataCount(); i++) {
- AppBreadcrumbReported atom = eventData.getData(i).getAtom().getAppBreadcrumbReported();
- assertThat(atom.getLabel()).isEqualTo(metricMatcherLabel);
- }
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java b/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
deleted file mode 100644
index 7097587..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
+++ /dev/null
@@ -1,163 +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 android.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.google.protobuf.Message;
-import com.google.protobuf.Descriptors.Descriptor;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-public class MetricsUtils {
- public static final long COUNT_METRIC_ID = 3333;
- public static final long DURATION_METRIC_ID = 4444;
- public static final long GAUGE_METRIC_ID = 5555;
- public static final long VALUE_METRIC_ID = 6666;
-
- public static AtomMatcher.Builder getAtomMatcher(int atomId) {
- AtomMatcher.Builder builder = AtomMatcher.newBuilder();
- builder.setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(atomId));
- return builder;
- }
-
- public static AtomMatcher startAtomMatcher(int id) {
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(
- SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .setEqInt(AppBreadcrumbReported.State.START.ordinal())))
- .build();
- }
-
- public static AtomMatcher startAtomMatcherWithLabel(int id, int label) {
- return appBreadcrumbMatcherWithLabelAndState(id, label, AppBreadcrumbReported.State.START);
- }
-
- public static AtomMatcher stopAtomMatcher(int id) {
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(
- SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .setEqInt(AppBreadcrumbReported.State.STOP.ordinal())))
- .build();
- }
-
- public static AtomMatcher stopAtomMatcherWithLabel(int id, int label) {
- return appBreadcrumbMatcherWithLabelAndState(id, label, AppBreadcrumbReported.State.STOP);
- }
-
- public static AtomMatcher unspecifiedAtomMatcher(int id) {
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .setEqInt(AppBreadcrumbReported.State.UNSPECIFIED.ordinal())))
- .build();
- }
-
- public static AtomMatcher simpleAtomMatcher(int id) {
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(
- SimpleAtomMatcher.newBuilder().setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER))
- .build();
- }
-
- public static AtomMatcher appBreadcrumbMatcherWithLabel(int 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 AtomMatcher appBreadcrumbMatcherWithLabelAndState(int id, int label,
- final AppBreadcrumbReported.State state) {
-
- return AtomMatcher.newBuilder()
- .setId(id)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
- .setEqInt(state.ordinal()))
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
- .setEqInt(label)))
- .build();
- }
-
- public static AtomMatcher simpleAtomMatcher(int 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 EventActivation.Builder createEventActivation(int ttlSecs, int matcherId,
- int cancelMatcherId) {
- return EventActivation.newBuilder()
- .setAtomMatcherId(matcherId)
- .setTtlSeconds(ttlSecs)
- .setDeactivationAtomMatcherId(cancelMatcherId);
- }
-
- public static long StringToId(String str) {
- return str.hashCode();
- }
-
- public static void assertBucketTimePresent(Message bucketInfo) {
- Descriptor descriptor = bucketInfo.getDescriptorForType();
- boolean found = false;
- FieldDescriptor bucketNum = descriptor.findFieldByName("bucket_num");
- FieldDescriptor startMillis = descriptor.findFieldByName("start_bucket_elapsed_millis");
- FieldDescriptor endMillis = descriptor.findFieldByName("end_bucket_elapsed_millis");
- if (bucketNum != null && bucketInfo.hasField(bucketNum)) {
- found = true;
- } else if (startMillis != null && bucketInfo.hasField(startMillis) &&
- endMillis != null && bucketInfo.hasField(endMillis)) {
- found = true;
- }
- assertWithMessage(
- "Bucket info did not have either bucket num or start and end elapsed millis"
- ).that(found).isTrue();
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
deleted file mode 100644
index 0cf5bbb..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
+++ /dev/null
@@ -1,465 +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 android.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto.ActivationType;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.MetricActivation;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.SystemElapsedRealtime;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.StatsLogReport.BucketDropReason;
-import com.android.os.StatsLog.ValueBucketInfo;
-import com.android.os.StatsLog.ValueMetricData;
-
-import com.android.tradefed.log.LogUtil;
-
-public class ValueMetricsTests extends DeviceAtomTestCase {
- private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
- private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1;
- private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2;
-
- public void testValueMetric() throws Exception {
- // Add AtomMatcher's.
- AtomMatcher startAtomMatcher =
- MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID);
- AtomMatcher stopAtomMatcher =
- MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID);
- AtomMatcher atomMatcher =
- MetricsUtils.simpleAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID);
-
- StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(startAtomMatcher);
- builder.addAtomMatcher(stopAtomMatcher);
- builder.addAtomMatcher(atomMatcher);
-
- // Add ValueMetric.
- builder.addValueMetric(
- ValueMetric.newBuilder()
- .setId(MetricsUtils.VALUE_METRIC_ID)
- .setWhat(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .setBucket(TimeUnit.CTS)
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder().setField(
- AppBreadcrumbReported.LABEL_FIELD_NUMBER)))
- .setDimensionsInWhat(FieldMatcher.newBuilder()
- .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
- .build())
- .build());
-
- // Upload config.
- uploadConfig(builder);
-
- // Create AppBreadcrumbReported Start/Stop events.
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(1000);
- doAppBreadcrumbReportedStop(1);
- doAppBreadcrumbReportedStart(3);
- doAppBreadcrumbReportedStop(3);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(1000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
- assertThat(metricReport.hasValueMetrics()).isTrue();
- StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
- assertThat(valueData.getDataCount()).isEqualTo(1);
-
- int bucketCount = valueData.getData(0).getBucketInfoCount();
- assertThat(bucketCount).isGreaterThan(1);
- ValueMetricData data = valueData.getData(0);
- int totalValue = 0;
- for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
- MetricsUtils.assertBucketTimePresent(bucketInfo);
- assertThat(bucketInfo.getValuesCount()).isEqualTo(1);
- assertThat(bucketInfo.getValues(0).getIndex()).isEqualTo(0);
- totalValue += (int) bucketInfo.getValues(0).getValueLong();
- }
- assertThat(totalValue).isEqualTo(8);
- }
-
- // Test value metric with pulled atoms and across multiple buckets
- public void testPullerAcrossBuckets() throws Exception {
- // Add AtomMatcher's.
- final String predicateTrueName = "APP_BREADCRUMB_REPORTED_START";
- final String predicateFalseName = "APP_BREADCRUMB_REPORTED_STOP";
- final String predicateName = "APP_BREADCRUMB_REPORTED_IS_STOP";
-
- AtomMatcher startAtomMatcher =
- MetricsUtils.startAtomMatcher(predicateTrueName.hashCode());
- AtomMatcher stopAtomMatcher =
- MetricsUtils.stopAtomMatcher(predicateFalseName.hashCode());
-
- StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(startAtomMatcher);
- builder.addAtomMatcher(stopAtomMatcher);
- builder.addPredicate(Predicate.newBuilder()
- .setId(predicateName.hashCode())
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(predicateTrueName.hashCode())
- .setStop(predicateFalseName.hashCode())
- .setCountNesting(false)
- )
- );
-
- final String atomName = "SYSTEM_ELAPSED_REALTIME";
- SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER);
- builder.addAtomMatcher(AtomMatcher.newBuilder()
- .setId(atomName.hashCode())
- .setSimpleAtomMatcher(sam));
-
- // Add ValueMetric.
- builder.addValueMetric(
- ValueMetric.newBuilder()
- .setId(MetricsUtils.VALUE_METRIC_ID)
- .setWhat(atomName.hashCode())
- .setBucket(TimeUnit.ONE_MINUTE)
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder().setField(
- SystemElapsedRealtime.TIME_MILLIS_FIELD_NUMBER)))
- .setCondition(predicateName.hashCode())
- .build());
-
- // Upload config.
- uploadConfig(builder);
-
- // Create AppBreadcrumbReported Start/Stop events.
- doAppBreadcrumbReportedStart(1);
- // Wait for 2 min and 1 sec to capture at least 2 buckets
- Thread.sleep(2*60_000 + 10_000);
- doAppBreadcrumbReportedStop(1);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(1_000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
- assertThat(metricReport.hasValueMetrics()).isTrue();
- StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
- assertThat(valueData.getDataCount()).isEqualTo(1);
-
- int bucketCount = valueData.getData(0).getBucketInfoCount();
- // should have at least 2 buckets
- assertThat(bucketCount).isAtLeast(2);
- ValueMetricData data = valueData.getData(0);
- int totalValue = 0;
- for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
- MetricsUtils.assertBucketTimePresent(bucketInfo);
- assertThat(bucketInfo.getValuesCount()).isEqualTo(1);
- assertThat(bucketInfo.getValues(0).getIndex()).isEqualTo(0);
- totalValue += (int) bucketInfo.getValues(0).getValueLong();
- }
- // At most we lose one full min bucket
- assertThat(totalValue).isGreaterThan(130_000 - 60_000);
- }
-
- // Test value metric with pulled atoms and across multiple buckets
- public void testMultipleEventsPerBucket() throws Exception {
- // Add AtomMatcher's.
- final String predicateTrueName = "APP_BREADCRUMB_REPORTED_START";
- final String predicateFalseName = "APP_BREADCRUMB_REPORTED_STOP";
- final String predicateName = "APP_BREADCRUMB_REPORTED_IS_STOP";
-
- AtomMatcher startAtomMatcher =
- MetricsUtils.startAtomMatcher(predicateTrueName.hashCode());
- AtomMatcher stopAtomMatcher =
- MetricsUtils.stopAtomMatcher(predicateFalseName.hashCode());
-
- StatsdConfig.Builder builder = createConfigBuilder();
- builder.addAtomMatcher(startAtomMatcher);
- builder.addAtomMatcher(stopAtomMatcher);
- builder.addPredicate(Predicate.newBuilder()
- .setId(predicateName.hashCode())
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(predicateTrueName.hashCode())
- .setStop(predicateFalseName.hashCode())
- .setCountNesting(false)
- )
- );
-
- final String atomName = "SYSTEM_ELAPSED_REALTIME";
- SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER);
- builder.addAtomMatcher(AtomMatcher.newBuilder()
- .setId(atomName.hashCode())
- .setSimpleAtomMatcher(sam));
-
- // Add ValueMetric.
- builder.addValueMetric(
- ValueMetric.newBuilder()
- .setId(MetricsUtils.VALUE_METRIC_ID)
- .setWhat(atomName.hashCode())
- .setBucket(TimeUnit.ONE_MINUTE)
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder().setField(
- SystemElapsedRealtime.TIME_MILLIS_FIELD_NUMBER)))
- .setCondition(predicateName.hashCode())
- .build());
-
- // Upload config.
- uploadConfig(builder);
-
- final int NUM_EVENTS = 10;
- final long GAP_INTERVAL = 10_000;
- // Create AppBreadcrumbReported Start/Stop events.
- for (int i = 0; i < NUM_EVENTS; i ++) {
- doAppBreadcrumbReportedStart(1);
- Thread.sleep(GAP_INTERVAL);
- doAppBreadcrumbReportedStop(1);
- Thread.sleep(GAP_INTERVAL);
- }
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(1_000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
- assertThat(metricReport.hasValueMetrics()).isTrue();
- StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
- assertThat(valueData.getDataCount()).isEqualTo(1);
-
- int bucketCount = valueData.getData(0).getBucketInfoCount();
- // should have at least 2 buckets
- assertThat(bucketCount).isAtLeast(2);
- ValueMetricData data = valueData.getData(0);
- int totalValue = 0;
- for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
- MetricsUtils.assertBucketTimePresent(bucketInfo);
- assertThat(bucketInfo.getValuesCount()).isEqualTo(1);
- assertThat(bucketInfo.getValues(0).getIndex()).isEqualTo(0);
- totalValue += (int) bucketInfo.getValues(0).getValueLong();
- }
- // At most we lose one full min bucket
- assertThat((long) totalValue).isGreaterThan(GAP_INTERVAL * NUM_EVENTS - 60_000);
- }
-
- // Test value metric with pulled atoms and across multiple buckets
- public void testPullerAcrossBucketsWithActivation() throws Exception {
- StatsdConfig.Builder builder = createConfigBuilder();
-
- // Add AtomMatcher's.
- int activationAtomMatcherId = 1;
- int activationAtomMatcherLabel = 1;
- AtomMatcher activationAtomMatcher =
- MetricsUtils.appBreadcrumbMatcherWithLabel(
- activationAtomMatcherId, activationAtomMatcherLabel);
- final String atomName = "SYSTEM_ELAPSED_REALTIME";
- SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER);
- builder.addAtomMatcher(activationAtomMatcher)
- .addAtomMatcher(AtomMatcher.newBuilder()
- .setId(atomName.hashCode())
- .setSimpleAtomMatcher(sam));
-
- // Add ValueMetric.
- builder.addValueMetric(
- ValueMetric.newBuilder()
- .setId(MetricsUtils.VALUE_METRIC_ID)
- .setWhat(atomName.hashCode())
- .setBucket(TimeUnit.ONE_MINUTE)
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder().setField(
- SystemElapsedRealtime.TIME_MILLIS_FIELD_NUMBER)))
- .build());
- // Add activation.
- builder.addMetricActivation(MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.VALUE_METRIC_ID)
- .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
- .addEventActivation(EventActivation.newBuilder()
- .setAtomMatcherId(activationAtomMatcherId)
- .setTtlSeconds(5)));
-
-
- // Upload config.
- uploadConfig(builder);
-
- // Wait for 1 min and 10 sec to capture at least 1 bucket
- Thread.sleep(60_000 + 10_000);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(1_000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
- assertThat(metricReport.getValueMetrics().getDataList()).isEmpty();
- // Bucket is skipped because metric is not activated.
- assertThat(metricReport.getValueMetrics().getSkippedList()).isNotEmpty();
- assertThat(metricReport.getValueMetrics().getSkipped(0).getDropEventList()).isNotEmpty();
- assertThat(metricReport.getValueMetrics().getSkipped(0).getDropEvent(0).getDropReason())
- .isEqualTo(BucketDropReason.NO_DATA);
- }
-
- public void testValueMetricWithConditionAndActivation() throws Exception {
- final int conditionLabel = 2;
- final int activationMatcherId = 5;
- final int activationMatcherLabel = 5;
- final int whatMatcherId = 8;
- final int ttlSec = 5;
-
- // Add AtomMatchers.
- AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, conditionLabel);
- AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
- APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, conditionLabel);
- AtomMatcher activationMatcher =
- MetricsUtils.startAtomMatcherWithLabel(
- activationMatcherId, activationMatcherLabel);
- AtomMatcher whatMatcher =
- MetricsUtils.unspecifiedAtomMatcher(whatMatcherId);
-
- StatsdConfig.Builder builder = createConfigBuilder()
- .addAtomMatcher(conditionStartAtomMatcher)
- .addAtomMatcher(conditionStopAtomMatcher)
- .addAtomMatcher(whatMatcher)
- .addAtomMatcher(activationMatcher);
-
- // Add Predicates.
- SimplePredicate simplePredicate = SimplePredicate.newBuilder()
- .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
- .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
- .build();
- Predicate predicate = Predicate.newBuilder()
- .setId(MetricsUtils.StringToId("Predicate"))
- .setSimplePredicate(simplePredicate)
- .build();
- builder.addPredicate(predicate);
-
- // Add ValueMetric.
- builder
- .addValueMetric(ValueMetric.newBuilder()
- .setId(MetricsUtils.VALUE_METRIC_ID)
- .setWhat(whatMatcher.getId())
- .setBucket(TimeUnit.ONE_MINUTE)
- .setCondition(predicate.getId())
- .setValueField(FieldMatcher.newBuilder()
- .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
- .addChild(FieldMatcher.newBuilder()
- .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
- )
- .setDimensionsInWhat(FieldMatcher.newBuilder().setField(whatMatcherId))
- )
- .addMetricActivation(MetricActivation.newBuilder()
- .setMetricId(MetricsUtils.VALUE_METRIC_ID)
- .addEventActivation(EventActivation.newBuilder()
- .setAtomMatcherId(activationMatcherId)
- .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
- .setTtlSeconds(ttlSec)
- )
- );
-
- uploadConfig(builder);
-
- // Activate the metric.
- doAppBreadcrumbReportedStart(activationMatcherLabel);
- Thread.sleep(10);
-
- // Set the condition to true.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // Skipped due to unknown condition at start of bucket.
- doAppBreadcrumbReported(10);
- Thread.sleep(10);
-
- // Skipped due to unknown condition at start of bucket.
- doAppBreadcrumbReported(200);
- Thread.sleep(10);
-
- // Set the condition to false.
- doAppBreadcrumbReportedStop(conditionLabel);
- Thread.sleep(10);
-
- // Log an event that should not be counted because condition is false.
- doAppBreadcrumbReported(3_000);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Log an event that should not be counted.
- doAppBreadcrumbReported(40_000);
- Thread.sleep(10);
-
- // Condition to true again.
- doAppBreadcrumbReportedStart(conditionLabel);
- Thread.sleep(10);
-
- // Event should not be counted, metric is still not active.
- doAppBreadcrumbReported(500_000);
- Thread.sleep(10);
-
- // Activate the metric.
- doAppBreadcrumbReportedStart(activationMatcherLabel);
- Thread.sleep(10);
-
- // Log an event that should be counted.
- doAppBreadcrumbReported(6_000_000);
- Thread.sleep(10);
-
- // Let the metric deactivate.
- Thread.sleep(ttlSec * 1000);
-
- // Log an event that should not be counted.
- doAppBreadcrumbReported(70_000_000);
- Thread.sleep(10);
-
- // Wait for the metrics to propagate to statsd.
- Thread.sleep(2000);
-
- StatsLogReport metricReport = getStatsLogReport();
- LogUtil.CLog.d("Received the following data: " + metricReport.toString());
- assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
- assertThat(metricReport.hasValueMetrics()).isTrue();
- assertThat(metricReport.getIsActive()).isFalse();
-
- StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
- assertThat(valueData.getDataCount()).isEqualTo(1);
- assertThat(valueData.getData(0).getBucketInfoCount()).isEqualTo(1);
- long totalValue = valueData.getData(0).getBucketInfoList().stream()
- .peek(MetricsUtils::assertBucketTimePresent)
- .peek(bucketInfo -> assertThat(bucketInfo.getValuesCount()).isEqualTo(1))
- .map(bucketInfo -> bucketInfo.getValues(0))
- .peek(value -> assertThat(value.getIndex()).isEqualTo(0))
- .mapToLong(value -> value.getValueLong())
- .sum();
- assertThat(totalValue).isEqualTo(6_000_000);
- }
-
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/subscriber/ShellSubscriberTest.java b/hostsidetests/statsd/src/android/cts/statsd/subscriber/ShellSubscriberTest.java
deleted file mode 100644
index ba980fb..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/subscriber/ShellSubscriberTest.java
+++ /dev/null
@@ -1,199 +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.cts.statsd.subscriber;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.compatibility.common.util.CpuFeatures;
-import com.android.internal.os.StatsdConfigProto;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.SystemUptime;
-import com.android.os.ShellConfig;
-import com.android.os.statsd.ShellDataProto;
-import com.android.tradefed.device.CollectingByteOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.google.common.io.Files;
-import com.google.protobuf.InvalidProtocolBufferException;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Statsd shell data subscription test.
- */
-public class ShellSubscriberTest extends DeviceTestCase {
- private int sizetBytes;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- sizetBytes = getSizetBytes();
- }
-
- public void testShellSubscription() {
- if (sizetBytes < 0) {
- return;
- }
-
- ShellConfig.ShellSubscription config = createConfig();
- CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
- startSubscription(config, receiver, /*maxTimeoutForCommandSec=*/5,
- /*subscriptionTimeSec=*/5);
- checkOutput(receiver);
- }
-
- public void testShellSubscriptionReconnect() {
- if (sizetBytes < 0) {
- return;
- }
-
- ShellConfig.ShellSubscription config = createConfig();
- for (int i = 0; i < 5; i++) {
- CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
- // A subscription time of -1 means that statsd will not impose a timeout on the
- // subscription. Thus, the client will exit before statsd ends the subscription.
- startSubscription(config, receiver, /*maxTimeoutForCommandSec=*/5,
- /*subscriptionTimeSec=*/-1);
- checkOutput(receiver);
- }
- }
-
- private int getSizetBytes() {
- try {
- ITestDevice device = getDevice();
- if (CpuFeatures.isArm64(device)) {
- return 8;
- }
- if (CpuFeatures.isArm32(device)) {
- return 4;
- }
- return -1;
- } catch (DeviceNotAvailableException e) {
- return -1;
- }
- }
-
- // Choose a pulled atom that is likely to be supported on all devices (SYSTEM_UPTIME). Testing
- // pushed atoms is trickier because executeShellCommand() is blocking, so we cannot push a
- // breadcrumb event while the shell subscription is running.
- private ShellConfig.ShellSubscription createConfig() {
- return ShellConfig.ShellSubscription.newBuilder()
- .addPulled(ShellConfig.PulledAtomSubscription.newBuilder()
- .setMatcher(StatsdConfigProto.SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SYSTEM_UPTIME_FIELD_NUMBER))
- .setFreqMillis(2000))
- .build();
- }
-
- /**
- * @param maxTimeoutForCommandSec maximum time imposed by adb that the command will run
- * @param subscriptionTimeSec maximum time imposed by statsd that the subscription will last
- */
- private void startSubscription(
- ShellConfig.ShellSubscription config,
- CollectingByteOutputReceiver receiver,
- int maxTimeoutForCommandSec,
- int subscriptionTimeSec) {
- LogUtil.CLog.d("Uploading the following config:\n" + config.toString());
- try {
- File configFile = File.createTempFile("shellconfig", ".config");
- configFile.deleteOnExit();
- int length = config.toByteArray().length;
- byte[] combined = new byte[sizetBytes + config.toByteArray().length];
-
- System.arraycopy(IntToByteArrayLittleEndian(length), 0, combined, 0, sizetBytes);
- System.arraycopy(config.toByteArray(), 0, combined, sizetBytes, length);
-
- Files.write(combined, configFile);
- String remotePath = "/data/local/tmp/" + configFile.getName();
- getDevice().pushFile(configFile, remotePath);
- LogUtil.CLog.d("waiting....................");
-
- String cmd = String.join(" ", "cat", remotePath, "|", "cmd stats data-subscribe",
- String.valueOf(subscriptionTimeSec));
-
-
- getDevice().executeShellCommand(cmd, receiver, maxTimeoutForCommandSec,
- /*maxTimeToOutputShellResponse=*/maxTimeoutForCommandSec, TimeUnit.SECONDS,
- /*retryAttempts=*/0);
- getDevice().executeShellCommand("rm " + remotePath);
- } catch (Exception e) {
- fail(e.getMessage());
- }
- }
-
- private byte[] IntToByteArrayLittleEndian(int length) {
- ByteBuffer b = ByteBuffer.allocate(sizetBytes);
- b.order(ByteOrder.LITTLE_ENDIAN);
- b.putInt(length);
- return b.array();
- }
-
- // We do not know how much data will be returned, but we can check the data format.
- private void checkOutput(CollectingByteOutputReceiver receiver) {
- int atomCount = 0;
- int startIndex = 0;
-
- byte[] output = receiver.getOutput();
- assertThat(output.length).isGreaterThan(0);
- while (output.length > startIndex) {
- assertThat(output.length).isAtLeast(startIndex + sizetBytes);
- int dataLength = readSizetFromByteArray(output, startIndex);
- if (dataLength == 0) {
- // We have received a heartbeat from statsd. This heartbeat isn't accompanied by any
- // atoms so return to top of while loop.
- startIndex += sizetBytes;
- continue;
- }
- assertThat(output.length).isAtLeast(startIndex + sizetBytes + dataLength);
-
- ShellDataProto.ShellData data = null;
- try {
- int dataStart = startIndex + sizetBytes;
- int dataEnd = dataStart + dataLength;
- data = ShellDataProto.ShellData.parseFrom(
- Arrays.copyOfRange(output, dataStart, dataEnd));
- } catch (InvalidProtocolBufferException e) {
- fail("Failed to parse proto");
- }
-
- assertThat(data.getAtomCount()).isEqualTo(1);
- assertThat(data.getAtom(0).hasSystemUptime()).isTrue();
- assertThat(data.getAtom(0).getSystemUptime().getUptimeMillis()).isGreaterThan(0L);
- atomCount++;
- startIndex += sizetBytes + dataLength;
- }
- assertThat(atomCount).isGreaterThan(0);
- }
-
- // Converts the bytes in range [startIndex, startIndex + sizetBytes) from a little-endian array
- // into an integer. Even though sizetBytes could be greater than 4, we assume that the result
- // will fit within an int.
- private int readSizetFromByteArray(byte[] arr, int startIndex) {
- int value = 0;
- for (int j = 0; j < sizetBytes; j++) {
- value += ((int) arr[j + startIndex] & 0xffL) << (8 * j);
- }
- return value;
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java b/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
deleted file mode 100644
index 4ceefa7..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
+++ /dev/null
@@ -1,136 +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 android.cts.statsd.uidmap;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.internal.os.StatsdConfigProto;
-import com.android.os.AtomsProto;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.UidMapping;
-import com.android.os.StatsLog.UidMapping.PackageInfoSnapshot;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.List;
-
-public class UidMapTests extends DeviceAtomTestCase {
-
- // Tests that every report has at least one snapshot.
- public void testUidSnapshotIncluded() throws Exception {
- // There should be at least the test app installed during the test setup.
- createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
-
- ConfigMetricsReportList reports = getReportList();
- assertThat(reports.getReportsCount()).isGreaterThan(0);
-
- for (ConfigMetricsReport report : reports.getReportsList()) {
- UidMapping uidmap = report.getUidMap();
- assertThat(uidmap.getSnapshotsCount()).isGreaterThan(0);
- for (PackageInfoSnapshot snapshot : uidmap.getSnapshotsList()) {
- // There must be at least one element in each snapshot (at least one package is
- // installed).
- assertThat(snapshot.getPackageInfoCount()).isGreaterThan(0);
- }
- }
- }
-
- private boolean hasMatchingChange(UidMapping uidmap, int uid, boolean expectDeletion) {
- LogUtil.CLog.d("The uid we are looking for is " + uid);
- for (UidMapping.Change change : uidmap.getChangesList()) {
- if (change.getAppHash() == DEVICE_SIDE_TEST_PKG_HASH && change.getUid() == uid) {
- if (change.getDeletion() == expectDeletion) {
- return true;
- }
- }
- }
- return false;
- }
-
- // Tests that delta event included during app installation.
- public void testChangeFromInstallation() throws Exception {
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
- createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
- // Install the package after the config is sent to statsd. The uid map is not guaranteed to
- // be updated if there's no config in statsd.
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
- final String result = getDevice().installPackage(
- buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
-
- Thread.sleep(WAIT_TIME_LONG);
-
- ConfigMetricsReportList reports = getReportList();
- assertThat(reports.getReportsCount()).isGreaterThan(0);
-
- boolean found = false;
- int uid = getUid();
- for (ConfigMetricsReport report : reports.getReportsList()) {
- LogUtil.CLog.d("Got the following report: \n" + report.toString());
- if (hasMatchingChange(report.getUidMap(), uid, false)) {
- found = true;
- }
- }
- assertThat(found).isTrue();
- }
-
- // We check that a re-installation gives a change event (similar to an app upgrade).
- public void testChangeFromReinstall() throws Exception {
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
- getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
- createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
- // Now enable re-installation.
- getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
-
- Thread.sleep(WAIT_TIME_LONG);
-
- ConfigMetricsReportList reports = getReportList();
- assertThat(reports.getReportsCount()).isGreaterThan(0);
-
- boolean found = false;
- int uid = getUid();
- for (ConfigMetricsReport report : reports.getReportsList()) {
- LogUtil.CLog.d("Got the following report: \n" + report.toString());
- if (hasMatchingChange(report.getUidMap(), uid, false)) {
- found = true;
- }
- }
- assertThat(found).isTrue();
- }
-
- public void testChangeFromUninstall() throws Exception {
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
- getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
- createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
- int uid = getUid();
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-
- Thread.sleep(WAIT_TIME_LONG);
-
- ConfigMetricsReportList reports = getReportList();
- assertThat(reports.getReportsCount()).isGreaterThan(0);
-
- boolean found = false;
- for (ConfigMetricsReport report : reports.getReportsList()) {
- LogUtil.CLog.d("Got the following report: \n" + report.toString());
- if (hasMatchingChange(report.getUidMap(), uid, true)) {
- found = true;
- }
- }
- assertThat(found).isTrue();
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java
deleted file mode 100644
index 125a32a..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java
+++ /dev/null
@@ -1,209 +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 android.cts.statsd.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-import android.os.BatteryStatsProto;
-import android.os.UidProto;
-import android.os.UidProto.Package;
-import android.os.UidProto.Package.Service;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.DeviceCalculatedPowerBlameUid;
-import com.android.os.StatsLog.DimensionsValue;
-import com.android.os.StatsLog.CountMetricData;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.util.List;
-
-/**
- * Side-by-side comparison between statsd and batterystats.
- */
-public class BatteryStatsValidationTests extends DeviceAtomTestCase {
-
- private static final String TAG = "Statsd.BatteryStatsValidationTests";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- resetBatteryStatus();
- unplugDevice();
- }
-
- @Override
- protected void tearDown() throws Exception {
- plugInUsb();
- super.tearDown();
- }
-
- /*
- public void testConnectivityStateChange() throws Exception {
- if (!hasFeature(FEATURE_WIFI, true)) return;
- if (!hasFeature(FEATURE_WATCH, false)) return;
- if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
- final String fileName = "BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt";
- StatsdConfig config = createValidationUtil().getConfig(fileName);
- LogUtil.CLog.d("Updating the following config:\n" + config.toString());
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- turnOnAirplaneMode();
- turnOffAirplaneMode();
- // wait for long enough for device to restore connection
- Thread.sleep(13_000);
-
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
- List<CountMetricData> countMetricData = getCountMetricDataList();
- assertThat(countMetricData).hasSize(1);
- assertThat(countMetricData.get(0).getBucketInfoCount()).isEqualTo(1);
- assertThat(countMetricData.get(0).getBucketInfo(0).getCount()).isAtLeast(2L);
- assertThat(countMetricData.get(0).getBucketInfo(0).getCount()).isEqualTo(
- (long) batterystatsProto.getSystem().getMisc().getNumConnectivityChanges());
- }
- */
-
- public void testPowerUse() throws Exception {
- if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
- resetBatteryStats();
- unplugDevice();
-
- final double ALLOWED_FRACTIONAL_DIFFERENCE = 0.7; // ratio that statsd and bs can differ
-
- StatsdConfig.Builder config = createConfigBuilder();
- addGaugeAtomWithDimensions(config, Atom.DEVICE_CALCULATED_POWER_USE_FIELD_NUMBER, null);
- uploadConfig(config);
- unplugDevice();
-
- Thread.sleep(WAIT_TIME_LONG);
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
- Thread.sleep(WAIT_TIME_LONG);
-
- setAppBreadcrumbPredicate();
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
- Thread.sleep(WAIT_TIME_LONG);
- List<Atom> atomList = getGaugeMetricDataList();
-
- // Extract statsd data
- Atom atom = atomList.get(0);
- long statsdPowerNas = atom.getDeviceCalculatedPowerUse().getComputedPowerNanoAmpSecs();
- assertThat(statsdPowerNas).isGreaterThan(0L);
-
- // Extract BatteryStats data
- double bsPowerNas = batterystatsProto.getSystem().getPowerUseSummary().getComputedPowerMah()
- * 1_000_000L * 3600L; /* mAh to nAs */
- assertThat(bsPowerNas).isGreaterThan(0d);
-
- assertThat((double) statsdPowerNas)
- .isGreaterThan(ALLOWED_FRACTIONAL_DIFFERENCE * bsPowerNas);
- assertThat(bsPowerNas).isGreaterThan(ALLOWED_FRACTIONAL_DIFFERENCE * statsdPowerNas);
- }
-
- public void testServiceStartCount() throws Exception {
- final String fileName = "BATTERYSTATS_SERVICE_START_COUNT.pbtxt";
- StatsdConfig config = createValidationUtil().getConfig(fileName);
- LogUtil.CLog.d("Updating the following config:\n" + config.toString());
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testForegroundService");
-
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
- List<CountMetricData> countMetricData = getCountMetricDataList();
- assertThat(countMetricData).isNotEmpty();
- int uid = getUid();
- long countFromStatsd = 0;
- for (CountMetricData data : countMetricData) {
- List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
- if (dims.get(0).getValueInt() == uid) {
- assertThat(dims.get(1).getValueStr()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(dims.get(2).getValueStr())
- .isEqualTo(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME);
- countFromStatsd = data.getBucketInfo(0).getCount();
- assertThat(countFromStatsd).isGreaterThan(0L);
- }
- }
- long countFromBS = 0;
- for (UidProto uidProto : batterystatsProto.getUidsList()) {
- if (uidProto.getUid() == uid) {
- for (Package pkg : uidProto.getPackagesList()) {
- if (pkg.getName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
- for (Service svc : pkg.getServicesList()) {
- if (svc.getName().equals(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME)) {
- countFromBS = svc.getStartCount();
- assertThat(countFromBS).isGreaterThan(0L);
- }
- }
- }
- }
- }
- }
- assertThat(countFromStatsd).isGreaterThan(0L);
- assertThat(countFromBS).isGreaterThan(0L);
- assertThat(countFromBS).isEqualTo(countFromStatsd);
- }
-
- public void testServiceLaunchCount() throws Exception {
- final String fileName = "BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt";
- StatsdConfig config = createValidationUtil().getConfig(fileName);
- LogUtil.CLog.d("Updating the following config:\n" + config.toString());
- uploadConfig(config);
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testForegroundService");
-
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
- List<CountMetricData> countMetricData = getCountMetricDataList();
- assertThat(countMetricData).isNotEmpty();
- int uid = getUid();
- long countFromStatsd = 0;
- for (CountMetricData data : countMetricData) {
- List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
- if (dims.get(0).getValueInt() == uid) {
- assertThat(dims.get(1).getValueStr()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
- assertThat(dims.get(2).getValueStr())
- .isEqualTo(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME);
- countFromStatsd = data.getBucketInfo(0).getCount();
- assertThat(countFromStatsd).isGreaterThan(0L);
- }
- }
- long countFromBS = 0;
- for (UidProto uidProto : batterystatsProto.getUidsList()) {
- if (uidProto.getUid() == uid) {
- for (Package pkg : uidProto.getPackagesList()) {
- if (pkg.getName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
- for (Service svc : pkg.getServicesList()) {
- if (svc.getName().equals(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME)) {
- countFromBS = svc.getLaunchCount();
- assertThat(countFromBS).isGreaterThan(0L);
- }
- }
- }
- }
- }
- }
- assertThat(countFromStatsd).isGreaterThan(0L);
- assertThat(countFromBS).isGreaterThan(0L);
- assertThat(countFromBS).isEqualTo(countFromStatsd);
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/DirectoryValidationTest.java b/hostsidetests/statsd/src/android/cts/statsd/validation/DirectoryValidationTest.java
deleted file mode 100644
index 37ded0b..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/DirectoryValidationTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package android.cts.statsd.validation;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-/**
- * Tests Suite for directories used by Statsd.
- */
-public class DirectoryValidationTest extends DeviceAtomTestCase {
-
- public void testStatsActiveMetricDirectoryExists() throws Exception {
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
- ".DirectoryTests", "testStatsActiveMetricDirectoryExists");
- }
-
- public void testStatsDataDirectoryExists() throws Exception {
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
- ".DirectoryTests", "testStatsDataDirectoryExists");
- }
-
- public void testStatsMetadataDirectoryExists() throws Exception {
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
- ".DirectoryTests", "testStatsMetadataDirectoryExists");
- }
-
- public void testStatsServiceDirectoryExists() throws Exception {
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
- ".DirectoryTests", "testStatsServiceDirectoryExists");
- }
-
- public void testTrainInfoDirectoryExists() throws Exception {
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
- ".DirectoryTests", "testTrainInfoDirectoryExists");
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
deleted file mode 100644
index 5b42aa9..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
+++ /dev/null
@@ -1,306 +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 android.cts.statsd.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.ProcStateTestCase;
-import android.service.procstats.ProcessState;
-import android.service.procstats.AggregatedProcessState;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.ProcessStateAggregated;
-import com.android.os.AtomsProto.ProcessStatsPackageProto;
-import com.android.os.AtomsProto.ProcessStatsProto;
-import com.android.os.AtomsProto.ProcessStatsStateProto;
-import com.android.os.StatsLog.DimensionsValue;
-import com.android.os.StatsLog.ValueBucketInfo;
-import com.android.os.StatsLog.ValueMetricData;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.List;
-
-/**
- * Side-by-side comparison between statsd and procstats.
- */
-public class ProcStatsValidationTests extends ProcStateTestCase {
-
- private static final String TAG = "Statsd.ProcStatsValidationTests";
-
- private static final int EXTRA_WAIT_TIME_MS = 1_000; // as buffer when proc state changing.
-
- public void testProcessStatePssValue() throws Exception {
- final String fileName = "PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt";
- StatsdConfig config = createValidationUtil().getConfig(fileName);
- LogUtil.CLog.d("Updating the following config:\n" + config.toString());
- uploadConfig(config);
- clearProcStats();
- toggleScreenAndSleep(WAIT_TIME_SHORT);
-
- // foreground service
- executeForegroundService();
- toggleScreenAndSleep(SLEEP_OF_FOREGROUND_SERVICE + EXTRA_WAIT_TIME_MS);
- // background
- executeBackgroundService(ACTION_BACKGROUND_SLEEP);
- toggleScreenAndSleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP + EXTRA_WAIT_TIME_MS);
- // top
- executeForegroundActivity(ACTION_LONG_SLEEP_WHILE_TOP);
- toggleScreenAndSleep(SLEEP_OF_ACTION_LONG_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS);
- // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
- executeBackgroundService(ACTION_END_IMMEDIATELY);
- final int cacheTime = 2_000; // process should be in cached state for up to this long
- toggleScreenAndSleep(cacheTime);
- // foreground
- // overlay should take 2 sec to appear. So this makes it 4 sec in TOP
- executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
- toggleScreenAndSleep(EXTRA_WAIT_TIME_MS + 5_000);
-
- // Sorted list of events in order in which they occurred.
- List<ValueMetricData> statsdData = getValueMetricDataList();
-
- List<ProcessStatsProto> processStatsProtoList = getProcStatsProto();
-
- LogUtil.CLog.d("======================");
-
- String statsdPkgName = "com.android.server.cts.device.statsd";
- double valueInStatsd = 0;
- for (ValueMetricData d : statsdData) {
- List<DimensionsValue> dimensionsValuesInWhat = d.getDimensionLeafValuesInWhatList();
- if (dimensionsValuesInWhat.get(0).getValueStr().equals(statsdPkgName)
- && dimensionsValuesInWhat.get(1).getValueStr().equals(statsdPkgName)) {
- LogUtil.CLog.d(d.toString());
- for (ValueBucketInfo bucket : d.getBucketInfoList()) {
- valueInStatsd = Math.max(bucket.getValues(0).getValueLong(), valueInStatsd);
- }
- }
- }
-
- double valueInProcStats = 0;
- for (ProcessStatsProto p : processStatsProtoList) {
- if (p.getProcess().equals(statsdPkgName)) {
- LogUtil.CLog.d(p.toString());
- for (ProcessStatsStateProto s : p.getStatesList()) {
- valueInProcStats = Math.max(s.getPss().getMax(), valueInProcStats);
- }
- }
- }
- assertThat(valueInProcStats).isGreaterThan(0d);
- assertThat(valueInStatsd).isWithin(1e-10).of(valueInProcStats);
- }
-
- private void toggleScreenAndSleep(final long duration) throws Exception {
- final long half = duration >> 1;
- Thread.sleep(half);
- turnScreenOff();
- Thread.sleep(half);
- turnScreenOn();
- }
-
- public void testProcessStateByPulling() throws Exception {
- startProcStatsTesting();
- clearProcStats();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // foreground service
- executeForegroundService();
- Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE + EXTRA_WAIT_TIME_MS);
- // background
- executeBackgroundService(ACTION_BACKGROUND_SLEEP);
- Thread.sleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP + EXTRA_WAIT_TIME_MS);
- // top
- executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
- Thread.sleep(SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS);
- // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
- executeBackgroundService(ACTION_END_IMMEDIATELY);
- final int cacheTime = 2_000; // process should be in cached state for up to this long
- Thread.sleep(cacheTime);
- // foreground
- // overlay should take 2 sec to appear. So this makes it 4 sec in TOP
- executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
- Thread.sleep(EXTRA_WAIT_TIME_MS + 5_000);
-
- Thread.sleep(60_000);
- uninstallPackage();
- stopProcStatsTesting();
- commitProcStatsToDisk();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final String fileName = "PROCSTATSQ_PULL.pbtxt";
- StatsdConfig config = createValidationUtil().getConfig(fileName);
- LogUtil.CLog.d("Updating the following config:\n" + config.toString());
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT + 5_000);
-
- List<Atom> statsdData = getGaugeMetricDataList();
-
- List<android.service.procstats.ProcessStatsProto> processStatsProtoList
- = getAllProcStatsProtoForStatsd();
-
- // We pull directly from ProcessStatsService, so not necessary to compare every field.
- // Make sure that 1. both capture statsd package 2. spot check some values are reasonable
- LogUtil.CLog.d("======================");
-
- String statsdPkgName = "com.android.server.cts.device.statsd";
- long rssAvgStatsd = 0;
- for (Atom d : statsdData) {
- for (ProcessStatsProto proc : d.getProcStats().getProcStatsSection().getProcessStatsList()) {
- if (proc.getProcess().equals(statsdPkgName)) {
- LogUtil.CLog.d("Got proto from statsd:");
- LogUtil.CLog.d(proc.toString());
- for (ProcessStatsStateProto state : proc.getStatesList()) {
- if (state.getProcessStateAggregated()
- == ProcessStateAggregated.PROCESS_STATE_IMPORTANT_FOREGROUND) {
- rssAvgStatsd = state.getRss().getMeanKb();
- }
- }
- }
- }
- }
-
- long rssAvgProcstats = 0;
- for (android.service.procstats.ProcessStatsProto process: processStatsProtoList) {
- if (process.getProcess().equals(statsdPkgName)) {
- LogUtil.CLog.d("Got proto from procstats dumpsys:");
- LogUtil.CLog.d(process.toString());
- for (android.service.procstats.ProcessStatsStateProto state
- : process.getStatesList()) {
- if (AggregatedProcessState.AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND
- == state.getProcessStateAggregated()) {
- rssAvgProcstats = state.getRss().getMeanKb();
- break;
- }
- }
- }
- }
-
- assertThat(rssAvgStatsd).isEqualTo(rssAvgProcstats);
- }
-
- public void testProcStatsPkgProcStats() throws Exception {
- /**
- * Temporarily disable this test as the proc stats data being pulled into the statsd
- * doesn't include the pkg part now.
- *
- startProcStatsTesting();
- clearProcStats();
- Thread.sleep(WAIT_TIME_SHORT);
-
- // foreground service
- executeForegroundService();
- Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE + EXTRA_WAIT_TIME_MS);
- // background
- executeBackgroundService(ACTION_BACKGROUND_SLEEP);
- Thread.sleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP + EXTRA_WAIT_TIME_MS);
- // top
- executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
- Thread.sleep(SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS);
- // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
- executeBackgroundService(ACTION_END_IMMEDIATELY);
- final int cacheTime = 2_000; // process should be in cached state for up to this long
- Thread.sleep(cacheTime);
- // foreground
- // overlay should take 2 sec to appear. So this makes it 4 sec in TOP
- executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
- Thread.sleep(EXTRA_WAIT_TIME_MS + 5_000);
-
- Thread.sleep(60_000);
- uninstallPackage();
- stopProcStatsTesting();
- commitProcStatsToDisk();
- Thread.sleep(WAIT_TIME_SHORT);
-
- final String fileName = "PROCSTATSQ_PULL_PKG_PROC.pbtxt";
- StatsdConfig config = createValidationUtil().getConfig(fileName);
- LogUtil.CLog.d("Updating the following config:\n" + config.toString());
- uploadConfig(config);
- Thread.sleep(WAIT_TIME_SHORT);
- setAppBreadcrumbPredicate();
- Thread.sleep(WAIT_TIME_SHORT);
-
- List<Atom> statsdData = getGaugeMetricDataList();
- assertThat(statsdData).isNotEmpty();
- assertThat(
- statsdData.get(0).getProcStatsPkgProc().getProcStatsSection()
- .getProcessStatsList()
- ).isNotEmpty();
-
- // We pull directly from ProcessStatsService, so not necessary to compare every field.
- // Make sure that 1. both capture statsd package 2. spot check some values are reasonable
- LogUtil.CLog.d("======================");
-
- String statsdPkgName = "com.android.server.cts.device.statsd";
- long rssAvgStatsd = 0;
- long durationStatsd = 0;
- for (Atom d : statsdData) {
- for (ProcessStatsPackageProto pkg : d.getProcStatsPkgProc().getProcStatsSection().getPackageStatsList()) {
- if (pkg.getPackage().equals(statsdPkgName)) {
- LogUtil.CLog.d("Got proto from statsd:");
- LogUtil.CLog.d(pkg.toString());
- for (ProcessStatsProto process : pkg.getProcessStatsList()) {
- for (ProcessStatsStateProto state : process.getStatesList()) {
- if (state.getProcessState()
- == ProcessState.PROCESS_STATE_IMPORTANT_FOREGROUND) {
- durationStatsd = state.getDurationMillis();
- rssAvgStatsd = state.getRss().getAverage();
- }
- }
- }
- }
- assertThat(pkg.getServiceStatsCount()).isEqualTo(0L);
- assertThat(pkg.getAssociationStatsCount()).isEqualTo(0L);
- }
- }
-
- LogUtil.CLog.d("avg rss from statsd is " + rssAvgStatsd);
-
- List<ProcessStatsPackageProto> processStatsPackageProtoList = getAllProcStatsProto();
-
- long pssAvgProcstats = 0;
- long ussAvgProcstats = 0;
- long rssAvgProcstats = 0;
- long durationProcstats = 0;
- int serviceStatsCount = 0;
- int associationStatsCount = 0;
- for (ProcessStatsPackageProto pkg : processStatsPackageProtoList) {
- if (pkg.getPackage().equals(statsdPkgName)) {
- LogUtil.CLog.d("Got proto from procstats dumpsys:");
- LogUtil.CLog.d(pkg.toString());
- for (ProcessStatsProto process : pkg.getProcessStatsList()) {
- for (ProcessStatsStateProto state : process.getStatesList()) {
- if (state.getProcessState()
- == ProcessState.PROCESS_STATE_IMPORTANT_FOREGROUND) {
- durationProcstats = state.getDurationMillis();
- pssAvgProcstats = state.getPss().getAverage();
- ussAvgProcstats = state.getUss().getAverage();
- rssAvgProcstats = state.getRss().getAverage();
- }
- }
- }
- }
- serviceStatsCount += pkg.getServiceStatsCount();
- associationStatsCount += pkg.getAssociationStatsCount();
- }
- assertThat(serviceStatsCount).isGreaterThan(0);
- assertThat(associationStatsCount).isGreaterThan(0);
-
- LogUtil.CLog.d("avg pss from procstats is " + pssAvgProcstats);
- assertThat(rssAvgStatsd).isEqualTo(rssAvgProcstats);
- */
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTestUtil.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTestUtil.java
deleted file mode 100644
index d3e5bad..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTestUtil.java
+++ /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.
- */
-package android.cts.statsd.validation;
-
-import android.cts.statsd.atom.BaseTestCase;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.FileUtil;
-
-import com.google.protobuf.TextFormat;
-import com.google.protobuf.TextFormat.ParseException;
-
-import java.io.File;
-import java.io.IOException;
-
-public class ValidationTestUtil extends BaseTestCase {
-
- private static final String TAG = "Statsd.ValidationTestUtil";
-
- public StatsdConfig getConfig(String fileName) throws IOException {
- try {
- // TODO: Ideally, we should use real metrics that are also pushed to the fleet.
- File configFile = getBuildHelper().getTestFile(fileName);
- String configStr = FileUtil.readStringFromFile(configFile);
- StatsdConfig.Builder builder = StatsdConfig.newBuilder();
- TextFormat.merge(configStr, builder);
- return builder.build();
- } catch (ParseException e) {
- LogUtil.CLog.e(
- "Failed to parse the config! line: " + e.getLine() + " col: " + e.getColumn(),
- e);
- }
- return null;
- }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
deleted file mode 100644
index 87f6840..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ /dev/null
@@ -1,676 +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 android.cts.statsd.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-import android.os.BatteryPluggedStateEnum;
-import android.os.BatteryStatsProto;
-import android.os.UidProto;
-import android.os.UidProto.Wakelock;
-import android.os.WakeLockLevelEnum;
-import android.platform.test.annotations.RestrictedBuildTest;
-import android.view.DisplayStateEnum;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.DurationMetric;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.LogicalOperation;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.PluggedStateChanged;
-import com.android.os.AtomsProto.ScreenStateChanged;
-import com.android.os.AtomsProto.WakelockStateChanged;
-import com.android.os.StatsLog.DimensionsValue;
-import com.android.os.StatsLog.DurationBucketInfo;
-import com.android.os.StatsLog.DurationMetricData;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import com.google.common.collect.Range;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Side-by-side comparison between statsd and batterystats.
- */
-public class ValidationTests extends DeviceAtomTestCase {
-
- private static final String TAG = "Statsd.ValidationTests";
- private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
- private static final boolean ENABLE_LOAD_TEST = false;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- resetBatteryStatus(); // Undo any unplugDevice().
- turnScreenOn(); // Reset screen to on state
- super.tearDown();
- }
-
- public void testPartialWakelock() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
- resetBatteryStats();
- unplugDevice();
- // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
- // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
- String aodState = getAodState();
- setAodState("0");
- turnScreenOff();
-
- final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
- Set<Integer> wakelockOn = new HashSet<>(Arrays.asList(
- WakelockStateChanged.State.ACQUIRE_VALUE,
- WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE));
- Set<Integer> wakelockOff = new HashSet<>(Arrays.asList(
- WakelockStateChanged.State.RELEASE_VALUE,
- WakelockStateChanged.State.CHANGE_RELEASE_VALUE));
-
- final String EXPECTED_TAG = "StatsdPartialWakelock";
- final WakeLockLevelEnum EXPECTED_LEVEL = WakeLockLevelEnum.PARTIAL_WAKE_LOCK;
-
- // Add state sets to the list in order.
- List<Set<Integer>> stateSet = Arrays.asList(wakelockOn, wakelockOff);
-
- createAndUploadConfig(atomTag, true); // True: uses attribution.
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
-
- // Sorted list of events in order in which they occurred.
- List<EventMetricData> data = getEventMetricDataList();
-
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-
- //=================== verify that statsd is correct ===============//
- // Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getWakelockStateChanged().getState().getNumber());
-
- for (EventMetricData event : data) {
- String tag = event.getAtom().getWakelockStateChanged().getTag();
- WakeLockLevelEnum type = event.getAtom().getWakelockStateChanged().getType();
- assertThat(tag).isEqualTo(EXPECTED_TAG);
- assertThat(type).isEqualTo(EXPECTED_LEVEL);
- }
-
- //=================== verify that batterystats is correct ===============//
- int uid = getUid();
- android.os.TimerProto wl =
- getBatteryStatsPartialWakelock(batterystatsProto, uid, EXPECTED_TAG);
-
- assertThat(wl).isNotNull();
- assertThat(wl.getDurationMs()).isGreaterThan(0L);
- assertThat(wl.getMaxDurationMs()).isIn(Range.closedOpen(400L, 700L));
- assertThat(wl.getTotalDurationMs()).isIn(Range.closedOpen(400L, 700L));
-
- setAodState(aodState); // restores AOD to initial state.
- }
-
- @RestrictedBuildTest
- public void testPartialWakelockDuration() throws Exception {
- if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-
- // getUid() needs shell command via ADB. turnScreenOff() sometimes let system go to suspend.
- // ADB disconnection causes failure of getUid(). Move up here before turnScreenOff().
- final int EXPECTED_UID = getUid();
-
-
- turnScreenOn(); // To ensure that the ScreenOff later gets logged.
- // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
- // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
- String aodState = getAodState();
- setAodState("0");
- uploadWakelockDurationBatteryStatsConfig(TimeUnit.CTS);
- Thread.sleep(WAIT_TIME_SHORT);
- resetBatteryStats();
- unplugDevice();
- turnScreenOff();
-
- Thread.sleep(WAIT_TIME_SHORT);
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
- Thread.sleep(WAIT_TIME_LONG); // Make sure the one second bucket has ended.
-
-
- final String EXPECTED_TAG = "StatsdPartialWakelock";
- final long EXPECTED_TAG_HASH = Long.parseUnsignedLong("15814523794762874414");
- final int MIN_DURATION = 350;
- final int MAX_DURATION = 700;
-
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
- HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = getStatsdWakelockData();
-
- // Get the batterystats wakelock time and make sure it's reasonable.
- android.os.TimerProto bsWakelock =
- getBatteryStatsPartialWakelock(batterystatsProto, EXPECTED_UID, EXPECTED_TAG);
- assertWithMessage(
- "No partial wakelocks with uid %s and tag %s in BatteryStats",
- EXPECTED_UID, EXPECTED_TAG
- ).that(bsWakelock).isNotNull();
- long bsDurationMs = bsWakelock.getTotalDurationMs();
- assertWithMessage(
- "Wakelock in batterystats with uid %s and tag %s was too short or too long",
- EXPECTED_UID, EXPECTED_TAG
- ).that(bsDurationMs).isIn(Range.closed((long) MIN_DURATION, (long) MAX_DURATION));
-
- // Get the statsd wakelock time and make sure it's reasonable.
- assertWithMessage("No wakelocks with uid %s in statsd", EXPECTED_UID)
- .that(statsdWakelockData).containsKey(EXPECTED_UID);
- assertWithMessage("No wakelocks with tag %s in statsd", EXPECTED_TAG)
- .that(statsdWakelockData.get(EXPECTED_UID)).containsKey(EXPECTED_TAG_HASH);
- long statsdDurationMs = statsdWakelockData.get(EXPECTED_UID)
- .get(EXPECTED_TAG_HASH) / 1_000_000;
- assertWithMessage(
- "Wakelock in statsd with uid %s and tag %s was too short or too long",
- EXPECTED_UID, EXPECTED_TAG
- ).that(statsdDurationMs).isIn(Range.closed((long) MIN_DURATION, (long) MAX_DURATION));
-
- // Compare batterystats with statsd.
- long difference = Math.abs(statsdDurationMs - bsDurationMs);
- assertWithMessage(
- "For uid=%s tag=%s had BatteryStats=%s ms but statsd=%s ms",
- EXPECTED_UID, EXPECTED_TAG, bsDurationMs, statsdDurationMs
- ).that(difference).isAtMost(Math.max(bsDurationMs / 10, 10L));
-
- setAodState(aodState); // restores AOD to initial state.
- }
-
- public void testPartialWakelockLoad() throws Exception {
- if (!ENABLE_LOAD_TEST) return;
- turnScreenOn(); // To ensure that the ScreenOff later gets logged.
- uploadWakelockDurationBatteryStatsConfig(TimeUnit.CTS);
- Thread.sleep(WAIT_TIME_SHORT);
- resetBatteryStats();
- unplugDevice();
- turnScreenOff();
-
- runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockLoad");
- // Give time for stuck wakelocks to increase duration.
- Thread.sleep(10_000);
-
-
- final String EXPECTED_TAG = "StatsdPartialWakelock";
- final int EXPECTED_UID = getUid();
- final int NUM_THREADS = 16;
- final int NUM_COUNT_PER_THREAD = 1000;
- final int MAX_DURATION_MS = 15_000;
- final int MIN_DURATION_MS = 1_000;
-
-
- BatteryStatsProto batterystatsProto = getBatteryStatsProto();
- HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = getStatsdWakelockData();
-
- // TODO: this fails because we only have the hashes of the wakelock tags in statsd.
- // If we want to run this test, we need to fix this.
-
- // Verify batterystats output is reasonable.
- // boolean foundUid = false;
- // for (UidProto uidProto : batterystatsProto.getUidsList()) {
- // if (uidProto.getUid() == EXPECTED_UID) {
- // foundUid = true;
- // CLog.d("Battery stats has the following wakelocks: \n" +
- // uidProto.getWakelocksList());
- // assertTrue("UidProto has size " + uidProto.getWakelocksList().size() +
- // " wakelocks in it. Expected " + NUM_THREADS + " wakelocks.",
- // uidProto.getWakelocksList().size() == NUM_THREADS);
- //
- // for (Wakelock wl : uidProto.getWakelocksList()) {
- // String tag = wl.getName();
- // assertTrue("Wakelock tag in batterystats " + tag + " does not contain "
- // + "expected tag " + EXPECTED_TAG, tag.contains(EXPECTED_TAG));
- // assertTrue("Wakelock in batterystats with tag " + tag + " does not have any "
- // + "partial wakelock data.", wl.hasPartial());
- // assertTrue("Wakelock in batterystats with tag " + tag + " tag has count " +
- // wl.getPartial().getCount() + " Expected " + NUM_COUNT_PER_THREAD,
- // wl.getPartial().getCount() == NUM_COUNT_PER_THREAD);
- // long bsDurationMs = wl.getPartial().getTotalDurationMs();
- // assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
- // + EXPECTED_TAG + "was too short. Expected " + MIN_DURATION_MS +
- // ", received " + bsDurationMs, bsDurationMs >= MIN_DURATION_MS);
- // assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
- // + EXPECTED_TAG + "was too long. Expected " + MAX_DURATION_MS +
- // ", received " + bsDurationMs, bsDurationMs <= MAX_DURATION_MS);
- //
- // // Validate statsd.
- // long statsdDurationNs = statsdWakelockData.get(EXPECTED_UID).get(tag);
- // long statsdDurationMs = statsdDurationNs / 1_000_000;
- // long difference = Math.abs(statsdDurationMs - bsDurationMs);
- // assertTrue("Unusually large difference in wakelock duration for tag: " +
- // tag +
- // ". Statsd had duration " + statsdDurationMs +
- // " and batterystats had duration " + bsDurationMs,
- // difference <= bsDurationMs / 10);
- //
- // }
- // }
- // }
- // assertTrue("Did not find uid " + EXPECTED_UID + " in batterystats.", foundUid);
- //
- // // Assert that the wakelock appears in statsd and is correct.
- // assertTrue("Could not find any wakelocks with uid " + EXPECTED_UID + " in statsd",
- // statsdWakelockData.containsKey(EXPECTED_UID));
- // HashMap<String, Long> expectedWakelocks = statsdWakelockData.get(EXPECTED_UID);
- // assertEquals("Expected " + NUM_THREADS + " wakelocks in statsd with UID " +
- // EXPECTED_UID +
- // ". Received " + expectedWakelocks.size(), expectedWakelocks.size(), NUM_THREADS);
- }
-
- // Helper functions
- // TODO: Refactor these into some utils class.
-
- public HashMap<Integer, HashMap<Long, Long>> getStatsdWakelockData() throws Exception {
- StatsLogReport report = getStatsLogReport();
- CLog.d("Received the following stats log report: \n" + report.toString());
-
- // Stores total duration of each wakelock across buckets.
- HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = new HashMap<>();
-
- for (DurationMetricData data : report.getDurationMetrics().getDataList()) {
- // Gets tag and uid.
- List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
- assertThat(dims).hasSize(2);
- boolean hasTag = false;
- long tag = 0;
- int uid = -1;
- long duration = 0;
- for (DimensionsValue dim : dims) {
- if (dim.hasValueInt()) {
- uid = dim.getValueInt();
- } else if (dim.hasValueStrHash()) {
- hasTag = true;
- tag = dim.getValueStrHash();
- }
- }
- assertWithMessage("Did not receive a tag for the wakelock").that(hasTag).isTrue();
- assertWithMessage("Did not receive a uid for the wakelock").that(uid).isNotEqualTo(-1);
-
- // Gets duration.
- for (DurationBucketInfo bucketInfo : data.getBucketInfoList()) {
- duration += bucketInfo.getDurationNanos();
- }
-
- // Store the info.
- if (statsdWakelockData.containsKey(uid)) {
- HashMap<Long, Long> tagToDuration = statsdWakelockData.get(uid);
- tagToDuration.put(tag, duration);
- } else {
- HashMap<Long, Long> tagToDuration = new HashMap<>();
- tagToDuration.put(tag, duration);
- statsdWakelockData.put(uid, tagToDuration);
- }
- }
- CLog.d("follow: statsdwakelockdata is: " + statsdWakelockData);
- return statsdWakelockData;
- }
-
- private android.os.TimerProto getBatteryStatsPartialWakelock(BatteryStatsProto proto,
- long uid, String tag) {
- if (proto.getUidsList().size() < 1) {
- CLog.w("Batterystats proto contains no uids");
- return null;
- }
- boolean hadUid = false;
- for (UidProto uidProto : proto.getUidsList()) {
- if (uidProto.getUid() == uid) {
- hadUid = true;
- for (Wakelock wl : uidProto.getWakelocksList()) {
- if (tag.equals(wl.getName())) {
- if (wl.hasPartial()) {
- return wl.getPartial();
- }
- CLog.w("Batterystats had wakelock for uid (" + uid + ") "
- + "with tag (" + tag + ") "
- + "but it didn't have a partial wakelock");
- }
- }
- CLog.w("Batterystats didn't have a partial wakelock for uid " + uid
- + " with tag " + tag);
- }
- }
- if (!hadUid) CLog.w("Batterystats didn't have uid " + uid);
- return null;
- }
-
- public void uploadWakelockDurationBatteryStatsConfig(TimeUnit bucketsize) throws Exception {
- final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
- String metricName = "DURATION_PARTIAL_WAKELOCK_PER_TAG_UID_WHILE_SCREEN_OFF_ON_BATTERY";
- int metricId = metricName.hashCode();
-
- String partialWakelockIsOnName = "PARTIAL_WAKELOCK_IS_ON";
- int partialWakelockIsOnId = partialWakelockIsOnName.hashCode();
-
- String partialWakelockOnName = "PARTIAL_WAKELOCK_ON";
- int partialWakelockOnId = partialWakelockOnName.hashCode();
- String partialWakelockOffName = "PARTIAL_WAKELOCK_OFF";
- int partialWakelockOffId = partialWakelockOffName.hashCode();
-
- String partialWakelockAcquireName = "PARTIAL_WAKELOCK_ACQUIRE";
- int partialWakelockAcquireId = partialWakelockAcquireName.hashCode();
- String partialWakelockChangeAcquireName = "PARTIAL_WAKELOCK_CHANGE_ACQUIRE";
- int partialWakelockChangeAcquireId = partialWakelockChangeAcquireName.hashCode();
-
- String partialWakelockReleaseName = "PARTIAL_WAKELOCK_RELEASE";
- int partialWakelockReleaseId = partialWakelockReleaseName.hashCode();
- String partialWakelockChangeReleaseName = "PARTIAL_WAKELOCK_CHANGE_RELEASE";
- int partialWakelockChangeReleaseId = partialWakelockChangeReleaseName.hashCode();
-
-
- String screenOffBatteryOnName = "SCREEN_IS_OFF_ON_BATTERY";
- int screenOffBatteryOnId = screenOffBatteryOnName.hashCode();
-
- String screenStateUnknownName = "SCREEN_STATE_UNKNOWN";
- int screenStateUnknownId = screenStateUnknownName.hashCode();
- String screenStateOffName = "SCREEN_STATE_OFF";
- int screenStateOffId = screenStateOffName.hashCode();
- String screenStateOnName = "SCREEN_STATE_ON";
- int screenStateOnId = screenStateOnName.hashCode();
- String screenStateDozeName = "SCREEN_STATE_DOZE";
- int screenStateDozeId = screenStateDozeName.hashCode();
- String screenStateDozeSuspendName = "SCREEN_STATE_DOZE_SUSPEND";
- int screenStateDozeSuspendId = screenStateDozeSuspendName.hashCode();
- String screenStateVrName = "SCREEN_STATE_VR";
- int screenStateVrId = screenStateVrName.hashCode();
- String screenStateOnSuspendName = "SCREEN_STATE_ON_SUSPEND";
- int screenStateOnSuspendId = screenStateOnSuspendName.hashCode();
-
- String screenTurnedOnName = "SCREEN_TURNED_ON";
- int screenTurnedOnId = screenTurnedOnName.hashCode();
- String screenTurnedOffName = "SCREEN_TURNED_OFF";
- int screenTurnedOffId = screenTurnedOffName.hashCode();
-
- String screenIsOffName = "SCREEN_IS_OFF";
- int screenIsOffId = screenIsOffName.hashCode();
-
- String pluggedStateBatteryPluggedNoneName = "PLUGGED_STATE_BATTERY_PLUGGED_NONE";
- int pluggedStateBatteryPluggedNoneId = pluggedStateBatteryPluggedNoneName.hashCode();
- String pluggedStateBatteryPluggedAcName = "PLUGGED_STATE_BATTERY_PLUGGED_AC";
- int pluggedStateBatteryPluggedAcId = pluggedStateBatteryPluggedAcName.hashCode();
- String pluggedStateBatteryPluggedUsbName = "PLUGGED_STATE_BATTERY_PLUGGED_USB";
- int pluggedStateBatteryPluggedUsbId = pluggedStateBatteryPluggedUsbName.hashCode();
- String pluggedStateBatteryPluggedWlName = "PLUGGED_STATE_BATTERY_PLUGGED_WIRELESS";
- int pluggedStateBatteryPluggedWirelessId = pluggedStateBatteryPluggedWlName.hashCode();
-
- String pluggedStateBatteryPluggedName = "PLUGGED_STATE_BATTERY_PLUGGED";
- int pluggedStateBatteryPluggedId = pluggedStateBatteryPluggedName.hashCode();
-
- String deviceIsUnpluggedName = "DEVICE_IS_UNPLUGGED";
- int deviceIsUnpluggedId = deviceIsUnpluggedName.hashCode();
-
-
- FieldMatcher.Builder dimensions = FieldMatcher.newBuilder()
- .setField(atomTag)
- .addChild(FieldMatcher.newBuilder()
- .setField(WakelockStateChanged.TAG_FIELD_NUMBER))
- .addChild(FieldMatcher.newBuilder()
- .setField(1)
- .setPosition(Position.FIRST)
- .addChild(FieldMatcher.newBuilder()
- .setField(1)));
-
- AtomMatcher.Builder wakelockAcquire = AtomMatcher.newBuilder()
- .setId(partialWakelockAcquireId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(atomTag)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
- .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(WakelockStateChanged.State.ACQUIRE_VALUE)));
-
- AtomMatcher.Builder wakelockChangeAcquire = AtomMatcher.newBuilder()
- .setId(partialWakelockChangeAcquireId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(atomTag)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
- .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE)));
-
- AtomMatcher.Builder wakelockRelease = AtomMatcher.newBuilder()
- .setId(partialWakelockReleaseId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(atomTag)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
- .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(WakelockStateChanged.State.RELEASE_VALUE)));
-
- AtomMatcher.Builder wakelockChangeRelease = AtomMatcher.newBuilder()
- .setId(partialWakelockChangeReleaseId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(atomTag)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
- .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(WakelockStateChanged.State.CHANGE_RELEASE_VALUE)));
-
- AtomMatcher.Builder wakelockOn = AtomMatcher.newBuilder()
- .setId(partialWakelockOnId)
- .setCombination(AtomMatcher.Combination.newBuilder()
- .setOperation(LogicalOperation.OR)
- .addMatcher(partialWakelockAcquireId)
- .addMatcher(partialWakelockChangeAcquireId));
-
- AtomMatcher.Builder wakelockOff = AtomMatcher.newBuilder()
- .setId(partialWakelockOffId)
- .setCombination(AtomMatcher.Combination.newBuilder()
- .setOperation(LogicalOperation.OR)
- .addMatcher(partialWakelockReleaseId)
- .addMatcher(partialWakelockChangeReleaseId));
-
-
- Predicate.Builder wakelockPredicate = Predicate.newBuilder()
- .setId(partialWakelockIsOnId)
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(partialWakelockOnId)
- .setStop(partialWakelockOffId)
- .setCountNesting(true)
- .setDimensions(dimensions));
-
- AtomMatcher.Builder pluggedStateBatteryPluggedNone = AtomMatcher.newBuilder()
- .setId(pluggedStateBatteryPluggedNoneId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_NONE_VALUE)));
-
- AtomMatcher.Builder pluggedStateBatteryPluggedAc = AtomMatcher.newBuilder()
- .setId(pluggedStateBatteryPluggedAcId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_AC_VALUE)));
-
- AtomMatcher.Builder pluggedStateBatteryPluggedUsb = AtomMatcher.newBuilder()
- .setId(pluggedStateBatteryPluggedUsbId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_USB_VALUE)));
-
- AtomMatcher.Builder pluggedStateBatteryPluggedWireless = AtomMatcher.newBuilder()
- .setId(pluggedStateBatteryPluggedWirelessId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_WIRELESS_VALUE)));
-
- AtomMatcher.Builder pluggedStateBatteryPlugged = AtomMatcher.newBuilder()
- .setId(pluggedStateBatteryPluggedId)
- .setCombination(AtomMatcher.Combination.newBuilder()
- .setOperation(LogicalOperation.OR)
- .addMatcher(pluggedStateBatteryPluggedAcId)
- .addMatcher(pluggedStateBatteryPluggedUsbId)
- .addMatcher(pluggedStateBatteryPluggedWirelessId));
-
- Predicate.Builder deviceIsUnplugged = Predicate.newBuilder()
- .setId(deviceIsUnpluggedId)
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(pluggedStateBatteryPluggedNoneId)
- .setStop(pluggedStateBatteryPluggedId)
- .setCountNesting(false));
-
- AtomMatcher.Builder screenStateUnknown = AtomMatcher.newBuilder()
- .setId(screenStateUnknownId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_UNKNOWN_VALUE)));
-
- AtomMatcher.Builder screenStateOff = AtomMatcher.newBuilder()
- .setId(screenStateOffId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_OFF_VALUE)));
-
- AtomMatcher.Builder screenStateOn = AtomMatcher.newBuilder()
- .setId(screenStateOnId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_ON_VALUE)));
-
- AtomMatcher.Builder screenStateDoze = AtomMatcher.newBuilder()
- .setId(screenStateDozeId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_DOZE_VALUE)));
-
- AtomMatcher.Builder screenStateDozeSuspend = AtomMatcher.newBuilder()
- .setId(screenStateDozeSuspendId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_DOZE_SUSPEND_VALUE)));
-
- AtomMatcher.Builder screenStateVr = AtomMatcher.newBuilder()
- .setId(screenStateVrId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_VR_VALUE)));
-
- AtomMatcher.Builder screenStateOnSuspend = AtomMatcher.newBuilder()
- .setId(screenStateOnSuspendId)
- .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
- .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
- .addFieldValueMatcher(FieldValueMatcher.newBuilder()
- .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
- .setEqInt(DisplayStateEnum.DISPLAY_STATE_ON_SUSPEND_VALUE)));
-
-
- AtomMatcher.Builder screenTurnedOff = AtomMatcher.newBuilder()
- .setId(screenTurnedOffId)
- .setCombination(AtomMatcher.Combination.newBuilder()
- .setOperation(LogicalOperation.OR)
- .addMatcher(screenStateOffId)
- .addMatcher(screenStateDozeId)
- .addMatcher(screenStateDozeSuspendId)
- .addMatcher(screenStateUnknownId));
-
- AtomMatcher.Builder screenTurnedOn = AtomMatcher.newBuilder()
- .setId(screenTurnedOnId)
- .setCombination(AtomMatcher.Combination.newBuilder()
- .setOperation(LogicalOperation.OR)
- .addMatcher(screenStateOnId)
- .addMatcher(screenStateOnSuspendId)
- .addMatcher(screenStateVrId));
-
- Predicate.Builder screenIsOff = Predicate.newBuilder()
- .setId(screenIsOffId)
- .setSimplePredicate(SimplePredicate.newBuilder()
- .setStart(screenTurnedOffId)
- .setStop(screenTurnedOnId)
- .setCountNesting(false));
-
-
- Predicate.Builder screenOffBatteryOn = Predicate.newBuilder()
- .setId(screenOffBatteryOnId)
- .setCombination(Predicate.Combination.newBuilder()
- .setOperation(LogicalOperation.AND)
- .addPredicate(screenIsOffId)
- .addPredicate(deviceIsUnpluggedId));
-
- StatsdConfig.Builder builder = createConfigBuilder();
- builder.addDurationMetric(DurationMetric.newBuilder()
- .setId(metricId)
- .setWhat(partialWakelockIsOnId)
- .setCondition(screenOffBatteryOnId)
- .setDimensionsInWhat(dimensions)
- .setBucket(bucketsize))
- .addAtomMatcher(wakelockAcquire)
- .addAtomMatcher(wakelockChangeAcquire)
- .addAtomMatcher(wakelockRelease)
- .addAtomMatcher(wakelockChangeRelease)
- .addAtomMatcher(wakelockOn)
- .addAtomMatcher(wakelockOff)
- .addAtomMatcher(pluggedStateBatteryPluggedNone)
- .addAtomMatcher(pluggedStateBatteryPluggedAc)
- .addAtomMatcher(pluggedStateBatteryPluggedUsb)
- .addAtomMatcher(pluggedStateBatteryPluggedWireless)
- .addAtomMatcher(pluggedStateBatteryPlugged)
- .addAtomMatcher(screenStateUnknown)
- .addAtomMatcher(screenStateOff)
- .addAtomMatcher(screenStateOn)
- .addAtomMatcher(screenStateDoze)
- .addAtomMatcher(screenStateDozeSuspend)
- .addAtomMatcher(screenStateVr)
- .addAtomMatcher(screenStateOnSuspend)
- .addAtomMatcher(screenTurnedOff)
- .addAtomMatcher(screenTurnedOn)
- .addPredicate(wakelockPredicate)
- .addPredicate(deviceIsUnplugged)
- .addPredicate(screenIsOff)
- .addPredicate(screenOffBatteryOn);
-
- uploadConfig(builder);
- }
-}